]> granicus.if.org Git - php/commitdiff
Fixed string interning during constants substitution
authorDmitry Stogov <dmitry@zend.com>
Wed, 1 Nov 2017 07:34:39 +0000 (10:34 +0300)
committerDmitry Stogov <dmitry@zend.com>
Wed, 1 Nov 2017 07:34:39 +0000 (10:34 +0300)
Zend/tests/class_constants_005.phpt [new file with mode: 0644]
Zend/zend_constants.c
ext/opcache/ZendAccelerator.c

diff --git a/Zend/tests/class_constants_005.phpt b/Zend/tests/class_constants_005.phpt
new file mode 100644 (file)
index 0000000..de53c2c
--- /dev/null
@@ -0,0 +1,12 @@
+--TEST--
+String interning during constants substitution
+--INI--
+opcache.enable_cli=0
+--FILE--
+<?php
+define ("A", "." . ord(26) . ".");
+eval("class A {const a = A;}");
+var_dump(A::a);
+?>
+--EXPECT--
+string(4) ".50."
index 100d0a263bb1cac574b2a60ecb0d55b68cf3ff6b..bbb4824d1d3083b6967cc249ab59ca1eae864f75 100644 (file)
@@ -445,13 +445,21 @@ ZEND_API zend_constant* ZEND_FASTCALL zend_quick_get_constant(const zval *key, u
 
 static void* zend_hash_add_constant(HashTable *ht, zend_string *key, zend_constant *c)
 {
-       void *ret;
-       zend_constant *copy = pemalloc(sizeof(zend_constant), c->flags & CONST_PERSISTENT);
-
-       memcpy(copy, c, sizeof(zend_constant));
-       ret = zend_hash_add_ptr(ht, key, copy);
-       if (!ret) {
-               pefree(copy, c->flags & CONST_PERSISTENT);
+       zval *ret, tmp;
+       zend_constant *copy;
+
+       ZVAL_PTR(&tmp, NULL);
+       ret = zend_hash_add(ht, key, &tmp);
+       if (EXPECTED(ret)) {
+               Z_PTR_P(ret) = copy = pemalloc(sizeof(zend_constant), c->flags & CONST_PERSISTENT);
+               memcpy(copy, c, sizeof(zend_constant));
+               if (Z_TYPE(copy->value) == IS_STRING && !ZSTR_IS_INTERNED(Z_STR(copy->value))) {
+                       SEPARATE_STRING(&copy->value);
+                       Z_STR(copy->value) = zend_new_interned_string(Z_STR(copy->value));
+                       if (ZSTR_IS_INTERNED(Z_STR(copy->value))) {
+                               Z_TYPE_FLAGS(copy->value) &= ~ (IS_TYPE_REFCOUNTED | IS_TYPE_COPYABLE);
+                       }
+               }
        }
        return ret;
 }
@@ -466,9 +474,7 @@ ZEND_API int zend_register_constant(zend_constant *c)
        printf("Registering constant for module %d\n", c->module_number);
 #endif
 
-    if (c->module_number != PHP_USER_CONSTANT) {
-               c->name = zend_new_interned_string(c->name);
-       }
+       c->name = zend_new_interned_string(c->name);
 
        if (!(c->flags & CONST_CS)) {
                lowercase_name = zend_string_alloc(ZSTR_LEN(c->name), c->flags & CONST_PERSISTENT);
index 1d314894294c803457dc73454963b189697a2166..2a66077631ab608d2887d430b2896326685c7e24 100644 (file)
@@ -644,6 +644,9 @@ static void accel_copy_permanent_strings(zend_new_interned_string_func_t new_int
                if (c->name) {
                        c->name = new_interned_string(c->name);
                }
+               if (Z_TYPE(c->value) == IS_STRING) {
+                       Z_STR(c->value) = new_interned_string(Z_STR(c->value));
+               }
        } ZEND_HASH_FOREACH_END();
 
        /* auto globals hash keys and names */