]> granicus.if.org Git - php/commitdiff
Fix #80185: jdtounix() fails after 2037
authorChristoph M. Becker <cmbecker69@gmx.de>
Wed, 7 Oct 2020 08:38:30 +0000 (10:38 +0200)
committerChristoph M. Becker <cmbecker69@gmx.de>
Wed, 7 Oct 2020 11:23:50 +0000 (13:23 +0200)
There is no such thing as the "end of the unix epoch", and if it was,
it would certainly not be 2037-10-11T02:00:00.  There is, however,
potential integer overflow which we need to avoid.

Closes GH-6288.

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

diff --git a/NEWS b/NEWS
index 43ee8d9db2ffe6db50c03d3e51cb6a54712fd6fc..c7e278e3cd97c41979b4607a63e7d2433fa83795 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -6,6 +6,9 @@ PHP                                                                        NEWS
   . Fixed bug #79423 (copy command is limited to size of file it can copy).
     (cmb)
 
+- Calendar:
+  . Fixed bug #80185 (jdtounix() fails after 2037). (cmb)
+
 - MySQLnd:
   . Fixed bug #80115 (mysqlnd.debug doesn't recognize absolute paths with
     slashes). (cmb)
index da6a184e6c17a6035fb47c6641568417812f35d0..d364079bd047449d69f5fac67024f31f3044d35b 100644 (file)
@@ -23,6 +23,8 @@
 #include "sdncal.h"
 #include <time.h>
 
+#define SECS_PER_DAY (24 * 3600)
+
 /* {{{ proto int unixtojd([int timestamp])
    Convert UNIX timestamp to Julian Day */
 PHP_FUNCTION(unixtojd)
@@ -62,11 +64,11 @@ PHP_FUNCTION(jdtounix)
        }
        uday -= 2440588 /* J.D. of 1.1.1970 */;
 
-       if (uday < 0 || uday > 24755) { /* before beginning of unix epoch or behind end of unix epoch */
+       if (uday < 0 || uday > ZEND_LONG_MAX / SECS_PER_DAY) { /* before beginning of unix epoch or greater than representable */
                RETURN_FALSE;
        }
 
-       RETURN_LONG(uday * 24 * 3600);
+       RETURN_LONG(uday * SECS_PER_DAY);
 }
 /* }}} */
 
diff --git a/ext/calendar/tests/bug80185.phpt b/ext/calendar/tests/bug80185.phpt
new file mode 100644 (file)
index 0000000..cd9ddb7
--- /dev/null
@@ -0,0 +1,17 @@
+--TEST--
+Bug #80185 (jdtounix() fails after 2037)
+--SKIPIF--
+<?php
+if (!extension_loaded('calendar')) die('skip ext/calendar required');
+if (PHP_INT_SIZE != 8) die("skip for 64bit platforms only");
+?>
+--FILE--
+<?php
+var_dump(jdtounix(2465712));
+var_dump(jdtounix(PHP_INT_MAX / 86400 + 2440588));
+var_dump(jdtounix(PHP_INT_MAX / 86400 + 2440589));
+?>
+--EXPECT--
+int(2170713600)
+int(9223372036854720000)
+bool(false)
diff --git a/ext/calendar/tests/bug80185_32bit.phpt b/ext/calendar/tests/bug80185_32bit.phpt
new file mode 100644 (file)
index 0000000..95ee050
--- /dev/null
@@ -0,0 +1,17 @@
+--TEST--
+Bug #80185 (jdtounix() fails after 2037)
+--SKIPIF--
+<?php
+if (!extension_loaded('calendar')) die('skip ext/calendar required');
+if (PHP_INT_SIZE != 4) die("skip for 32bit platforms only");
+?>
+--FILE--
+<?php
+var_dump(jdtounix(2465712));
+var_dump(jdtounix(PHP_INT_MAX / 86400 + 2440588));
+var_dump(jdtounix(PHP_INT_MAX / 86400 + 2440589));
+?>
+--EXPECT--
+bool(false)
+int(2147472000)
+bool(false)