Skip to content

Commit

Permalink
Allow negative string offsets.
Browse files Browse the repository at this point in the history
Negative offsets return characters starting from the end of the string.
  • Loading branch information
lt committed Apr 17, 2014
1 parent a381cc3 commit 8bfd09b
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 2 deletions.
9 changes: 7 additions & 2 deletions Zend/zend_execute.c
Original file line number Diff line number Diff line change
Expand Up @@ -1300,15 +1300,20 @@ static void zend_fetch_dimension_address_read(temp_variable *result, zval *conta
INIT_PZVAL(ptr);
Z_TYPE_P(ptr) = IS_STRING;

if (Z_LVAL_P(dim) < 0 || Z_STRLEN_P(container) <= Z_LVAL_P(dim)) {
if (Z_STRLEN_P(container) <= Z_LVAL_P(dim) || (Z_LVAL_P(dim) < 0 && Z_LVAL_P(dim) < -Z_STRLEN_P(container))) {
if (type != BP_VAR_IS) {
zend_error(E_NOTICE, "Uninitialized string offset: %ld", Z_LVAL_P(dim));
}
Z_STRVAL_P(ptr) = STR_EMPTY_ALLOC();
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)];
if (Z_LVAL_P(dim) < 0) {
Z_STRVAL_P(ptr)[0] = Z_STRVAL_P(container)[Z_STRLEN_P(container) + Z_LVAL_P(dim)];
}
else {
Z_STRVAL_P(ptr)[0] = Z_STRVAL_P(container)[Z_LVAL_P(dim)];
}
Z_STRVAL_P(ptr)[1] = 0;
Z_STRLEN_P(ptr) = 1;
}
Expand Down
11 changes: 11 additions & 0 deletions tests/strings/offsets_general.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ var_dump(isset($string{0}));
var_dump(isset($string{0}{0}));
var_dump($string{"foo"});
var_dump(isset($string{"foo"}{"bar"}));
var_dump($string[6]);
var_dump($string[-1]);
var_dump($string[-6]);
var_dump($string[-7]);
?>
--EXPECTF--
string(1) "f"
Expand All @@ -36,3 +40,10 @@ Warning: Illegal string offset 'foo' in %s line %d
string(1) "f"
bool(false)

Notice: Uninitialized string offset: %d in %s line %d
string(0) ""
string(1) "r"
string(1) "f"

Notice: Uninitialized string offset: -%d in %s line %d
string(0) ""

0 comments on commit 8bfd09b

Please sign in to comment.