Skip to content

Commit c2acdbd

Browse files
committed
Improved the fix for bug #67072, thanks Nikita
1 parent 6e1e98d commit c2acdbd

File tree

4 files changed

+50
-44
lines changed

4 files changed

+50
-44
lines changed

ext/standard/tests/serialize/005.phpt

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -156,10 +156,11 @@ object(TestNAOld)#%d (0) {
156156
}
157157
===NANew===
158158
unserializer(TestNANew)
159-
TestNew::unserialize()
160-
TestNew::__wakeup()
161-
object(TestNANew)#%d (0) {
162-
}
159+
160+
Warning: Erroneous data format for unserializing 'TestNANew' in %s005.php on line %d
161+
162+
Notice: unserialize(): Error at offset 19 of 20 bytes in %s005.php on line %d
163+
bool(false)
163164
===NANew2===
164165
unserializer(TestNANew2)
165166
TestNew::unserialize()

ext/standard/tests/serialize/bug67072.phpt

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@ Bug #67072 Echoing unserialized "SplFileObject" crash
66
?>
77
===DONE==
88
--EXPECTF--
9-
Fatal error: Uncaught exception 'Exception' with message 'Unserialization of 'SplFileObject' is not allowed' in %sbug67072.php:2
10-
Stack trace:
11-
#0 %sbug67072.php(2): unserialize('O:13:"SplFileOb...')
12-
#1 {main}
13-
thrown in %sbug67072.php on line 2
9+
Warning: Erroneous data format for unserializing 'SplFileObject' in %sbug67072.php on line %d
10+
11+
Notice: unserialize(): Error at offset 24 of 64 bytes in %sbug67072.php on line %d
12+
===DONE==

ext/standard/var_unserializer.c

Lines changed: 36 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Generated by re2c 0.13.5 on Thu Apr 17 10:03:26 2014 */
1+
/* Generated by re2c 0.13.5 on Fri Apr 18 15:07:27 2014 */
22
#line 1 "ext/standard/var_unserializer.re"
33
/*
44
+----------------------------------------------------------------------+
@@ -396,9 +396,12 @@ static inline long object_common1(UNSERIALIZE_PARAMETER, zend_class_entry *ce)
396396

397397
(*p) += 2;
398398

399-
if (ce->unserialize == NULL) {
399+
if (ce->serialize == NULL) {
400400
object_init_ex(*rval, ce);
401-
} else if (ce->unserialize(rval, ce, (const unsigned char*)*p, elements, (zend_unserialize_data *)var_hash TSRMLS_CC) != SUCCESS) {
401+
} else {
402+
/* If this class implements Serializable, it should not land here but in object_custom(). The passed string
403+
obviously doesn't descend from the regular serializer. */
404+
zend_error(E_WARNING, "Erroneous data format for unserializing '%s'", ce->name);
402405
return 0;
403406
}
404407

@@ -466,7 +469,7 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
466469

467470

468471

