From 052a075f9dcb8172000f7e20e666fcac71102bc6 Mon Sep 17 00:00:00 2001 From: Marc Easen Date: Mon, 4 Jun 2012 19:32:30 +0100 Subject: [PATCH 1/4] Update the zend_fetch_dimension_address_read to support negative string offset and updated tests --- Zend/tests/str_offset_001.phpt | 16 ++++++++++++++-- Zend/zend_execute.c | 9 +++++++-- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/Zend/tests/str_offset_001.phpt b/Zend/tests/str_offset_001.phpt index 8a6b91b49ad9..33ccbe6a3d62 100644 --- a/Zend/tests/str_offset_001.phpt +++ b/Zend/tests/str_offset_001.phpt @@ -7,6 +7,9 @@ function foo($x) { } $str = "abc"; +var_dump($str[-4]); +var_dump($str[-3]); +var_dump($str[-2]); var_dump($str[-1]); var_dump($str[0]); var_dump($str[1]); @@ -15,6 +18,9 @@ var_dump($str[3]); var_dump($str[1][0]); var_dump($str[2][1]); +foo($str[-4]); +foo($str[-3]); +foo($str[-2]); foo($str[-1]); foo($str[0]); foo($str[1]); @@ -24,11 +30,14 @@ foo($str[1][0]); foo($str[2][1]); ?> --EXPECTF-- -Notice: Uninitialized string offset: -1 in %sstr_offset_001.php on line %d +Notice: Uninitialized string offset: -4 in %sstr_offset_001.php on line %d string(0) "" string(1) "a" string(1) "b" string(1) "c" +string(1) "a" +string(1) "b" +string(1) "c" Notice: Uninitialized string offset: 3 in %sstr_offset_001.php on line %d string(0) "" @@ -37,11 +46,14 @@ string(1) "b" Notice: Uninitialized string offset: 1 in %sstr_offset_001.php on line %d string(0) "" -Notice: Uninitialized string offset: -1 in %sstr_offset_001.php on line %d +Notice: Uninitialized string offset: -4 in %sstr_offset_001.php on line %d string(0) "" string(1) "a" string(1) "b" string(1) "c" +string(1) "a" +string(1) "b" +string(1) "c" Notice: Uninitialized string offset: 3 in %sstr_offset_001.php on line %d string(0) "" diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 205531fd28e5..5b40eb197ff2 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -1302,7 +1302,12 @@ static void zend_fetch_dimension_address_read(temp_variable *result, zval **cont INIT_PZVAL(ptr); Z_TYPE_P(ptr) = IS_STRING; - if (Z_LVAL_P(dim) < 0 || Z_STRLEN_P(container) <= Z_LVAL_P(dim)) { + long ldim = Z_LVAL_P(dim); + if (ldim < 0) { + ldim += Z_STRLEN_P(container); + } + + if (ldim < 0 || Z_STRLEN_P(container) <= ldim) { if (type != BP_VAR_IS) { zend_error(E_NOTICE, "Uninitialized string offset: %ld", Z_LVAL_P(dim)); } @@ -1310,7 +1315,7 @@ static void zend_fetch_dimension_address_read(temp_variable *result, zval **cont Z_STRLEN_P(ptr) = 0; } else { Z_STRVAL_P(ptr) = (char*)emalloc(2); - Z_STRVAL_P(ptr)[0] = Z_STRVAL_P(container)[Z_LVAL_P(dim)]; + Z_STRVAL_P(ptr)[0] = Z_STRVAL_P(container)[ldim]; Z_STRVAL_P(ptr)[1] = 0; Z_STRLEN_P(ptr) = 1; } From f5a0a21ab69e534e84c729471c2835a513df8ff6 Mon Sep 17 00:00:00 2001 From: Marc Easen Date: Mon, 11 Jun 2012 20:56:05 +0100 Subject: [PATCH 2/4] Moved the variable declaration to the top of the block --- Zend/zend_execute.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 5b40eb197ff2..9dd6b6df16a9 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -1268,6 +1268,7 @@ static void zend_fetch_dimension_address_read(temp_variable *result, zval **cont case IS_STRING: { zval tmp; zval *ptr; + long ldim; if (Z_TYPE_P(dim) != IS_LONG) { switch(Z_TYPE_P(dim)) { @@ -1302,7 +1303,7 @@ static void zend_fetch_dimension_address_read(temp_variable *result, zval **cont INIT_PZVAL(ptr); Z_TYPE_P(ptr) = IS_STRING; - long ldim = Z_LVAL_P(dim); + ldim = Z_LVAL_P(dim); if (ldim < 0) { ldim += Z_STRLEN_P(container); } From 2dd2eda21469f0baf746407ad833b0d7c5767556 Mon Sep 17 00:00:00 2001 From: Marc Easen Date: Sun, 17 Jun 2012 20:16:10 +0100 Subject: [PATCH 3/4] Added the unit test for negative string offset, setting a value --- Zend/tests/str_offset_003.phpt | 18 ++++++++++++++++++ tests/lang/bug22592.phpt | 2 -- 2 files changed, 18 insertions(+), 2 deletions(-) create mode 100644 Zend/tests/str_offset_003.phpt diff --git a/Zend/tests/str_offset_003.phpt b/Zend/tests/str_offset_003.phpt new file mode 100644 index 000000000000..5ecce6fca55c --- /dev/null +++ b/Zend/tests/str_offset_003.phpt @@ -0,0 +1,18 @@ +--TEST-- +string offset 003 +--FILE-- + +--EXPECTF-- +string(3) "aaa" +string(3) "aab" +string(3) "abb" +string(3) "bbb" \ No newline at end of file diff --git a/tests/lang/bug22592.phpt b/tests/lang/bug22592.phpt index 270584185f91..8fcfd4bc1691 100644 --- a/tests/lang/bug22592.phpt +++ b/tests/lang/bug22592.phpt @@ -32,7 +32,6 @@ var_dump($result); $e = $result[1] = $result[6]; var_dump($result); var_dump($a, $b, $c, $d, $e); -$result[-1] = 'a'; ?> --EXPECT-- string(5) "* *-*" @@ -50,4 +49,3 @@ string(1) "s" string(1) "4" string(1) "5" string(1) "5" -[Illegal string offset: -1] From 410f74971a548e9543f1c2b7364df1ce4e0a257c Mon Sep 17 00:00:00 2001 From: Marc Easen Date: Sun, 17 Jun 2012 20:21:29 +0100 Subject: [PATCH 4/4] Updated zend_assign_to_string_offset to support negative offset --- Zend/zend_execute.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 9dd6b6df16a9..3b7d2ddc6986 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -751,13 +751,12 @@ static inline void zend_assign_to_object(zval **retval, zval **object_ptr, zval FREE_OP_IF_VAR(free_value); } -static inline int zend_assign_to_string_offset(const temp_variable *T, const zval *value, int value_type TSRMLS_DC) +static inline int zend_assign_to_string_offset(temp_variable *T, const zval *value, int value_type TSRMLS_DC) { if (Z_TYPE_P(T->str_offset.str) == IS_STRING) { if (((int)T->str_offset.offset < 0)) { - zend_error(E_WARNING, "Illegal string offset: %d", T->str_offset.offset); - return 0; + T->str_offset.offset += Z_STRLEN_P(T->str_offset.str); } if (T->str_offset.offset >= Z_STRLEN_P(T->str_offset.str)) {