cataphract                               Sun, 19 Dec 2010 23:47:00 +0000

Revision: http://svn.php.net/viewvc?view=revision&revision=306475

Log:
- Fixed bug #53574 (Integer overflow in SdnToJulian, sometimes leading to
  segfault).

Bug: http://bugs.php.net/53574 (Assigned) Integer overflow in SdnToJulian
      
Changed paths:
    U   php/php-src/branches/PHP_5_3/NEWS
    U   php/php-src/branches/PHP_5_3/ext/calendar/julian.c
    A   php/php-src/branches/PHP_5_3/ext/calendar/tests/bug53574.phpt
    U   php/php-src/trunk/ext/calendar/julian.c
    A   php/php-src/trunk/ext/calendar/tests/bug53574.phpt

Modified: php/php-src/branches/PHP_5_3/NEWS
===================================================================
--- php/php-src/branches/PHP_5_3/NEWS   2010-12-19 23:46:27 UTC (rev 306474)
+++ php/php-src/branches/PHP_5_3/NEWS   2010-12-19 23:47:00 UTC (rev 306475)
@@ -12,6 +12,10 @@
     (Ilia)
   . Fixed bug #48607 (fwrite() doesn't check reply from ftp server before
     exiting). (Ilia)
+
+- Calendar extension:
+  . Fixed bug #53574 (Integer overflow in SdnToJulian, sometimes leading to
+    segfault). (Gustavo)

 - DateTime extension:
   . Fixed a bug in DateTime->modify() where absolute date/time statements had

Modified: php/php-src/branches/PHP_5_3/ext/calendar/julian.c
===================================================================
--- php/php-src/branches/PHP_5_3/ext/calendar/julian.c  2010-12-19 23:46:27 UTC 
(rev 306474)
+++ php/php-src/branches/PHP_5_3/ext/calendar/julian.c  2010-12-19 23:47:00 UTC 
(rev 306475)
@@ -146,6 +146,7 @@
  **************************************************************************/

 #include "sdncal.h"
+#include <limits.h>

 #define JULIAN_SDN_OFFSET         32083
 #define DAYS_PER_5_MONTHS  153
@@ -164,15 +165,22 @@
        int dayOfYear;

        if (sdn <= 0) {
-               *pYear = 0;
-               *pMonth = 0;
-               *pDay = 0;
-               return;
+               goto fail;
        }
-       temp = (sdn + JULIAN_SDN_OFFSET) * 4 - 1;
+       /* Check for overflow */
+       if (sdn > (LONG_MAX - JULIAN_SDN_OFFSET * 4 + 1) / 4 || sdn < LONG_MIN 
/ 4) {
+               goto fail;
+       }
+       temp = sdn * 4 + (JULIAN_SDN_OFFSET * 4 - 1);

        /* Calculate the year and day of year (1 <= dayOfYear <= 366). */
-       year = temp / DAYS_PER_4_YEARS;
+       {
+               long yearl = temp / DAYS_PER_4_YEARS;
+               if (yearl > INT_MAX || yearl < INT_MIN) {
+                       goto fail;
+               }
+               year = (int) yearl;
+       }
        dayOfYear = (temp % DAYS_PER_4_YEARS) / 4 + 1;

        /* Calculate the month and day of month. */
@@ -196,6 +204,12 @@
        *pYear = year;
        *pMonth = month;
        *pDay = day;
