From adae5c180b0af357ee81b823b315b811b67cece8 Mon Sep 17 00:00:00 2001 From: "m.yakunin" Date: Fri, 6 Sep 2019 18:27:53 +0300 Subject: [PATCH 1/5] Fix #70153 \DateInterval incorrectly unserialized Added a special handling for the days property, so that bool(false) is correctly converted to the proper internal representation. Solution is based on Christoph M. Becker's (https://people.php.net/cmb) patch proposed in the bug page. --- ext/date/php_date.c | 8 ++++++-- ext/date/tests/bug48678.phpt | 2 +- ext/date/tests/bug53437.phpt | 2 +- ext/date/tests/bug53437_var2.phpt | 2 +- ext/date/tests/bug70153.phpt | 14 ++++++++++++++ 5 files changed, 23 insertions(+), 5 deletions(-) create mode 100644 ext/date/tests/bug70153.phpt diff --git a/ext/date/php_date.c b/ext/date/php_date.c index 9ad4427897fe9..98bdd9b5a4ed5 100644 --- a/ext/date/php_date.c +++ b/ext/date/php_date.c @@ -4357,7 +4357,11 @@ static int php_date_interval_initialize_from_hash(zval **return_value, php_inter zval *z_arg = zend_hash_str_find(myht, element, sizeof(element) - 1); \ if (z_arg && Z_TYPE_P(z_arg) <= IS_STRING) { \ zend_string *str = zval_get_string(z_arg); \ - DATE_A64I((*intobj)->diff->member, ZSTR_VAL(str)); \ + if (str->len) { \ + DATE_A64I((*intobj)->diff->member, ZSTR_VAL(str)); \ + } else { \ + (*intobj)->diff->member = -99999; \ + } \ zend_string_release(str); \ } else { \ (*intobj)->diff->member = -1LL; \ @@ -4661,7 +4665,7 @@ PHP_METHOD(DatePeriod, __construct) dpobj->end = clone; } } - + if (dpobj->end == NULL && recurrences < 1) { php_error_docref(NULL, E_WARNING, "The recurrence count '%d' is invalid. Needs to be > 0", (int) recurrences); } diff --git a/ext/date/tests/bug48678.phpt b/ext/date/tests/bug48678.phpt index 9565cb2dfbf25..6f97d614099b2 100644 --- a/ext/date/tests/bug48678.phpt +++ b/ext/date/tests/bug48678.phpt @@ -39,7 +39,7 @@ DateInterval Object [weekday_behavior] => 0 [first_last_day_of] => 0 [invert] => 0 - [days] => 0 + [days] => [special_type] => 0 [special_amount] => 0 [have_weekday_relative] => 0 diff --git a/ext/date/tests/bug53437.phpt b/ext/date/tests/bug53437.phpt index 0be9691a14010..3c94bd5313088 100644 --- a/ext/date/tests/bug53437.phpt +++ b/ext/date/tests/bug53437.phpt @@ -136,7 +136,7 @@ object(DatePeriod)#5 (6) { ["invert"]=> int(0) ["days"]=> - int(0) + bool(false) ["special_type"]=> int(0) ["special_amount"]=> diff --git a/ext/date/tests/bug53437_var2.phpt b/ext/date/tests/bug53437_var2.phpt index 2ef21e738e5fa..51cc28943be32 100644 --- a/ext/date/tests/bug53437_var2.phpt +++ b/ext/date/tests/bug53437_var2.phpt @@ -71,7 +71,7 @@ object(DateInterval)#2 (16) { ["invert"]=> int(0) ["days"]=> - int(0) + bool(false) ["special_type"]=> int(0) ["special_amount"]=> diff --git a/ext/date/tests/bug70153.phpt b/ext/date/tests/bug70153.phpt new file mode 100644 index 0000000000000..5b965207fc27d --- /dev/null +++ b/ext/date/tests/bug70153.phpt @@ -0,0 +1,14 @@ +--TEST-- +Bug #70153 (\DateInterval incorrectly unserialized) +--FILE-- +days, $i2->days); +var_dump($i2->special_amount, $i2->special_amount); +?> +--EXPECT-- +bool(false) +bool(false) +int(0) +int(0) From ab9f3514e754be8ce0916d088f098955e80acbe4 Mon Sep 17 00:00:00 2001 From: iakunin Date: Fri, 6 Sep 2019 19:25:46 +0300 Subject: [PATCH 2/5] Fix #70153 \DateInterval incorrectly unserialized Using the proper accessor macro Co-Authored-By: Christoph M. Becker --- ext/date/php_date.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/date/php_date.c b/ext/date/php_date.c index 98bdd9b5a4ed5..7f5171d95d19d 100644 --- a/ext/date/php_date.c +++ b/ext/date/php_date.c @@ -4357,7 +4357,7 @@ static int php_date_interval_initialize_from_hash(zval **return_value, php_inter zval *z_arg = zend_hash_str_find(myht, element, sizeof(element) - 1); \ if (z_arg && Z_TYPE_P(z_arg) <= IS_STRING) { \ zend_string *str = zval_get_string(z_arg); \ - if (str->len) { \ + if (ZSTR_LEN(str)) { \ DATE_A64I((*intobj)->diff->member, ZSTR_VAL(str)); \ } else { \ (*intobj)->diff->member = -99999; \ From 0cd51d6727f3820c4397238f35f9bc2256b208ce Mon Sep 17 00:00:00 2001 From: "m.yakunin" Date: Sun, 8 Sep 2019 10:42:56 +0300 Subject: [PATCH 3/5] Fix #70153 \DateInterval incorrectly unserialized Added a separate macro for reading 'days' property. PHP_DATE_INTERVAL_READ_PROPERTY_I64 reverted to its original state. --- ext/date/php_date.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/ext/date/php_date.c b/ext/date/php_date.c index 7f5171d95d19d..042c27e4925ad 100644 --- a/ext/date/php_date.c +++ b/ext/date/php_date.c @@ -4357,11 +4357,21 @@ static int php_date_interval_initialize_from_hash(zval **return_value, php_inter zval *z_arg = zend_hash_str_find(myht, element, sizeof(element) - 1); \ if (z_arg && Z_TYPE_P(z_arg) <= IS_STRING) { \ zend_string *str = zval_get_string(z_arg); \ - if (ZSTR_LEN(str)) { \ - DATE_A64I((*intobj)->diff->member, ZSTR_VAL(str)); \ - } else { \ - (*intobj)->diff->member = -99999; \ - } \ + DATE_A64I((*intobj)->diff->member, ZSTR_VAL(str)); \ + zend_string_release(str); \ + } else { \ + (*intobj)->diff->member = -1LL; \ + } \ + } while (0); + +#define PHP_DATE_INTERVAL_READ_PROPERTY_DAYS(member) \ + do { \ + zval *z_arg = zend_hash_str_find(myht, "days", sizeof("days") - 1); \ + if (z_arg && Z_TYPE_P(z_arg) == IS_FALSE) { \ + (*intobj)->diff->member = -99999; \ + } else if (z_arg && Z_TYPE_P(z_arg) <= IS_STRING) { \ + zend_string *str = zval_get_string(z_arg); \ + DATE_A64I((*intobj)->diff->member, ZSTR_VAL(str)); \ zend_string_release(str); \ } else { \ (*intobj)->diff->member = -1LL; \ @@ -4396,7 +4406,7 @@ static int php_date_interval_initialize_from_hash(zval **return_value, php_inter PHP_DATE_INTERVAL_READ_PROPERTY("weekday_behavior", weekday_behavior, int, -1) PHP_DATE_INTERVAL_READ_PROPERTY("first_last_day_of", first_last_day_of, int, -1) PHP_DATE_INTERVAL_READ_PROPERTY("invert", invert, int, 0); - PHP_DATE_INTERVAL_READ_PROPERTY_I64("days", days); + PHP_DATE_INTERVAL_READ_PROPERTY_DAYS(days); PHP_DATE_INTERVAL_READ_PROPERTY("special_type", special.type, unsigned int, 0); PHP_DATE_INTERVAL_READ_PROPERTY_I64("special_amount", special.amount); PHP_DATE_INTERVAL_READ_PROPERTY("have_weekday_relative", have_weekday_relative, unsigned int, 0); From 3f378ea50db56b9a8ece02577d16b02805c2a4ac Mon Sep 17 00:00:00 2001 From: "m.yakunin" Date: Mon, 9 Sep 2019 13:17:57 +0300 Subject: [PATCH 4/5] Fix #70153 \DateInterval incorrectly unserialized Revert formatting --- ext/date/php_date.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/date/php_date.c b/ext/date/php_date.c index 042c27e4925ad..eb32c5d9dc9d6 100644 --- a/ext/date/php_date.c +++ b/ext/date/php_date.c @@ -4675,7 +4675,7 @@ PHP_METHOD(DatePeriod, __construct) dpobj->end = clone; } } - + if (dpobj->end == NULL && recurrences < 1) { php_error_docref(NULL, E_WARNING, "The recurrence count '%d' is invalid. Needs to be > 0", (int) recurrences); } From e850ba4e21d274778b6937958e053dbeae89b6ae Mon Sep 17 00:00:00 2001 From: iakunin Date: Mon, 16 Sep 2019 19:50:55 +0300 Subject: [PATCH 5/5] Fix #70153 \DateInterval incorrectly unserialized Extra whitespace removed --- ext/date/php_date.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/date/php_date.c b/ext/date/php_date.c index eb32c5d9dc9d6..042c27e4925ad 100644 --- a/ext/date/php_date.c +++ b/ext/date/php_date.c @@ -4675,7 +4675,7 @@ PHP_METHOD(DatePeriod, __construct) dpobj->end = clone; } } - + if (dpobj->end == NULL && recurrences < 1) { php_error_docref(NULL, E_WARNING, "The recurrence count '%d' is invalid. Needs to be > 0", (int) recurrences); }