summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristoph M. Becker <cmb@php.net>2016-07-29 00:24:46 +0200
committerChristoph M. Becker <cmb@php.net>2016-07-29 01:04:21 +0200
commitf67ccd4a7b8fb4b9e55796e69b152e2a899ba3cd (patch)
tree8e1d2cac6c699bf4af3b3adeab56b77c25b513e9
parent5c458c9b025f6f654497f5e3d2ee53b4d1561454 (diff)
downloadphp-git-f67ccd4a7b8fb4b9e55796e69b152e2a899ba3cd.tar.gz
Fix #71894: AddressSanitizer: global-buffer-overflow in zif_cal_from_jd
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.
-rw-r--r--NEWS2
-rw-r--r--ext/calendar/calendar.c20
-rw-r--r--ext/calendar/tests/bug71894.phpt32
3 files changed, 47 insertions, 7 deletions
diff --git a/NEWS b/NEWS
index 98e9d42028..48a78c8f1b 100644
--- 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).
diff --git a/ext/calendar/calendar.c b/ext/calendar/calendar.c
index 1f92b9f2e0..fd487607ba 100644
--- a/ext/calendar/calendar.c
+++ b/ext/calendar/calendar.c
@@ -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
index 0000000000..ea2d6004e7
--- /dev/null
+++ b/ext/calendar/tests/bug71894.phpt
@@ -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) ""