Skip to content

Commit 013e0f9

Browse files
committed
Merge branch 'PHP-8.2'
* PHP-8.2: unserialize: Strictly check for `:{` at object start (#10214)
2 parents 410e786 + f2e8c5d commit 013e0f9

File tree

7 files changed

+97
-3
lines changed

7 files changed

+97
-3
lines changed

ext/gmp/tests/bug74670.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,5 @@ $str = 'C:3:"GMP":4:{s:6666666666:""}';
88
var_dump(unserialize($str));
99
?>
1010
--EXPECTF--
11-
Warning: unserialize(): Error at offset 13 of 29 bytes in %s on line %d
11+
Warning: unserialize(): Error at offset 17 of 29 bytes in %s on line %d
1212
bool(false)

ext/spl/tests/bug73029.phpt

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,13 @@ Bug #73029: Missing type check when unserializing SplArray
33
--FILE--
44
<?php
55
try {
6+
$a = 'C:11:"ArrayObject":19:{x:i:0;r:2;;m:a:0:{}}';
7+
$m = unserialize($a);
8+
$x = $m[2];
9+
} catch(UnexpectedValueException $e) {
10+
print $e->getMessage() . "\n";
11+
}
12+
try {
613
$a = 'C:11:"ArrayObject":19:0x:i:0;r:2;;m:a:0:{}}';
714
$m = unserialize($a);
815
$x = $m[2];
@@ -11,6 +18,10 @@ $x = $m[2];
1118
}
1219
?>
1320
DONE
14-
--EXPECT--
21+
--EXPECTF--
1522
Error at offset 10 of 19 bytes
23+
24+
Warning: unserialize(): Error at offset 22 of 43 bytes in %s on line %d
25+
26+
Warning: Trying to access array offset on value of type bool in %s on line %d
1627
DONE

ext/standard/tests/serialize/bug73341.phpt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,13 @@
22
Bug #73144 (Use-afte-free in ArrayObject Deserialization)
33
--FILE--
44
<?php
5+
try {
6+
$token = 'a:2:{i:0;O:1:"0":2:{s:1:"0";i:0;s:1:"0";a:1:{i:0;C:11:"ArrayObject":7:{x:i:0;r}';
7+
$obj = unserialize($token);
8+
} catch(Exception $e) {
9+
echo $e->getMessage()."\n";
10+
}
11+
512
try {
613
$token = 'a:2:{i:0;O:1:"0":2:0s:1:"0";i:0;s:1:"0";a:1:{i:0;C:11:"ArrayObject":7:{x:i:0;r}';
714
$obj = unserialize($token);
@@ -20,5 +27,7 @@ unserialize($exploit);
2027
--EXPECTF--
2128
Error at offset 6 of 7 bytes
2229

30+
Warning: unserialize(): Error at offset 19 of 79 bytes in %s on line %d
31+
2332
Warning: ArrayObject::unserialize(): Unexpected end of serialized data in %sbug73341.php on line %d
2433
Error at offset 24 of 34 bytes

ext/standard/tests/serialize/bug74111.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,5 @@ $s = 'O:8:"stdClass":00000000';
66
var_dump(unserialize($s));
77
?>
88
--EXPECTF--
9-
Warning: unserialize(): Error at offset 25 of 23 bytes in %s on line %d
9+
Warning: unserialize(): Error at offset 23 of 23 bytes in %s on line %d
1010
bool(false)
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
--TEST--
2+
Object serialization / unserialization: Strict format
3+
--FILE--
4+
<?php
5+
class A {public $a;}
6+
7+
var_dump(unserialize('O:1:"A":1x{s:1:"a";N;}'));
8+
//0123456789012345678901
9+
var_dump(unserialize('O:1:"A":1:xs:1:"a";N;}'));
10+
//0123456789012345678901
11+
?>
12+
--EXPECTF--
13+
Warning: unserialize(): Error at offset 9 of 22 bytes in %s on line %d
14+
bool(false)
15+
16+
Warning: unserialize(): Error at offset 10 of 22 bytes in %s on line %d
17+
bool(false)
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
--TEST--
2+
Object serialization / unserialization: Strict format (2)
3+
--FILE--
4+
<?php
5+
class A implements Serializable {
6+
public function serialize() {}
7+
public function unserialize($data) {}
8+
public function __serialize() {}
9+
public function __unserialize($data) {}
10+
}
11+
12+
var_dump(unserialize('C:1:"A":3x{foo}'));
13+
//012345678901234
14+
var_dump(unserialize('C:1:"A":3:xfoo}'));
15+
//012345678901234
16+
var_dump(unserialize('C:1:"A":3:{foox'));
17+
//012345678901234
18+
var_dump(unserialize('C:1:"A":'));
19+
//01234567
20+
21+
?>
22+
--EXPECTF--
23+
Warning: unserialize(): Error at offset 9 of 15 bytes in %s on line %d
24+
bool(false)
25+
26+
Warning: unserialize(): Error at offset 10 of 15 bytes in %s on line %d
27+
bool(false)
28+
29+
Warning: unserialize(): Error at offset 14 of 15 bytes in %s on line %d
30+
bool(false)
31+
32+
Warning: unserialize(): Error at offset 8 of 8 bytes in %s on line %d
33+
bool(false)

ext/standard/var_unserializer.re

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -744,6 +744,19 @@ static inline int object_custom(UNSERIALIZE_PARAMETER, zend_class_entry *ce)
744744

745745
datalen = parse_iv2((*p) + 2, p);
746746

747+
if (max - (*p) < 2) {
748+
return 0;
749+
}
750+
751+
if ((*p)[0] != ':') {
752+
return 0;
753+
}
754+
755+
if ((*p)[1] != '{') {
756+
(*p) += 1;
757+
return 0;
758+
}
759+
747760
(*p) += 2;
748761

749762
if (datalen < 0 || (max - (*p)) <= datalen) {
@@ -755,6 +768,7 @@ static inline int object_custom(UNSERIALIZE_PARAMETER, zend_class_entry *ce)
755768
* with unserialize reading past the end of the passed buffer if the string is not
756769
* appropriately terminated (usually NUL terminated, but '}' is also sufficient.) */
757770
if ((*p)[datalen] != '}') {
771+
(*p) += datalen;
758772
return 0;
759773
}
760774

@@ -1294,6 +1308,16 @@ object ":" uiv ":" ["] {
12941308
return 0;
12951309
}
12961310

1311+
YYCURSOR = *p;
1312+
1313+
if (*(YYCURSOR) != ':') {
1314+
return 0;
1315+
}
1316+
if (*(YYCURSOR+1) != '{') {
1317+
*p = YYCURSOR+1;
1318+
return 0;
1319+
}
1320+
12971321
*p += 2;
12981322

12991323
has_unserialize = !incomplete_class && ce->__unserialize;

0 commit comments

Comments
 (0)