1
0
mirror of https://github.com/php/php-src.git synced 2026-03-27 09:42:22 +01:00

MFH: Fixed bug #46882 (Serialize / Unserialize misbehaviour under OS with different bit numbers)

This commit is contained in:
Matt Wilmas
2009-03-17 22:04:57 +00:00
parent 9d638e65c7
commit c06fb2f274
4 changed files with 74 additions and 18 deletions

2
NEWS
View File

@@ -18,6 +18,8 @@ PHP NEWS
addresses in the filter extension). (Ilia)
- Fixed bug #47430 (Errors after writing to nodeValue parameter of an absent
previousSibling). (Rob)
- Fixed bug #46882 (Serialize / Unserialize misbehaviour under OS with different
bit numbers). (Matt)
- Fixed bug #45799 (imagepng() crashes on empty image). (Martin McNickle,
Takeshi Abe)

View File

@@ -0,0 +1,8 @@
--TEST--
Bug #46882 (Serialize / Unserialize misbehaviour under OS with different bit numbers)
--FILE--
<?php
var_dump(unserialize('i:5000000000;') == 5000000000);
?>
--EXPECT--
bool(true)

View File

@@ -1,4 +1,4 @@
/* Generated by re2c 0.13.5 on Sat Oct 4 10:07:18 2008 */
/* Generated by re2c 0.13.5 on Tue Mar 17 16:18:30 2009 */
#line 1 "ext/standard/var_unserializer.re"
/*
+----------------------------------------------------------------------+
@@ -458,7 +458,7 @@ yy2:
yych = *(YYMARKER = ++YYCURSOR);
if (yych == ':') goto yy95;
yy3:
#line 698 "ext/standard/var_unserializer.re"
#line 721 "ext/standard/var_unserializer.re"
{ return 0; }
#line 464 "ext/standard/var_unserializer.c"
yy4:
@@ -503,7 +503,7 @@ yy13:
goto yy3;
yy14:
++YYCURSOR;
#line 692 "ext/standard/var_unserializer.re"
#line 715 "ext/standard/var_unserializer.re"
{
/* this is the case where we have less data than planned */
php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Unexpected end of serialized data");
@@ -539,7 +539,7 @@ yy20:
yych = *++YYCURSOR;
if (yych != '"') goto yy18;
++YYCURSOR;
#line 580 "ext/standard/var_unserializer.re"
#line 603 "ext/standard/var_unserializer.re"
{
size_t len, len2, len3, maxlen;
long elements;
@@ -676,7 +676,7 @@ yy27:
yych = *++YYCURSOR;
if (yych != '"') goto yy18;
++YYCURSOR;
#line 572 "ext/standard/var_unserializer.re"
#line 595 "ext/standard/var_unserializer.re"
{
INIT_PZVAL(*rval);
@@ -705,7 +705,7 @@ yy34:
yych = *++YYCURSOR;
if (yych != '{') goto yy18;
++YYCURSOR;
#line 550 "ext/standard/var_unserializer.re"
#line 573 "ext/standard/var_unserializer.re"
{
long elements = parse_iv(start + 2);
/* use iv() not uiv() in order to check data range */
@@ -748,7 +748,7 @@ yy41:
yych = *++YYCURSOR;
if (yych != '"') goto yy18;
++YYCURSOR;
#line 521 "ext/standard/var_unserializer.re"
#line 544 "ext/standard/var_unserializer.re"
{
size_t len, maxlen;
char *str;
@@ -798,7 +798,7 @@ yy48:
yych = *++YYCURSOR;
if (yych != '"') goto yy18;
++YYCURSOR;
#line 493 "ext/standard/var_unserializer.re"
#line 516 "ext/standard/var_unserializer.re"
{
size_t len, maxlen;
char *str;
@@ -914,14 +914,17 @@ yy61:
}
yy63:
++YYCURSOR;
#line 486 "ext/standard/var_unserializer.re"
#line 506 "ext/standard/var_unserializer.re"
{
#if SIZEOF_LONG == 4
use_double:
#endif
*p = YYCURSOR;
INIT_PZVAL(*rval);
ZVAL_DOUBLE(*rval, zend_strtod((const char *)start + 2, NULL));
return 1;
}
#line 925 "ext/standard/var_unserializer.c"
#line 928 "ext/standard/var_unserializer.c"
yy65:
yych = *++YYCURSOR;
if (yych <= ',') {
@@ -980,7 +983,7 @@ yy73:
yych = *++YYCURSOR;
if (yych != ';') goto yy18;
++YYCURSOR;
#line 471 "ext/standard/var_unserializer.re"
#line 491 "ext/standard/var_unserializer.re"
{
*p = YYCURSOR;
INIT_PZVAL(*rval);
@@ -995,7 +998,7 @@ yy73:
return 1;
}
#line 999 "ext/standard/var_unserializer.c"
#line 1002 "ext/standard/var_unserializer.c"
yy76:
yych = *++YYCURSOR;
if (yych == 'N') goto yy73;
@@ -1024,12 +1027,32 @@ yy79:
++YYCURSOR;
#line 464 "ext/standard/var_unserializer.re"
{
#if SIZEOF_LONG == 4
int digits = YYCURSOR - start - 3;
if (start[2] == '-' || start[2] == '+') {
digits--;
}
/* Use double for large long values that were serialized on a 64-bit system */
if (digits >= MAX_LENGTH_OF_LONG - 1) {
if (digits == MAX_LENGTH_OF_LONG - 1) {
int cmp = strncmp(YYCURSOR - MAX_LENGTH_OF_LONG, long_min_digits, MAX_LENGTH_OF_LONG - 1);
if (!(cmp < 0 || (cmp == 0 && start[2] == '-'))) {
goto use_double;
}
} else {
goto use_double;
}
}
#endif
*p = YYCURSOR;
INIT_PZVAL(*rval);
ZVAL_LONG(*rval, parse_iv(start + 2));
return 1;
}
#line 1033 "ext/standard/var_unserializer.c"
#line 1056 "ext/standard/var_unserializer.c"
yy83:
yych = *++YYCURSOR;
if (yych <= '/') goto yy18;
@@ -1044,7 +1067,7 @@ yy83:
ZVAL_BOOL(*rval, parse_iv(start + 2));
return 1;
}
#line 1048 "ext/standard/var_unserializer.c"
#line 1071 "ext/standard/var_unserializer.c"
yy87:
++YYCURSOR;
#line 450 "ext/standard/var_unserializer.re"
@@ -1054,7 +1077,7 @@ yy87:
ZVAL_NULL(*rval);
return 1;
}
#line 1058 "ext/standard/var_unserializer.c"
#line 1081 "ext/standard/var_unserializer.c"
yy89:
yych = *++YYCURSOR;
if (yych <= ',') {
@@ -1100,7 +1123,7 @@ yy91:
return 1;
}
#line 1104 "ext/standard/var_unserializer.c"
#line 1127 "ext/standard/var_unserializer.c"
yy95:
yych = *++YYCURSOR;
if (yych <= ',') {
@@ -1144,9 +1167,9 @@ yy97:
return 1;
}
#line 1148 "ext/standard/var_unserializer.c"
#line 1171 "ext/standard/var_unserializer.c"
}
#line 700 "ext/standard/var_unserializer.re"
#line 723 "ext/standard/var_unserializer.re"
return 0;

View File

@@ -462,6 +462,26 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
}
"i:" iv ";" {
#if SIZEOF_LONG == 4
int digits = YYCURSOR - start - 3;
if (start[2] == '-' || start[2] == '+') {
digits--;
}
/* Use double for large long values that were serialized on a 64-bit system */
if (digits >= MAX_LENGTH_OF_LONG - 1) {
if (digits == MAX_LENGTH_OF_LONG - 1) {
int cmp = strncmp(YYCURSOR - MAX_LENGTH_OF_LONG, long_min_digits, MAX_LENGTH_OF_LONG - 1);
if (!(cmp < 0 || (cmp == 0 && start[2] == '-'))) {
goto use_double;
}
} else {
goto use_double;
}
}
#endif
*p = YYCURSOR;
INIT_PZVAL(*rval);
ZVAL_LONG(*rval, parse_iv(start + 2));
@@ -484,6 +504,9 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
}
"d:" (iv | nv | nvexp) ";" {
#if SIZEOF_LONG == 4
use_double:
#endif
*p = YYCURSOR;
INIT_PZVAL(*rval);
ZVAL_DOUBLE(*rval, zend_strtod((const char *)start + 2, NULL));