469-
#line 470 "ext/standard/var_unserializer.c"
472+
#line 473 "ext/standard/var_unserializer.c"
470473
{
471474
YYCTYPE yych;
472475
static const unsigned char yybm[] = {
@@ -526,9 +529,9 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
526529
yych = *(YYMARKER = ++YYCURSOR);
527530
if (yych == ':') goto yy95;
528531
yy3:
529-
#line 821 "ext/standard/var_unserializer.re"
532+
#line 824 "ext/standard/var_unserializer.re"
530533
{ return 0; }
531-
#line 532 "ext/standard/var_unserializer.c"
534+
#line 535 "ext/standard/var_unserializer.c"
532535
yy4:
533536
yych = *(YYMARKER = ++YYCURSOR);
534537
if (yych == ':') goto yy89;
@@ -571,13 +574,13 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
571574
goto yy3;
572575
yy14:
573576
++YYCURSOR;
574-
#line 815 "ext/standard/var_unserializer.re"
577+
#line 818 "ext/standard/var_unserializer.re"
575578
{
576579
/* this is the case where we have less data than planned */
577580
php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Unexpected end of serialized data");
578581
return 0; /* not sure if it should be 0 or 1 here? */
579582
}
580-
#line 581 "ext/standard/var_unserializer.c"
583+
#line 584 "ext/standard/var_unserializer.c"
581584
yy16:
582585
yych = *++YYCURSOR;
583586
goto yy3;
@@ -607,7 +610,7 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
607610
yych = *++YYCURSOR;
608611
if (yych != '"') goto yy18;
609612
++YYCURSOR;
610-
#line 669 "ext/standard/var_unserializer.re"
613+
#line 672 "ext/standard/var_unserializer.re"
611614
{
612615
size_t len, len2, len3, maxlen;
613616
long elements;
@@ -753,7 +756,7 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
753756

754757
return object_common2(UNSERIALIZE_PASSTHRU, elements);
755758
}
756-
#line 757 "ext/standard/var_unserializer.c"
759+
#line 760 "ext/standard/var_unserializer.c"
757760
yy25:
758761
yych = *++YYCURSOR;
759762
if (yych <= ',') {
@@ -778,15 +781,15 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
778781
yych = *++YYCURSOR;
779782
if (yych != '"') goto yy18;
780783
++YYCURSOR;
781-
#line 661 "ext/standard/var_unserializer.re"
784+
#line 664 "ext/standard/var_unserializer.re"
782785
{
783786

784787
INIT_PZVAL(*rval);
785788

786789
return object_common2(UNSERIALIZE_PASSTHRU,
787790
object_common1(UNSERIALIZE_PASSTHRU, ZEND_STANDARD_CLASS_DEF_PTR));
788791
}
789-
#line 790 "ext/standard/var_unserializer.c"
792+
#line 793 "ext/standard/var_unserializer.c"
790793
yy32:
791794
yych = *++YYCURSOR;
792795
if (yych == '+') goto yy33;
@@ -807,7 +810,7 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
807810
yych = *++YYCURSOR;
808811
if (yych != '{') goto yy18;
809812
++YYCURSOR;
810-
#line 641 "ext/standard/var_unserializer.re"
813+
#line 644 "ext/standard/var_unserializer.re"
811814
{
812815
long elements = parse_iv(start + 2);
813816
/* use iv() not uiv() in order to check data range */
@@ -827,7 +830,7 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
827830

828831
return finish_nested_data(UNSERIALIZE_PASSTHRU);
829832
}
830-
#line 831 "ext/standard/var_unserializer.c"
833+
#line 834 "ext/standard/var_unserializer.c"
831834
yy39:
832835
yych = *++YYCURSOR;
833836
if (yych == '+') goto yy40;
@@ -848,7 +851,7 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
848851
yych = *++YYCURSOR;
849852
if (yych != '"') goto yy18;
850853
++YYCURSOR;
851-
#line 612 "ext/standard/var_unserializer.re"
854+
#line 615 "ext/standard/var_unserializer.re"
852855
{
853856
size_t len, maxlen;
854857
char *str;
@@ -877,7 +880,7 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
877880
ZVAL_STRINGL(*rval, str, len, 0);
878881
return 1;
879882
}
880-
#line 881 "ext/standard/var_unserializer.c"
883+
#line 884 "ext/standard/var_unserializer.c"
881884
yy46:
882885
yych = *++YYCURSOR;
883886
if (yych == '+') goto yy47;
@@ -898,7 +901,7 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
898901
yych = *++YYCURSOR;
899902
if (yych != '"') goto yy18;
900903
++YYCURSOR;
901-
#line 584 "ext/standard/var_unserializer.re"
904+
#line 587 "ext/standard/var_unserializer.re"
902905
{
903906
size_t len, maxlen;
904907
char *str;
@@ -926,7 +929,7 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
926929
ZVAL_STRINGL(*rval, str, len, 1);
927930
return 1;
928931
}
929-
#line 930 "ext/standard/var_unserializer.c"
932+
#line 933 "ext/standard/var_unserializer.c"
930933
yy53:
931934
yych = *++YYCURSOR;
932935
if (yych <= '/') {
@@ -1014,7 +1017,7 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
10141017
}
10151018
yy63:
10161019
++YYCURSOR;
1017-
#line 574 "ext/standard/var_unserializer.re"
1020+
#line 577 "ext/standard/var_unserializer.re"
10181021
{
10191022
#if SIZEOF_LONG == 4
10201023
use_double:
@@ -1024,7 +1027,7 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
10241027
ZVAL_DOUBLE(*rval, zend_strtod((const char *)start + 2, NULL));
10251028
return 1;
10261029
}
1027-
#line 1028 "ext/standard/var_unserializer.c"
1030+
#line 1031 "ext/standard/var_unserializer.c"
10281031
yy65:
10291032
yych = *++YYCURSOR;
10301033
if (yych <= ',') {
@@ -1083,7 +1086,7 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
10831086
yych = *++YYCURSOR;
10841087
if (yych != ';') goto yy18;
10851088
++YYCURSOR;
1086-
#line 559 "ext/standard/var_unserializer.re"
1089+
#line 562 "ext/standard/var_unserializer.re"
10871090
{
10881091
*p = YYCURSOR;
10891092
INIT_PZVAL(*rval);
@@ -1098,7 +1101,7 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
10981101

10991102
return 1;
11001103
}
1101-
#line 1102 "ext/standard/var_unserializer.c"
1104+
#line 1105 "ext/standard/var_unserializer.c"
11021105
yy76:
11031106
yych = *++YYCURSOR;
11041107
if (yych == 'N') goto yy73;
@@ -1125,7 +1128,7 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
11251128
if (yych <= '9') goto yy79;
11261129
if (yych != ';') goto yy18;
11271130
++YYCURSOR;
1128-
#line 532 "ext/standard/var_unserializer.re"
1131+
#line 535 "ext/standard/var_unserializer.re"
11291132
{
11301133
#if SIZEOF_LONG == 4
11311134
int digits = YYCURSOR - start - 3;
@@ -1152,32 +1155,32 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
11521155
ZVAL_LONG(*rval, parse_iv(start + 2));
11531156
return 1;
11541157
}
1155-
#line 1156 "ext/standard/var_unserializer.c"
1158+
#line 1159 "ext/standard/var_unserializer.c"
11561159
yy83:
11571160
yych = *++YYCURSOR;
11581161
if (yych <= '/') goto yy18;
11591162
if (yych >= '2') goto yy18;
11601163
yych = *++YYCURSOR;
11611164
if (yych != ';') goto yy18;
11621165
++YYCURSOR;
1163-
#line 525 "ext/standard/var_unserializer.re"
1166+
#line 528 "ext/standard/var_unserializer.re"
11641167
{
11651168
*p = YYCURSOR;
11661169
INIT_PZVAL(*rval);
11671170
ZVAL_BOOL(*rval, parse_iv(start + 2));
11681171
return 1;
11691172
}
1170-
#line 1171 "ext/standard/var_unserializer.c"
1173+
#line 1174 "ext/standard/var_unserializer.c"
11711174
yy87:
11721175
++YYCURSOR;
1173-
#line 518 "ext/standard/var_unserializer.re"
1176+
#line 521 "ext/standard/var_unserializer.re"
11741177
{
11751178
*p = YYCURSOR;
11761179
INIT_PZVAL(*rval);
11771180
ZVAL_NULL(*rval);
11781181
return 1;
11791182
}
1180-
#line 1181 "ext/standard/var_unserializer.c"
1183+
#line 1184 "ext/standard/var_unserializer.c"
11811184
yy89:
11821185
yych = *++YYCURSOR;
11831186
if (yych <= ',') {
@@ -1200,7 +1203,7 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
12001203
if (yych <= '9') goto yy91;
12011204
if (yych != ';') goto yy18;
12021205
++YYCURSOR;
1203-
#line 495 "ext/standard/var_unserializer.re"
1206+
#line 498 "ext/standard/var_unserializer.re"
12041207
{
12051208
long id;
12061209

@@ -1223,7 +1226,7 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
12231226

12241227
return 1;
12251228
}
1226-
#line 1227 "ext/standard/var_unserializer.c"
1229+
#line 1230 "ext/standard/var_unserializer.c"
12271230
yy95:
12281231
yych = *++YYCURSOR;
12291232
if (yych <= ',') {
@@ -1246,7 +1249,7 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
12461249
if (yych <= '9') goto yy97;
12471250
if (yych != ';') goto yy18;
12481251
++YYCURSOR;
1249-
#line 474 "ext/standard/var_unserializer.re"
1252+
#line 477 "ext/standard/var_unserializer.re"
12501253
{
12511254
long id;
12521255

@@ -1267,9 +1270,9 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
12671270

12681271
return 1;
12691272
}
1270-
#line 1271 "ext/standard/var_unserializer.c"
1273+
#line 1274 "ext/standard/var_unserializer.c"
12711274
}
1272-
#line 823 "ext/standard/var_unserializer.re"
1275+
#line 826 "ext/standard/var_unserializer.re"
12731276

12741277

12751278
return 0;

ext/standard/var_unserializer.re

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -400,9 +400,12 @@ static inline long object_common1(UNSERIALIZE_PARAMETER, zend_class_entry *ce)
400400

401401
(*p) += 2;
402402

403-
if (ce->unserialize == NULL) {
403+
if (ce->serialize == NULL) {
404404
object_init_ex(*rval, ce);
405-
} else if (ce->unserialize(rval, ce, (const unsigned char*)*p, elements, (zend_unserialize_data *)var_hash TSRMLS_CC) != SUCCESS) {
405+
} else {
406+
/* If this class implements Serializable, it should not land here but in object_custom(). The passed string
407+
obviously doesn't descend from the regular serializer. */
408+
zend_error(E_WARNING, "Erroneous data format for unserializing '%s'", ce->name);
406409
return 0;
407410
}
408411

0 commit comments

Comments
 (0)