# [PATCH] segfault with string dimensions

- Thread: https://externals.io/message/28292
- Original archive: https://news-web.php.net/php.internals/28292
- Started by Brian Shire on 2007-03-08T02:45:48+00:00
- Messages: 2
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #28292 — Brian Shire — 2007-03-08T02:45:48+00:00

URL: https://externals.io/message/28292#28292

Let me know if I have any issues with my patch/thinking here:

Reproduce code:

<?php

$x = "a";
$x['x']['y'] += 1;

?>


The zend_binary_assign_op_helper_* function isn't checking that the  
value returned from _get_zval_ptr_ptr_var is set, so it faults  
instead of letting zend_fetch_dimension_address trigger the "Cannot  
use string offset as an array" error.


patch:

Index: Zend/zend_vm_def.h
===================================================================
RCS file: /repository/ZendEngine2/zend_vm_def.h,v
retrieving revision 1.59.2.29.2.39
diff -u -r1.59.2.29.2.39 zend_vm_def.h
--- Zend/zend_vm_def.h	25 Feb 2007 16:02:43 -0000	1.59.2.29.2.39
+++ Zend/zend_vm_def.h	8 Mar 2007 02:39:02 -0000
@@ -408,11 +408,11 @@
		case ZEND_ASSIGN_DIM: {
				zval **object_ptr = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_W);
