summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS2
-rw-r--r--ext/standard/tests/serialize/bug80411.phpt31
-rw-r--r--ext/standard/var.c2
3 files changed, 34 insertions, 1 deletions
diff --git a/NEWS b/NEWS
index b68c93a9da..0387c08514 100644
--- a/NEWS
+++ b/NEWS
@@ -18,6 +18,8 @@ PHP NEWS
- Standard:
. Fixed bug #80366 (Return Value of zend_fstat() not Checked). (sagpant, cmb)
+ . Fixed bug #80411 (References to null-serialized object break serialize()).
+ (Nikita)
- Tidy:
. Fixed bug #77594 (ob_tidyhandler is never reset). (cmb)
diff --git a/ext/standard/tests/serialize/bug80411.phpt b/ext/standard/tests/serialize/bug80411.phpt
new file mode 100644
index 0000000000..fe611f2629
--- /dev/null
+++ b/ext/standard/tests/serialize/bug80411.phpt
@@ -0,0 +1,31 @@
+--TEST--
+Bug #80411: References to null-serialized object break serialize()
+--FILE--
+<?php
+
+class UnSerializable implements Serializable
+{
+ public function serialize() {}
+ public function unserialize($serialized) {}
+}
+
+$unser = new UnSerializable();
+$arr = [$unser];
+$arr[1] = &$arr[0];
+$arr[2] = 'endcap';
+$arr[3] = &$arr[2];
+
+$data = serialize($arr);
+echo $data . PHP_EOL;
+$recovered = unserialize($data);
+var_export($recovered);
+
+?>
+--EXPECT--
+a:4:{i:0;N;i:1;N;i:2;s:6:"endcap";i:3;R:4;}
+array (
+ 0 => NULL,
+ 1 => NULL,
+ 2 => 'endcap',
+ 3 => 'endcap',
+)
diff --git a/ext/standard/var.c b/ext/standard/var.c
index 9f48063f25..98efdcc7f3 100644
--- a/ext/standard/var.c
+++ b/ext/standard/var.c
@@ -677,7 +677,7 @@ static inline zend_long php_add_var_hash(php_serialize_data_t data, zval *var) /
if (zv) {
/* References are only counted once, undo the data->n increment above */
- if (is_ref) {
+ if (is_ref && Z_LVAL_P(zv) != -1) {
data->n -= 1;
}