From: Nikita Popov Date: Wed, 24 Sep 2014 09:58:13 +0000 (+0200) Subject: Fix counting of "R:" references in serialize() X-Git-Tag: PRE_NATIVE_TLS_MERGE~158^2~39 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=75860fa8e1d8ce0c9fd2b505bf7663a4936a7a39;p=php Fix counting of "R:" references in serialize() --- 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-- + +--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;