From afc53077ab459e67f08ca83c46b706b88fec2a7c Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Mon, 23 Dec 2019 13:28:52 +0100 Subject: [PATCH 1/2] Fix #79015: undefined-behavior in php_date.c We check that the given microsecond fraction is in the valid range [0, 1000000[, and otherwise mark it as invalid. We also drop the useless do loop; a plain block is sufficient here. --- ext/date/php_date.c | 12 +++++++----- ext/date/tests/bug79015.phpt | 9 +++++++++ 2 files changed, 16 insertions(+), 5 deletions(-) create mode 100644 ext/date/tests/bug79015.phpt diff --git a/ext/date/php_date.c b/ext/date/php_date.c index 00656a41f9763..785c1b222e563 100644 --- a/ext/date/php_date.c +++ b/ext/date/php_date.c @@ -4389,14 +4389,16 @@ static int php_date_interval_initialize_from_hash(zval **return_value, php_inter PHP_DATE_INTERVAL_READ_PROPERTY("h", h, timelib_sll, -1) PHP_DATE_INTERVAL_READ_PROPERTY("i", i, timelib_sll, -1) PHP_DATE_INTERVAL_READ_PROPERTY("s", s, timelib_sll, -1) - do { + { zval *z_arg = zend_hash_str_find(myht, "f", sizeof("f") - 1); + (*intobj)->diff->us = -1000000; if (z_arg) { - (*intobj)->diff->us = ((double)zval_get_double(z_arg) * 1000000); - } else { - (*intobj)->diff->us = (double) -1000000; + double val = zval_get_double(z_arg) * 1000000; + if (val >= 0 && val < 1000000) { + (*intobj)->diff->us = val; + } } - } while (0); + } PHP_DATE_INTERVAL_READ_PROPERTY("weekday", weekday, int, -1) 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) diff --git a/ext/date/tests/bug79015.phpt b/ext/date/tests/bug79015.phpt new file mode 100644 index 0000000000000..ce6a499469f12 --- /dev/null +++ b/ext/date/tests/bug79015.phpt @@ -0,0 +1,9 @@ +--TEST-- +Bug #79015 (undefined-behavior in php_date.c) +--FILE-- + +--EXPECTF-- +Notice: unserialize(): Error at offset 47 of 47 bytes in %s on line %d +bool(false) From 09edc018db103904e3c4959fc7dc4a629688ce6b Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Mon, 23 Dec 2019 14:42:54 +0100 Subject: [PATCH 2/2] Use unserializable payload in test --- ext/date/tests/bug79015.phpt | 39 +++++++++++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/ext/date/tests/bug79015.phpt b/ext/date/tests/bug79015.phpt index ce6a499469f12..5ebb13832b796 100644 --- a/ext/date/tests/bug79015.phpt +++ b/ext/date/tests/bug79015.phpt @@ -2,8 +2,41 @@ Bug #79015 (undefined-behavior in php_date.c) --FILE-- --EXPECTF-- -Notice: unserialize(): Error at offset 47 of 47 bytes in %s on line %d -bool(false) +object(DateInterval)#%d (16) { + ["y"]=> + int(1) + ["m"]=> + int(0) + ["d"]=> + int(4) + ["h"]=> + int(0) + ["i"]=> + int(0) + ["s"]=> + int(0) + ["f"]=> + float(-1) + ["weekday"]=> + int(0) + ["weekday_behavior"]=> + int(0) + ["first_last_day_of"]=> + int(0) + ["invert"]=> + int(0) + ["days"]=> + bool(false) + ["special_type"]=> + int(0) + ["special_amount"]=> + int(0) + ["have_weekday_relative"]=> + int(0) + ["have_special_relative"]=> + int(0) +}