Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 125c1ff

Browse files
committed
Zend: Implement __unserialize() for Exception/Error
1 parent ca3a3d7 commit 125c1ff

File tree

6 files changed

+160
-27
lines changed

6 files changed

+160
-27
lines changed

‎Zend/zend_exceptions.c‎

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -396,6 +396,106 @@ ZEND_METHOD(Exception, __wakeup)
396396
}
397397
/* }}} */
398398

399+
ZEND_METHOD(Exception, __unserialize)
400+
{
401+
HashTable *ht;
402+
403+
if (zend_parse_parameters(ZEND_NUM_ARGS(), "h", &ht) == FAILURE) {
404+
RETURN_THROWS();
405+
}
406+
407+
zval *tmp = zend_hash_str_find(ht, ZEND_STRL("0円*0円message"));
408+
if (tmp) {
409+
if (Z_TYPE_P(tmp) != IS_STRING) {
410+
zend_type_error("Cannot assign %s to property %s::$message of type string",
411+
zend_zval_type_name(tmp), ZSTR_VAL(Z_OBJCE_P(ZEND_THIS)->name));
412+
RETURN_THROWS();
413+
}
414+
zend_update_property_num_checked(NULL, Z_OBJ_P(ZEND_THIS), ZEND_EXCEPTION_MESSAGE_OFF, ZSTR_KNOWN(ZEND_STR_MESSAGE), tmp);
415+
zval_add_ref(tmp);
416+
if (UNEXPECTED(EG(exception))) {
417+
RETURN_THROWS();
418+
}
419+
}
420+
421+
tmp = zend_hash_str_find(ht, ZEND_STRL("0円*0円code"));
422+
if (tmp) {
423+
if (Z_TYPE_P(tmp) != IS_LONG) {
424+
zend_type_error("Cannot assign %s to property %s::$code of type int",
425+
zend_zval_type_name(tmp), ZSTR_VAL(Z_OBJCE_P(ZEND_THIS)->name));
426+
RETURN_THROWS();
427+
}
428+
zend_update_property_num_checked(NULL, Z_OBJ_P(ZEND_THIS), ZEND_EXCEPTION_CODE_OFF, ZSTR_KNOWN(ZEND_STR_CODE), tmp);
429+
if (UNEXPECTED(EG(exception))) {
430+
RETURN_THROWS();
431+
}
432+
}
433+
434+
tmp = zend_hash_str_find(ht, ZEND_STRL("0円*0円file"));
435+
if (tmp) {
436+
if (Z_TYPE_P(tmp) != IS_STRING) {
437+
zend_type_error("Cannot assign %s to property %s::$file of type string",
438+
zend_zval_type_name(tmp), ZSTR_VAL(Z_OBJCE_P(ZEND_THIS)->name));
439+
RETURN_THROWS();
440+
}
441+
zend_update_property_num_checked(NULL, Z_OBJ_P(ZEND_THIS), ZEND_EXCEPTION_FILE_OFF, ZSTR_KNOWN(ZEND_STR_FILE), tmp);
442+
zval_add_ref(tmp);
443+
if (UNEXPECTED(EG(exception))) {
444+
RETURN_THROWS();
445+
}
446+
}
447+
448+
tmp = zend_hash_str_find(ht, ZEND_STRL("0円*0円line"));
449+
if (tmp) {
450+
if (Z_TYPE_P(tmp) != IS_LONG) {
451+
zend_type_error("Cannot assign %s to property %s::$line of type int",
452+
zend_zval_type_name(tmp), ZSTR_VAL(Z_OBJCE_P(ZEND_THIS)->name));
453+
RETURN_THROWS();
454+
}
455+
zend_update_property_num_checked(NULL, Z_OBJ_P(ZEND_THIS), ZEND_EXCEPTION_LINE_OFF, ZSTR_KNOWN(ZEND_STR_LINE), tmp);
456+
if (UNEXPECTED(EG(exception))) {
457+
RETURN_THROWS();
458+
}
459+
}
460+
461+
if (instanceof_function(Z_OBJCE_P(ZEND_THIS), zend_ce_exception)) {
462+
tmp = zend_hash_str_find(ht, ZEND_STRL("0円Exception0円trace"));
463+
} else {
464+
tmp = zend_hash_str_find(ht, ZEND_STRL("0円Error0円trace"));
465+
}
466+
if (tmp) {
467+
if (Z_TYPE_P(tmp) != IS_ARRAY) {
468+
zend_type_error("Cannot assign %s to property %s::$trace of type array",
469+
zend_zval_type_name(tmp), ZSTR_VAL(Z_OBJCE_P(ZEND_THIS)->name));
470+
RETURN_THROWS();
471+
}
472+
zend_update_property_num_checked(NULL, Z_OBJ_P(ZEND_THIS), ZEND_EXCEPTION_TRACE_OFF, ZSTR_KNOWN(ZEND_STR_TRACE), tmp);
473+
zval_add_ref(tmp);
474+
if (UNEXPECTED(EG(exception))) {
475+
RETURN_THROWS();
476+
}
477+
}
478+
479+
if (instanceof_function(Z_OBJCE_P(ZEND_THIS), zend_ce_exception)) {
480+
tmp = zend_hash_str_find(ht, ZEND_STRL("0円Exception0円previous"));
481+
} else {
482+
tmp = zend_hash_str_find(ht, ZEND_STRL("0円Error0円previous"));
483+
}
484+
if (tmp) {
485+
if (Z_TYPE_P(tmp) != IS_NULL && !instanceof_function(Z_OBJCE_P(tmp), zend_ce_throwable)) {
486+
zend_type_error("Cannot assign %s to property %s::$previous of type ?Throwable",
487+
zend_zval_type_name(tmp), ZSTR_VAL(Z_OBJCE_P(ZEND_THIS)->name));
488+
RETURN_THROWS();
489+
}
490+
zend_update_property_num_checked(NULL, Z_OBJ_P(ZEND_THIS), ZEND_EXCEPTION_PREVIOUS_OFF, ZSTR_KNOWN(ZEND_STR_PREVIOUS), tmp);
491+
zval_add_ref(tmp);
492+
if (UNEXPECTED(EG(exception))) {
493+
RETURN_THROWS();
494+
}
495+
}
496+
}
497+
/* }}} */
498+
399499
/* {{{ ErrorException constructor */
400500
ZEND_METHOD(ErrorException, __construct)
401501
{

‎Zend/zend_exceptions.stub.php‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ public function __construct(string $message = "", int $code = 0, ?Throwable $pre
4747
/** @tentative-return-type */
4848
public function __wakeup(): void {}
4949

50+
public function __unserialize(array $data): void {}
51+
5052
final public function getMessage(): string {}
5153

5254
/** @return int */
@@ -111,6 +113,11 @@ public function __construct(string $message = "", int $code = 0, ?Throwable $pre
111113
*/
112114
public function __wakeup(): void {}
113115

116+
/**
117+
* @implementation-alias Exception::__unserialize
118+
*/
119+
public function __unserialize(array $data): void {}
120+
114121
/** @implementation-alias Exception::getMessage */
115122
final public function getMessage(): string {}
116123

‎Zend/zend_exceptions_arginfo.h‎

Lines changed: 10 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎ext/standard/tests/serialize/bug69152.phpt‎

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,25 @@
22
Bug #69152: Type Confusion Infoleak Vulnerability in unserialize()
33
--FILE--
44
<?php
5-
$x = unserialize('O:9:"exception":1:{s:16:"'."0円".'Exception'."0円".'trace";s:4:"ryat";}');
6-
echo $x;
7-
$x = unserialize('O:4:"test":1:{s:27:"__PHP_Incomplete_Class_Name";R:1;}');
8-
$x->test();
5+
try {
6+
$x = unserialize('O:9:"exception":1:{s:16:"'."0円".'Exception'."0円".'trace";s:4:"ryat";}');
7+
var_dump($x);
8+
} catch (Throwable $e) {
9+
echo $e::class, ': ', $e->getMessage(), PHP_EOL;
10+
}
11+
try {
12+
$x = unserialize('O:4:"test":1:{s:27:"__PHP_Incomplete_Class_Name";R:1;}');
13+
var_dump($x);
14+
$x->test();
15+
} catch (Throwable $e) {
16+
echo $e::class, ': ', $e->getMessage(), PHP_EOL;
17+
}
918

1019
?>
11-
--EXPECTF--
12-
Fatal error: Uncaught TypeError: Cannot assign string to property Exception::$trace of type array in %s:%d
13-
Stack trace:
14-
#0 %s(%d): unserialize('O:9:"exception"...')
15-
#1 {main}
16-
thrown in %s on line %d
20+
--EXPECT--
21+
TypeError: Cannot assign string to property Exception::$trace of type array
22+
object(__PHP_Incomplete_Class)#1 (1) {
23+
["__PHP_Incomplete_Class_Name"]=>
24+
*RECURSION*
25+
}
26+
Error: The script tried to call a method on an incomplete object. Please ensure that the class definition "unknown" of the object you are trying to operate on was loaded _before_ unserialize() gets called or provide an autoloader to load the class definition

‎ext/standard/tests/serialize/bug69793.phpt‎

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22
Bug #69793: Remotely triggerable stack exhaustion via recursive method calls
33
--FILE--
44
<?php
5-
$e = unserialize('O:9:"Exception":7:{s:17:"'."0円".'Exception'."0円".'string";s:1:"a";s:7:"'."0円".'*'."0円".'code";i:0;s:7:"'."0円".'*'."0円".'file";s:0:"";s:7:"'."0円".'*'."0円".'line";i:1337;s:16:"'."0円".'Exception'."0円".'trace";a:0:{}s:19:"'."0円".'Exception'."0円".'previous";i:10;s:10:"'."0円".'*'."0円".'message";N;}');
6-
7-
var_dump($e."");
5+
try {
6+
$e = unserialize('O:9:"Exception":7:{s:17:"'."0円".'Exception'."0円".'string";s:1:"a";s:7:"'."0円".'*'."0円".'code";i:0;s:7:"'."0円".'*'."0円".'file";s:0:"";s:7:"'."0円".'*'."0円".'line";i:1337;s:16:"'."0円".'Exception'."0円".'trace";a:0:{}s:19:"'."0円".'Exception'."0円".'previous";i:10;s:10:"'."0円".'*'."0円".'message";N;}');
7+
var_dump($e);
8+
var_dump($e."");
9+
} catch (Throwable $e) {
10+
echo $e::class, ': ', $e->getMessage(), PHP_EOL;
11+
}
812
?>
9-
--EXPECTF--
10-
Fatal error: Uncaught TypeError: Cannot assign int to property Exception::$previous of type ?Throwable in %s:%d
11-
Stack trace:
12-
#0 %s(%d): unserialize('O:9:"Exception"...')
13-
#1 {main}
14-
thrown in %s on line %d
13+
--EXPECT--
14+
TypeError: Cannot assign null to property Exception::$message of type string

‎ext/standard/tests/serialize/bug70963.phpt‎

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,19 @@
22
Bug #70963 (Unserialize shows UNKNOW in result)
33
--FILE--
44
<?php
5-
var_dump(unserialize('a:2:{i:0;O:9:"exception":1:{s:16:"'."0円".'Exception'."0円".'trace";s:4:"test";}i:1;R:3;}'));
6-
var_dump(unserialize('a:2:{i:0;O:9:"exception":1:{s:16:"'."0円".'Exception'."0円".'trace";s:4:"test";}i:1;r:3;}'));
5+
try {
6+
var_dump(unserialize('a:2:{i:0;O:9:"exception":1:{s:16:"'."0円".'Exception'."0円".'trace";s:4:"test";}i:1;R:3;}'));
7+
} catch (Throwable $e) {
8+
echo $e::class, ': ', $e->getMessage(), PHP_EOL;
9+
}
10+
try {
11+
var_dump(unserialize('a:2:{i:0;O:9:"exception":1:{s:16:"'."0円".'Exception'."0円".'trace";s:4:"test";}i:1;r:3;}'));
12+
} catch (Throwable $e) {
13+
echo $e::class, ': ', $e->getMessage(), PHP_EOL;
14+
}
715
?>
816
--EXPECTF--
9-
Fatal error: Uncaught TypeError: Cannot assign string to property Exception::$trace of type array in %s:%d
10-
Stack trace:
11-
#0 %s(%d): unserialize('a:2:{i:0;O:9:"e...')
12-
#1 {main}
13-
thrown in %s on line %d
17+
TypeError: Cannot assign string to property Exception::$trace of type array
18+
19+
Warning: unserialize(): Error at offset 72 of 73 bytes in %s on line %d
20+
TypeError: Cannot assign string to property Exception::$trace of type array

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /