]> granicus.if.org Git - php/commitdiff
Fix #79015: undefined-behavior in php_date.c
authorChristoph M. Becker <cmbecker69@gmx.de>
Mon, 23 Dec 2019 13:42:54 +0000 (14:42 +0100)
committerChristoph M. Becker <cmbecker69@gmx.de>
Fri, 3 Jan 2020 13:31:03 +0000 (14:31 +0100)
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.

NEWS
ext/date/php_date.c
ext/date/tests/bug79015.phpt [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index eb1d2c4edd0931831c8a6e4eb1736cbd945516cd..e2fe829d40b7f1921d2959f971ffd556d2d3277c 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -10,6 +10,9 @@ PHP                                                                        NEWS
   . Implemented FR #77711 (CURLFile should support UNICODE filenames). (cmb)
   . Fixed bug #79033 (Curl timeout error with specific url and post). (cmb)
 
+- Date:
+  . Fixed bug #79015 (undefined-behavior in php_date.c). (cmb)
+
 - Fileinfo:
   . Fixed bug #74170 (locale information change after mime_content_type).
     (Sergei Turchanov)
index 00656a41f97635d96e25306fc5a6d8545a79fd00..785c1b222e56364d01e395b99f4f5338db17b34b 100644 (file)
@@ -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 (file)
index 0000000..5ebb138
--- /dev/null
@@ -0,0 +1,42 @@
+--TEST--
+Bug #79015 (undefined-behavior in php_date.c)
+--FILE--
+<?php
+$payload = 'O:12:"DateInterval":16:{s:1:"y";i:1;s:1:"m";i:0;s:1:"d";i:4;s:1:"h";i:0;s:1:"i";i:0;s:1:"s";i:0;s:1:"f";i:9999999999990;s:7:"weekday";i:0;s:16:"weekday_behavior";i:0;s:17:"first_last_day_of";i:0;s:6:"invert";i:0;s:4:"days";b:0;s:12:"special_type";i:0;s:14:"special_amount";i:0;s:21:"have_weekday_relative";i:0;s:21:"have_special_relative";i:0;}';
+var_dump(unserialize($payload));
+?>
+--EXPECTF--
+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)
+}