Skip to content

Commit b50b30c

Browse files
authored
standard: Fail unserialization when the C format is used for classes that are not Serializable (#22058)
Fixes #22046
1 parent b7cc1c1 commit b50b30c

4 files changed

Lines changed: 31 additions & 10 deletions

File tree

NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ PHP NEWS
2121
. Deprecate specifying a nullable return type for __debugInfo(). (timwolla)
2222
. Fixed bug GH-22142 (Assertion failure in zendi_try_get_long() on IS_UNDEF).
2323
(David Carlier)
24+
. Fixed bug GH-22046 (The unserialize function can lead to segfault when
25+
non-Serializable internal classes are serialized back with the C format).
26+
(kocsismate)
2427

2528
- BCMath:
2629
. Added NUL-byte validation to BCMath functions. (jorgsowa)

ext/standard/tests/serialize/serialization_objects_009.phpt

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,16 @@ eval('class C {}');
88
$b = unserialize($ser);
99

1010
var_dump($a, $b);
11-
1211
echo "Done";
1312
?>
1413
--EXPECTF--
15-
Warning: Class __PHP_Incomplete_Class has no unserializer in %sserialization_objects_009.php on line %d
14+
Warning: Class __PHP_Incomplete_Class has no unserializer in %s on line %d
15+
16+
Warning: unserialize(): Error at offset 11 of 18 bytes in %s on line %d
17+
18+
Warning: Class C has no unserializer in %s on line %d
1619

17-
Warning: Class C has no unserializer in %sserialization_objects_009.php on line %d
18-
object(__PHP_Incomplete_Class)#%d (1) {
19-
["__PHP_Incomplete_Class_Name"]=>
20-
string(1) "C"
21-
}
22-
object(C)#%d (0) {
23-
}
20+
Warning: unserialize(): Error at offset 11 of 18 bytes in %s on line %d
21+
bool(false)
22+
bool(false)
2423
Done

ext/standard/var_unserializer.re

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -770,7 +770,7 @@ static inline int object_custom(UNSERIALIZE_PARAMETER, zend_class_entry *ce)
770770

771771
if (ce->unserialize == NULL) {
772772
zend_error(E_WARNING, "Class %s has no unserializer", ZSTR_VAL(ce->name));
773-
object_init_ex(rval, ce);
773+
return 0;
774774
} else if (ce->unserialize(rval, ce, (const unsigned char*)*p, datalen, (zend_unserialize_data *)var_hash) != SUCCESS) {
775775
return 0;
776776
}

ext/uri/tests/gh22046.phpt

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
--TEST--
2+
GH-22046: The unserialize function can lead to segfault when internal classes are serialized back with the unsupported C format
3+
--FILE--
4+
<?php
5+
6+
$payload = 'C:14:"Uri\WhatWg\Url":0:{}';
7+
unserialize($payload);
8+
9+
$payload = 'C:15:"Uri\Rfc3986\Uri":0:{}';
10+
unserialize($payload);
11+
?>
12+
--EXPECTF--
13+
Warning: Class Uri\WhatWg\Url has no unserializer in %s on line %d
14+
15+
Warning: unserialize(): Error at offset 25 of 26 bytes in %s on line %d
16+
17+
Warning: Class Uri\Rfc3986\Uri has no unserializer in %s on line %d
18+
19+
Warning: unserialize(): Error at offset 26 of 27 bytes in %s on line %d

0 commit comments

Comments
 (0)