Browse Source

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

experimental/5.3-FPM
Matt Wilmas 18 years ago
parent
commit
927880b5cc
  1. 8
      ext/standard/tests/serialize/bug46882.phpt
  2. 59
      ext/standard/var_unserializer.c
  3. 23
      ext/standard/var_unserializer.re

8
ext/standard/tests/serialize/bug46882.phpt

@ -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)

59
ext/standard/var_unserializer.c

@ -1,4 +1,4 @@
/* Generated by re2c 0.13.6.dev on Tue Nov 4 01:37:59 2008 */
/* Generated by re2c 0.13.5 on Tue Mar 17 15:55:10 2009 */
#line 1 "ext/standard/var_unserializer.re"
/*
+----------------------------------------------------------------------+
@ -456,7 +456,7 @@ yy2:
yych = *(YYMARKER = ++YYCURSOR);
if (yych == ':') goto yy95;
yy3:
#line 699 "ext/standard/var_unserializer.re"
#line 722 "ext/standard/var_unserializer.re"
{ return 0; }
#line 462 "ext/standard/var_unserializer.c"
yy4:
@ -501,7 +501,7 @@ yy13:
goto yy3;
yy14:
++YYCURSOR;
#line 693 "ext/standard/var_unserializer.re"
#line 716 "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");
@ -537,7 +537,7 @@ yy20:
yych = *++YYCURSOR;
if (yych != '"') goto yy18;
++YYCURSOR;
#line 576 "ext/standard/var_unserializer.re"
#line 599 "ext/standard/var_unserializer.re"
{
size_t len, len2, len3, maxlen;
long elements;
@ -679,7 +679,7 @@ yy27:
yych = *++YYCURSOR;
if (yych != '"') goto yy18;
++YYCURSOR;
#line 568 "ext/standard/var_unserializer.re"
#line 591 "ext/standard/var_unserializer.re"
{
INIT_PZVAL(*rval);
@ -708,7 +708,7 @@ yy34:
yych = *++YYCURSOR;
if (yych != '{') goto yy18;
++YYCURSOR;
#line 548 "ext/standard/var_unserializer.re"
#line 571 "ext/standard/var_unserializer.re"
{
long elements = parse_iv(start + 2);
/* use iv() not uiv() in order to check data range */
@ -749,7 +749,7 @@ yy41:
yych = *++YYCURSOR;
if (yych != '"') goto yy18;
++YYCURSOR;
#line 519 "ext/standard/var_unserializer.re"
#line 542 "ext/standard/var_unserializer.re"
{
size_t len, maxlen;
char *str;
@ -799,7 +799,7 @@ yy48:
yych = *++YYCURSOR;
if (yych != '"') goto yy18;
++YYCURSOR;
#line 491 "ext/standard/var_unserializer.re"
#line 514 "ext/standard/var_unserializer.re"
{
size_t len, maxlen;
char *str;
@ -915,14 +915,17 @@ yy61:
}
yy63:
++YYCURSOR;
#line 484 "ext/standard/var_unserializer.re"
#line 504 "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 926 "ext/standard/var_unserializer.c"
#line 929 "ext/standard/var_unserializer.c"
yy65:
yych = *++YYCURSOR;
if (yych <= ',') {
@ -981,7 +984,7 @@ yy73:
yych = *++YYCURSOR;
if (yych != ';') goto yy18;
++YYCURSOR;
#line 469 "ext/standard/var_unserializer.re"
#line 489 "ext/standard/var_unserializer.re"
{
*p = YYCURSOR;
INIT_PZVAL(*rval);
@ -996,7 +999,7 @@ yy73:
return 1;
}
#line 1000 "ext/standard/var_unserializer.c"
#line 1003 "ext/standard/var_unserializer.c"
yy76:
yych = *++YYCURSOR;
if (yych == 'N') goto yy73;
@ -1025,12 +1028,32 @@ yy79:
++YYCURSOR;
#line 462 "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 1034 "ext/standard/var_unserializer.c"
#line 1057 "ext/standard/var_unserializer.c"
yy83:
yych = *++YYCURSOR;
if (yych <= '/') goto yy18;
@ -1045,7 +1068,7 @@ yy83:
ZVAL_BOOL(*rval, parse_iv(start + 2));
return 1;
}
#line 1049 "ext/standard/var_unserializer.c"
#line 1072 "ext/standard/var_unserializer.c"
yy87:
++YYCURSOR;
#line 448 "ext/standard/var_unserializer.re"
@ -1055,7 +1078,7 @@ yy87:
ZVAL_NULL(*rval);
return 1;
}
#line 1059 "ext/standard/var_unserializer.c"
#line 1082 "ext/standard/var_unserializer.c"
yy89:
yych = *++YYCURSOR;
if (yych <= ',') {
@ -1101,7 +1124,7 @@ yy91:
return 1;
}
#line 1105 "ext/standard/var_unserializer.c"
#line 1128 "ext/standard/var_unserializer.c"
yy95:
yych = *++YYCURSOR;
if (yych <= ',') {
@ -1145,9 +1168,9 @@ yy97:
return 1;
}
#line 1149 "ext/standard/var_unserializer.c"
#line 1172 "ext/standard/var_unserializer.c"
}
#line 701 "ext/standard/var_unserializer.re"
#line 724 "ext/standard/var_unserializer.re"
return 0;

23
ext/standard/var_unserializer.re

@ -460,6 +460,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));
@ -482,6 +502,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));

Loading…
Cancel
Save