-				if (OP1_TYPE != IS_CV && !OP1_FREE) {
+				if (object_ptr && OP1_TYPE != IS_CV && !OP1_FREE) {
					(*object_ptr)->refcount++;  /* undo the effect of  
get_obj_zval_ptr_ptr() */
				}
-				if (Z_TYPE_PP(object_ptr) == IS_OBJECT) {
+				if (object_ptr && Z_TYPE_PP(object_ptr) == IS_OBJECT) {
					ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_obj_helper,  
binary_op, binary_op);
				} else {
					zend_op *op_data = opline+1;
Index: Zend/zend_vm_execute.h
===================================================================
RCS file: /repository/ZendEngine2/zend_vm_execute.h,v
retrieving revision 1.62.2.30.2.39
diff -u -r1.62.2.30.2.39 zend_vm_execute.h
--- Zend/zend_vm_execute.h	25 Feb 2007 16:02:43 -0000	1.62.2.30.2.39
+++ Zend/zend_vm_execute.h	8 Mar 2007 02:39:03 -0000
@@ -8583,11 +8583,11 @@
		case ZEND_ASSIGN_DIM: {
				zval **object_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts),  
&free_op1 TSRMLS_CC);
-				if (IS_VAR != IS_CV && !(free_op1.var != NULL)) {
+				if (object_ptr && IS_VAR != IS_CV && !(free_op1.var != NULL)) {
					(*object_ptr)->refcount++;  /* undo the effect of  
get_obj_zval_ptr_ptr() */
				}
-				if (Z_TYPE_PP(object_ptr) == IS_OBJECT) {
+				if (object_ptr && Z_TYPE_PP(object_ptr) == IS_OBJECT) {
					return zend_binary_assign_op_obj_helper_SPEC_VAR_CONST 
(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
				} else {
					zend_op *op_data = opline+1;
@@ -10067,11 +10067,11 @@
		case ZEND_ASSIGN_DIM: {
				zval **object_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts),  
&free_op1 TSRMLS_CC);
-				if (IS_VAR != IS_CV && !(free_op1.var != NULL)) {
+				if (object_ptr && IS_VAR != IS_CV && !(free_op1.var != NULL)) {
					(*object_ptr)->refcount++;  /* undo the effect of  
get_obj_zval_ptr_ptr() */
				}
-				if (Z_TYPE_PP(object_ptr) == IS_OBJECT) {
+				if (object_ptr && Z_TYPE_PP(object_ptr) == IS_OBJECT) {
					return zend_binary_assign_op_obj_helper_SPEC_VAR_TMP(binary_op,  
ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
				} else {
					zend_op *op_data = opline+1;
@@ -11555,11 +11555,11 @@
		case ZEND_ASSIGN_DIM: {
				zval **object_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts),  
&free_op1 TSRMLS_CC);
-				if (IS_VAR != IS_CV && !(free_op1.var != NULL)) {
+				if (object_ptr && IS_VAR != IS_CV && !(free_op1.var != NULL)) {
					(*object_ptr)->refcount++;  /* undo the effect of  
get_obj_zval_ptr_ptr() */
				}
-				if (Z_TYPE_PP(object_ptr) == IS_OBJECT) {
+				if (object_ptr && Z_TYPE_PP(object_ptr) == IS_OBJECT) {
					return zend_binary_assign_op_obj_helper_SPEC_VAR_VAR(binary_op,  
ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
				} else {
					zend_op *op_data = opline+1;
@@ -12847,11 +12847,11 @@
		case ZEND_ASSIGN_DIM: {
				zval **object_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts),  
&free_op1 TSRMLS_CC);
-				if (IS_VAR != IS_CV && !(free_op1.var != NULL)) {
+				if (object_ptr && IS_VAR != IS_CV && !(free_op1.var != NULL)) {
					(*object_ptr)->refcount++;  /* undo the effect of  
get_obj_zval_ptr_ptr() */
				}
-				if (Z_TYPE_PP(object_ptr) == IS_OBJECT) {
+				if (object_ptr && Z_TYPE_PP(object_ptr) == IS_OBJECT) {
					return zend_binary_assign_op_obj_helper_SPEC_VAR_UNUSED 
(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
				} else {
					zend_op *op_data = opline+1;
@@ -13516,11 +13516,11 @@
		case ZEND_ASSIGN_DIM: {
				zval **object_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts),  
&free_op1 TSRMLS_CC);
-				if (IS_VAR != IS_CV && !(free_op1.var != NULL)) {
+				if (object_ptr && IS_VAR != IS_CV && !(free_op1.var != NULL)) {
					(*object_ptr)->refcount++;  /* undo the effect of  
get_obj_zval_ptr_ptr() */
				}
-				if (Z_TYPE_PP(object_ptr) == IS_OBJECT) {
+				if (object_ptr && Z_TYPE_PP(object_ptr) == IS_OBJECT) {
					return zend_binary_assign_op_obj_helper_SPEC_VAR_CV(binary_op,  
ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
				} else {
					zend_op *op_data = opline+1;
@@ -14882,11 +14882,11 @@
		case ZEND_ASSIGN_DIM: {
				zval **object_ptr = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
-				if (IS_UNUSED != IS_CV && !0) {
+				if (object_ptr && IS_UNUSED != IS_CV && !0) {
					(*object_ptr)->refcount++;  /* undo the effect of  
get_obj_zval_ptr_ptr() */
				}
-				if (Z_TYPE_PP(object_ptr) == IS_OBJECT) {
+				if (object_ptr && Z_TYPE_PP(object_ptr) == IS_OBJECT) {
					return zend_binary_assign_op_obj_helper_SPEC_UNUSED_CONST 
(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
				} else {
					zend_op *op_data = opline+1;
@@ -15885,11 +15885,11 @@
		case ZEND_ASSIGN_DIM: {
				zval **object_ptr = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
-				if (IS_UNUSED != IS_CV && !0) {
+				if (object_ptr && IS_UNUSED != IS_CV && !0) {
					(*object_ptr)->refcount++;  /* undo the effect of  
get_obj_zval_ptr_ptr() */
				}
-				if (Z_TYPE_PP(object_ptr) == IS_OBJECT) {
+				if (object_ptr && Z_TYPE_PP(object_ptr) == IS_OBJECT) {
					return zend_binary_assign_op_obj_helper_SPEC_UNUSED_TMP 
(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
				} else {
					zend_op *op_data = opline+1;
@@ -16849,11 +16849,11 @@
		case ZEND_ASSIGN_DIM: {
				zval **object_ptr = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
-				if (IS_UNUSED != IS_CV && !0) {
+				if (object_ptr && IS_UNUSED != IS_CV && !0) {
					(*object_ptr)->refcount++;  /* undo the effect of  
get_obj_zval_ptr_ptr() */
				}
-				if (Z_TYPE_PP(object_ptr) == IS_OBJECT) {
+				if (object_ptr && Z_TYPE_PP(object_ptr) == IS_OBJECT) {
					return zend_binary_assign_op_obj_helper_SPEC_UNUSED_VAR 
(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
				} else {
					zend_op *op_data = opline+1;
@@ -17813,11 +17813,11 @@
		case ZEND_ASSIGN_DIM: {
				zval **object_ptr = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
-				if (IS_UNUSED != IS_CV && !0) {
+				if (object_ptr && IS_UNUSED != IS_CV && !0) {
					(*object_ptr)->refcount++;  /* undo the effect of  
get_obj_zval_ptr_ptr() */
				}
-				if (Z_TYPE_PP(object_ptr) == IS_OBJECT) {
+				if (object_ptr && Z_TYPE_PP(object_ptr) == IS_OBJECT) {
					return zend_binary_assign_op_obj_helper_SPEC_UNUSED_UNUSED 
(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
				} else {
					zend_op *op_data = opline+1;
@@ -18079,11 +18079,11 @@
		case ZEND_ASSIGN_DIM: {
				zval **object_ptr = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
-				if (IS_UNUSED != IS_CV && !0) {
+				if (object_ptr && IS_UNUSED != IS_CV && !0) {
					(*object_ptr)->refcount++;  /* undo the effect of  
get_obj_zval_ptr_ptr() */
				}
-				if (Z_TYPE_PP(object_ptr) == IS_OBJECT) {
+				if (object_ptr && Z_TYPE_PP(object_ptr) == IS_OBJECT) {
					return zend_binary_assign_op_obj_helper_SPEC_UNUSED_CV 
(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
				} else {
					zend_op *op_data = opline+1;
@@ -20495,11 +20495,11 @@
		case ZEND_ASSIGN_DIM: {
				zval **object_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts),  
BP_VAR_W TSRMLS_CC);
-				if (IS_CV != IS_CV && !0) {
+				if (object_ptr && IS_CV != IS_CV && !0) {
					(*object_ptr)->refcount++;  /* undo the effect of  
get_obj_zval_ptr_ptr() */
				}
-				if (Z_TYPE_PP(object_ptr) == IS_OBJECT) {
+				if (object_ptr && Z_TYPE_PP(object_ptr) == IS_OBJECT) {
					return zend_binary_assign_op_obj_helper_SPEC_CV_CONST(binary_op,  
ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
				} else {
					zend_op *op_data = opline+1;
@@ -21971,11 +21971,11 @@
		case ZEND_ASSIGN_DIM: {
				zval **object_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts),  
BP_VAR_W TSRMLS_CC);
-				if (IS_CV != IS_CV && !0) {
+				if (object_ptr && IS_CV != IS_CV && !0) {
					(*object_ptr)->refcount++;  /* undo the effect of  
get_obj_zval_ptr_ptr() */
				}
-				if (Z_TYPE_PP(object_ptr) == IS_OBJECT) {
+				if (object_ptr && Z_TYPE_PP(object_ptr) == IS_OBJECT) {
					return zend_binary_assign_op_obj_helper_SPEC_CV_TMP(binary_op,  
ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
				} else {
					zend_op *op_data = opline+1;
@@ -23451,11 +23451,11 @@
		case ZEND_ASSIGN_DIM: {
				zval **object_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts),  
BP_VAR_W TSRMLS_CC);
-				if (IS_CV != IS_CV && !0) {
+				if (object_ptr && IS_CV != IS_CV && !0) {
					(*object_ptr)->refcount++;  /* undo the effect of  
get_obj_zval_ptr_ptr() */
				}
-				if (Z_TYPE_PP(object_ptr) == IS_OBJECT) {
+				if (object_ptr && Z_TYPE_PP(object_ptr) == IS_OBJECT) {
					return zend_binary_assign_op_obj_helper_SPEC_CV_VAR(binary_op,  
ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
				} else {
					zend_op *op_data = opline+1;
@@ -24734,11 +24734,11 @@
		case ZEND_ASSIGN_DIM: {
				zval **object_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts),  
BP_VAR_W TSRMLS_CC);
-				if (IS_CV != IS_CV && !0) {
+				if (object_ptr && IS_CV != IS_CV && !0) {
					(*object_ptr)->refcount++;  /* undo the effect of  
get_obj_zval_ptr_ptr() */
				}
-				if (Z_TYPE_PP(object_ptr) == IS_OBJECT) {
+				if (object_ptr && Z_TYPE_PP(object_ptr) == IS_OBJECT) {
					return zend_binary_assign_op_obj_helper_SPEC_CV_UNUSED 
(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
				} else {
					zend_op *op_data = opline+1;
@@ -25402,11 +25402,11 @@
		case ZEND_ASSIGN_DIM: {
				zval **object_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts),  
BP_VAR_W TSRMLS_CC);
-				if (IS_CV != IS_CV && !0) {
+				if (object_ptr && IS_CV != IS_CV && !0) {
					(*object_ptr)->refcount++;  /* undo the effect of  
get_obj_zval_ptr_ptr() */
				}
-				if (Z_TYPE_PP(object_ptr) == IS_OBJECT) {
+				if (object_ptr && Z_TYPE_PP(object_ptr) == IS_OBJECT) {
					return zend_binary_assign_op_obj_helper_SPEC_CV_CV(binary_op,  
ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
				} else {
					zend_op *op_data = opline+1;





- Shire
     shire@facebook.com
     shire@php.net

---

## #28299 — Stanislav Malyshev — 2007-03-08T20:47:41+00:00

URL: https://externals.io/message/28292#28299 · In reply to: #28292

> 
> Let me know if I have any issues with my patch/thinking here:

Patch seems to be ok. I'll add it.

-- 
Stanislav Malyshev, Zend Products Engineer
stas@zend.com  http://www.zend.com/