+       return;
+
+fail:
+       *pYear = 0;
+       *pMonth = 0;
+       *pDay = 0;
 }

 long int JulianToSdn(

Added: php/php-src/branches/PHP_5_3/ext/calendar/tests/bug53574.phpt
===================================================================
--- php/php-src/branches/PHP_5_3/ext/calendar/tests/bug53574.phpt               
                (rev 0)
+++ php/php-src/branches/PHP_5_3/ext/calendar/tests/bug53574.phpt       
2010-12-19 23:47:00 UTC (rev 306475)
@@ -0,0 +1,35 @@
+--TEST--
+Bug #53574 (Integer overflow in SdnToJulian; leads to segfault)
+--SKIPIF--
+<?php include 'skipif.inc'; ?>
+--FILE--
+<?php
+if (PHP_INT_MAX == 0x7FFFFFFF) {
+       $x = 882858043;
+} else {
+       $x = 3315881921229094912;
+}
+
+var_dump(cal_from_jd($x, CAL_JULIAN));
+--EXPECT--
+array(9) {
+  ["date"]=>
+  string(5) "0/0/0"
+  ["month"]=>
+  int(0)
+  ["day"]=>
+  int(0)
+  ["year"]=>
+  int(0)
+  ["dow"]=>
+  int(3)
+  ["abbrevdayname"]=>
+  string(3) "Wed"
+  ["dayname"]=>
+  string(9) "Wednesday"
+  ["abbrevmonth"]=>
+  string(0) ""
+  ["monthname"]=>
+  string(0) ""
+}
+

Modified: php/php-src/trunk/ext/calendar/julian.c
===================================================================
--- php/php-src/trunk/ext/calendar/julian.c     2010-12-19 23:46:27 UTC (rev 
306474)
+++ php/php-src/trunk/ext/calendar/julian.c     2010-12-19 23:47:00 UTC (rev 
306475)
@@ -146,6 +146,7 @@
  **************************************************************************/

 #include "sdncal.h"
+#include <limits.h>

 #define JULIAN_SDN_OFFSET         32083
 #define DAYS_PER_5_MONTHS  153
@@ -164,15 +165,22 @@
        int dayOfYear;

        if (sdn <= 0) {
-               *pYear = 0;
-               *pMonth = 0;
-               *pDay = 0;
-               return;
+               goto fail;
        }
-       temp = (sdn + JULIAN_SDN_OFFSET) * 4 - 1;
+       /* Check for overflow */
+       if (sdn > (LONG_MAX - JULIAN_SDN_OFFSET * 4 + 1) / 4 || sdn < LONG_MIN 
/ 4) {
+               goto fail;
+       }
+       temp = sdn * 4 + (JULIAN_SDN_OFFSET * 4 - 1);

        /* Calculate the year and day of year (1 <= dayOfYear <= 366). */
-       year = temp / DAYS_PER_4_YEARS;
+       {
+               long yearl = temp / DAYS_PER_4_YEARS;
+               if (yearl > INT_MAX || yearl < INT_MIN) {
+                       goto fail;
+               }
+               year = (int) yearl;
+       }
        dayOfYear = (temp % DAYS_PER_4_YEARS) / 4 + 1;

        /* Calculate the month and day of month. */
@@ -196,6 +204,12 @@
        *pYear = year;
        *pMonth = month;
        *pDay = day;
+       return;
+
+fail:
+       *pYear = 0;
+       *pMonth = 0;
+       *pDay = 0;
 }

 long int JulianToSdn(

Added: php/php-src/trunk/ext/calendar/tests/bug53574.phpt
===================================================================
--- php/php-src/trunk/ext/calendar/tests/bug53574.phpt                          
(rev 0)
+++ php/php-src/trunk/ext/calendar/tests/bug53574.phpt  2010-12-19 23:47:00 UTC 
(rev 306475)
@@ -0,0 +1,35 @@
+--TEST--
+Bug #53574 (Integer overflow in SdnToJulian; leads to segfault)
+--SKIPIF--
+<?php include 'skipif.inc'; ?>
+--FILE--
+<?php
+if (PHP_INT_MAX == 0x7FFFFFFF) {
+       $x = 882858043;
+} else {
+       $x = 3315881921229094912;
+}
+
+var_dump(cal_from_jd($x, CAL_JULIAN));
+--EXPECT--
+array(9) {
+  ["date"]=>
+  string(5) "0/0/0"
+  ["month"]=>
+  int(0)
+  ["day"]=>
+  int(0)
+  ["year"]=>
+  int(0)
+  ["dow"]=>
+  int(3)
+  ["abbrevdayname"]=>
+  string(3) "Wed"
+  ["dayname"]=>
+  string(9) "Wednesday"
+  ["abbrevmonth"]=>
+  string(0) ""
+  ["monthname"]=>
+  string(0) ""
+}
+

-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to