diff options
author | Nikita Popov <nikic@php.net> | 2014-09-24 11:58:13 +0200 |
---|---|---|
committer | Nikita Popov <nikic@php.net> | 2014-09-24 12:06:19 +0200 |
commit | 75860fa8e1d8ce0c9fd2b505bf7663a4936a7a39 (patch) | |
tree | 9b4e10cca902d23a4981a2ee56d1b7ed410ecb69 | |
parent | c45924b954e297ada0bb9b4582235922be0a106f (diff) | |
download | php-git-75860fa8e1d8ce0c9fd2b505bf7663a4936a7a39.tar.gz |
Fix counting of "R:" references in serialize()
-rw-r--r-- | ext/standard/tests/serialize/counting_of_references.phpt | 14 | ||||
-rw-r--r-- | ext/standard/var.c | 10 |
2 files changed, 22 insertions, 2 deletions
diff --git a/ext/standard/tests/serialize/counting_of_references.phpt b/ext/standard/tests/serialize/counting_of_references.phpt new file mode 100644 index 0000000000..e7ead96759 --- /dev/null +++ b/ext/standard/tests/serialize/counting_of_references.phpt @@ -0,0 +1,14 @@ +--TEST-- +References are not counted twice +--FILE-- +<?php + +$ref1 = 1; +$ref2 = 2; + +$arr = [&$ref1, &$ref1, &$ref2, &$ref2]; +var_dump(serialize($arr)); + +?> +--EXPECT-- +string(38) "a:4:{i:0;i:1;i:1;R:2;i:2;i:2;i:3;R:3;}" diff --git a/ext/standard/var.c b/ext/standard/var.c index 194715edf0..53fd54c647 100644 --- a/ext/standard/var.c +++ b/ext/standard/var.c @@ -604,15 +604,16 @@ static inline uint32_t php_add_var_hash(php_serialize_data_t data, zval *var TSR { zval *zv; zend_ulong key; + zend_bool is_ref = Z_ISREF_P(var); data->n += 1; - if (Z_TYPE_P(var) != IS_OBJECT && Z_TYPE_P(var) != IS_REFERENCE) { + if (!is_ref && Z_TYPE_P(var) != IS_OBJECT) { return 0; } /* References to objects are treated as if the reference didn't exist */ - if (Z_TYPE_P(var) == IS_REFERENCE && Z_TYPE_P(Z_REFVAL_P(var)) == IS_OBJECT) { + if (is_ref && Z_TYPE_P(Z_REFVAL_P(var)) == IS_OBJECT) { var = Z_REFVAL_P(var); } @@ -622,6 +623,11 @@ static inline uint32_t php_add_var_hash(php_serialize_data_t data, zval *var TSR zv = zend_hash_index_find(&data->ht, key); if (zv) { + /* References are only counted once, undo the data->n increment above */ + if (is_ref) { + data->n -= 1; + } + return Z_LVAL_P(zv); } else { zval zv_n; |