From 29433f9fd581574e11b1ccb2942d1022e9e2173a Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Mon, 16 Jan 2017 14:25:58 +0100 Subject: [PATCH] Make unserialize() ref unwrapping compatible with 7.0 Also fix output difference in merged test (unrelated). --- ext/standard/tests/serialize/bug69425.phpt | 4 +++- ext/standard/var.c | 8 +++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/ext/standard/tests/serialize/bug69425.phpt b/ext/standard/tests/serialize/bug69425.phpt index bfa8b9b369..e39f855f23 100644 --- a/ext/standard/tests/serialize/bug69425.phpt +++ b/ext/standard/tests/serialize/bug69425.phpt @@ -26,7 +26,7 @@ var_dump($data); int(1) array(2) { [0]=> - object(DateInterval)#1 (15) { + object(DateInterval)#1 (16) { ["y"]=> int(-1) ["m"]=> @@ -39,6 +39,8 @@ array(2) { int(-1) ["s"]=> int(-1) + ["f"]=> + float(-1) ["weekday"]=> int(-1) ["weekday_behavior"]=> diff --git a/ext/standard/var.c b/ext/standard/var.c index 490a68c175..03368287d7 100644 --- a/ext/standard/var.c +++ b/ext/standard/var.c @@ -1118,7 +1118,6 @@ PHP_FUNCTION(unserialize) } RETVAL_FALSE; } else { - ZVAL_DEREF(retval); ZVAL_COPY(return_value, retval); } @@ -1130,6 +1129,13 @@ PHP_FUNCTION(unserialize) /* Reset to previous allowed_classes in case this is a nested call */ php_var_unserialize_set_allowed_classes(var_hash, prev_class_hash); PHP_VAR_UNSERIALIZE_DESTROY(var_hash); + + /* Per calling convention we must not return a reference here, so unwrap. We're doing this at + * the very end, because __wakeup() calls performed during UNSERIALIZE_DESTROY might affect + * the value we unwrap here. This is compatible with behavior in PHP <=7.0. */ + if (Z_ISREF_P(return_value)) { + zend_unwrap_reference(return_value); + } } /* }}} */ -- 2.40.0