summaryrefslogtreecommitdiff
path: root/Zend/zend_string.c
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2017-11-03 21:00:07 +0300
committerDmitry Stogov <dmitry@zend.com>2017-11-03 21:00:07 +0300
commit26b2b27a25e998c80426ffa7752c7c750a74e554 (patch)
treea550198c602c7889a861716736e7aa67d936375f /Zend/zend_string.c
parent3d12e704592a57950bee3de400f82de0d154c2aa (diff)
downloadphp-git-26b2b27a25e998c80426ffa7752c7c750a74e554.tar.gz
Don't intern strings in-place if their refcoung greater than 1
Diffstat (limited to 'Zend/zend_string.c')
-rw-r--r--Zend/zend_string.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/Zend/zend_string.c b/Zend/zend_string.c
index 2fcaefcbdc..ad51148d4a 100644
--- a/Zend/zend_string.c
+++ b/Zend/zend_string.c
@@ -169,6 +169,14 @@ static zend_string *zend_new_interned_string_permanent(zend_string *str)
return ret;
}
+ ZEND_ASSERT(GC_FLAGS(str) & GC_PERSISTENT);
+ if (GC_REFCOUNT(str) > 1) {
+ zend_ulong h = ZSTR_H(str);
+ zend_string_delref(str);
+ str = zend_string_init(ZSTR_VAL(str), ZSTR_LEN(str), 1);
+ ZSTR_H(str) = h;
+ }
+
return zend_add_interned_string(str, &interned_strings_permanent, IS_STR_PERMANENT);
}
@@ -196,6 +204,14 @@ static zend_string *zend_new_interned_string_request(zend_string *str)
}
/* Create a short living interned, freed after the request. */
+ ZEND_ASSERT(!(GC_FLAGS(str) & GC_PERSISTENT));
+ if (GC_REFCOUNT(str) > 1) {
+ zend_ulong h = ZSTR_H(str);
+ zend_string_delref(str);
+ str = zend_string_init(ZSTR_VAL(str), ZSTR_LEN(str), 0);
+ ZSTR_H(str) = h;
+ }
+
ret = zend_add_interned_string(str, &CG(interned_strings), 0);
return ret;