summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@php.net>2008-03-04 11:46:09 +0000
committerDmitry Stogov <dmitry@php.net>2008-03-04 11:46:09 +0000
commit7089db25e08dac8ea30d6477573e7248a6cd8558 (patch)
tree79db392a27dd94f1d6af6e24eff54ac6b8b7920f
parentf3213ecacdfd7c978deae0ae19d217ee5c6075e4 (diff)
downloadphp-git-7089db25e08dac8ea30d6477573e7248a6cd8558.tar.gz
Fixed shared memory corruption of opcode caches
-rw-r--r--Zend/zend_execute_API.c23
-rw-r--r--Zend/zend_vm_def.h3
-rw-r--r--Zend/zend_vm_execute.h3
3 files changed, 23 insertions, 6 deletions
diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c
index 7e5074f752..dec7f67fe2 100644
--- a/Zend/zend_execute_API.c
+++ b/Zend/zend_execute_API.c
@@ -452,6 +452,19 @@ ZEND_API int zend_is_true(zval *op)
#define IS_CONSTANT_VISITED(p) (Z_TYPE_P(p) & IS_VISITED_CONSTANT)
#define MARK_CONSTANT_VISITED(p) Z_TYPE_P(p) |= IS_VISITED_CONSTANT
+static void zval_deep_copy(zval **p)
+{
+ zval *value;
+
+ ALLOC_ZVAL(value);
+ *value = **p;
+ Z_TYPE_P(value) &= ~IS_CONSTANT_INDEX;
+ zval_copy_ctor(value);
+ Z_TYPE_P(value) = Z_TYPE_PP(p);
+ INIT_PZVAL(value);
+ *p = value;
+}
+
ZEND_API int zval_update_constant_ex(zval **pp, void *arg, zend_class_entry *scope TSRMLS_DC)
{
zval *p = *pp;
@@ -503,6 +516,16 @@ ZEND_API int zval_update_constant_ex(zval **pp, void *arg, zend_class_entry *sco
p = *pp;
Z_TYPE_P(p) = IS_ARRAY;
+ if (!inline_change) {
+ zval *tmp;
+ HashTable *tmp_ht = NULL;
+
+ ALLOC_HASHTABLE(tmp_ht);
+ zend_hash_init(tmp_ht, zend_hash_num_elements(Z_ARRVAL_P(p)), NULL, ZVAL_PTR_DTOR, 0);
+ zend_hash_copy(tmp_ht, Z_ARRVAL_P(p), (copy_ctor_func_t) zval_deep_copy, (void *) &tmp, sizeof(zval *));
+ Z_ARRVAL_P(p) = tmp_ht;
+ }
+
/* First go over the array and see if there are any constant indices */
zend_hash_internal_pointer_reset(Z_ARRVAL_P(p));
while (zend_hash_get_current_data(Z_ARRVAL_P(p), (void **) &element)==SUCCESS) {
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index e9e5b3a7c6..4ea3dea5b3 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -2403,9 +2403,6 @@ ZEND_VM_HANDLER(64, ZEND_RECV_INIT, ANY, CONST)
ALLOC_ZVAL(default_value);
*default_value = opline->op2.u.constant;
- if (Z_TYPE(opline->op2.u.constant)==IS_CONSTANT_ARRAY) {
- zval_copy_ctor(default_value);
- }
default_value->refcount=1;
zval_update_constant(&default_value, 0 TSRMLS_CC);
default_value->refcount=0;
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index 0da39e33a5..79e1a10675 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -777,9 +777,6 @@ static int ZEND_RECV_INIT_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
ALLOC_ZVAL(default_value);
*default_value = opline->op2.u.constant;
- if (Z_TYPE(opline->op2.u.constant)==IS_CONSTANT_ARRAY) {
- zval_copy_ctor(default_value);
- }
default_value->refcount=1;
zval_update_constant(&default_value, 0 TSRMLS_CC);
default_value->refcount=0;