]> granicus.if.org Git - php/commitdiff
Fix #71894: AddressSanitizer: global-buffer-overflow in zif_cal_from_jd
authorChristoph M. Becker <cmb@php.net>
Thu, 28 Jul 2016 22:24:46 +0000 (00:24 +0200)
committerChristoph M. Becker <cmb@php.net>
Thu, 28 Jul 2016 23:04:21 +0000 (01:04 +0200)
Julian days < 347998 denote invalid Jewish calendar dates, so
cal_from_jd($jd, CAL_JEWISH) and jdmonthname($jd, CAL_MONTH_JEWISH) should
actually fail. For BC we don't yet let them though, but we fix the OOB read
that happens in this case, and we also adjust cal_from_jd()'s return value
to have empty strings for "abbrevdayname" and "dayname" instead of "Sun"/
"Sunday" and NULL for "dow" instead of 0, which doesn't make any sense.

NEWS
ext/calendar/calendar.c
ext/calendar/tests/bug71894.phpt [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index 98e9d420285811ec179cf7b4c355d561e877cf25..48a78c8f1b85d29e076e2a9e16d5e820a2527193 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -14,6 +14,8 @@ PHP                                                                        NEWS
 - Calendar:
   . Fixed bug #67976 (cal_days_month() fails for final month of the French
     calendar). (cmb)
+  . Fixed bug #71894 (AddressSanitizer: global-buffer-overflow in
+    zif_cal_from_jd). (cmb)
 
 - Curl:
   . Fixed bug #71144 (Segmentation fault when using cURL with ZTS).
index 1f92b9f2e058fe48bbf2b65aadd2edff429c487d..fd487607ba04a3cb825832be94656c5326c8b645 100644 (file)
@@ -420,15 +420,21 @@ PHP_FUNCTION(cal_from_jd)
        add_assoc_long(return_value, "year", year);
 
 /* day of week */
-       dow = DayOfWeek(jd);
-       add_assoc_long(return_value, "dow", dow);
-       add_assoc_string(return_value, "abbrevdayname", DayNameShort[dow], 1);
-       add_assoc_string(return_value, "dayname", DayNameLong[dow], 1);
+       if (cal != CAL_JEWISH || year > 0) {
+               dow = DayOfWeek(jd);
+               add_assoc_long(return_value, "dow", dow);
+               add_assoc_string(return_value, "abbrevdayname", DayNameShort[dow], 1);
+               add_assoc_string(return_value, "dayname", DayNameLong[dow], 1);
+       } else {
+               add_assoc_null(return_value, "dow");
+               add_assoc_string(return_value, "abbrevdayname", "", 1);
+               add_assoc_string(return_value, "dayname", "", 1);
+       }
 /* month name */
        if(cal == CAL_JEWISH) {
                /* special case for Jewish calendar */
-               add_assoc_string(return_value, "abbrevmonth", JEWISH_MONTH_NAME(year)[month], 1);
-               add_assoc_string(return_value, "monthname", JEWISH_MONTH_NAME(year)[month], 1);
+               add_assoc_string(return_value, "abbrevmonth", (year > 0 ? JEWISH_MONTH_NAME(year)[month] : ""), 1);
+               add_assoc_string(return_value, "monthname", (year > 0 ? JEWISH_MONTH_NAME(year)[month] : ""), 1);
        } else {
                add_assoc_string(return_value, "abbrevmonth", calendar->month_name_short[month], 1);
                add_assoc_string(return_value, "monthname", calendar->month_name_long[month], 1);
@@ -741,7 +747,7 @@ PHP_FUNCTION(jdmonthname)
                break;
        case CAL_MONTH_JEWISH:          /* jewish month */
                SdnToJewish(julday, &year, &month, &day);
-               monthname = JEWISH_MONTH_NAME(year)[month];
+               monthname = (year > 0 ? JEWISH_MONTH_NAME(year)[month] : "");
                break;
        case CAL_MONTH_FRENCH:          /* french month */
                SdnToFrench(julday, &year, &month, &day);
diff --git a/ext/calendar/tests/bug71894.phpt b/ext/calendar/tests/bug71894.phpt
new file mode 100644 (file)
index 0000000..ea2d600
--- /dev/null
@@ -0,0 +1,32 @@
+--TEST--
+Bug #71894 (AddressSanitizer: global-buffer-overflow in zif_cal_from_jd)
+--SKIPIF--
+<?php
+if (!extension_loaded('calendar')) die('skip ext/calendar required');
+?>
+--FILE--
+<?php
+var_dump(cal_from_jd(347997, CAL_JEWISH));
+var_dump(jdmonthname(347997,CAL_MONTH_JEWISH));?>
+--EXPECT--
+array(9) {
+  ["date"]=>
+  string(5) "0/0/0"
+  ["month"]=>
+  int(0)
+  ["day"]=>
+  int(0)
+  ["year"]=>
+  int(0)
+  ["dow"]=>
+  NULL
+  ["abbrevdayname"]=>
+  string(0) ""
+  ["dayname"]=>
+  string(0) ""
+  ["abbrevmonth"]=>
+  string(0) ""
+  ["monthname"]=>
+  string(0) ""
+}
+string(0) ""