summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZeev Suraski <zeev@php.net>2001-06-27 15:40:49 +0000
committerZeev Suraski <zeev@php.net>2001-06-27 15:40:49 +0000
commitee115c8ecce2b7f58c7a218dceb76c8f3c0f19f4 (patch)
treec913ef638ab651a025ab534ab92aeae25e2d0819
parent44e75b6cddd9969d6cd6b188027806df57287b55 (diff)
downloadphp-git-ee115c8ecce2b7f58c7a218dceb76c8f3c0f19f4.tar.gz
- Warn about illegal offsets
- Allow assignments to uninitialized string offsets (automatically pads the string with spaces)
-rw-r--r--Zend/zend_execute.c35
1 files changed, 28 insertions, 7 deletions
diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c
index 0ea12af77e..667a6d1689 100644
--- a/Zend/zend_execute.c
+++ b/Zend/zend_execute.c
@@ -100,6 +100,7 @@ static inline zval *_get_zval_ptr(znode *node, temp_variable *Ts, int *should_fr
if (T->EA.data.str_offset.str->type != IS_STRING
|| (T->EA.data.str_offset.offset<0)
|| (T->EA.data.str_offset.str->value.str.len <= T->EA.data.str_offset.offset)) {
+ zend_error(E_NOTICE, "Uninitialized string offset: %d", T->EA.data.str_offset.offset);
T->tmp_var.value.str.val = empty_string;
T->tmp_var.value.str.len = 0;
} else {
@@ -315,12 +316,29 @@ static inline void zend_assign_to_variable(znode *result, znode *op1, znode *op2
case IS_STRING_OFFSET: {
temp_variable *T = &Ts[op1->u.var];
- if (T->EA.data.str_offset.str->type == IS_STRING
- && (T->EA.data.str_offset.offset >= 0)
- && (T->EA.data.str_offset.offset < T->EA.data.str_offset.str->value.str.len)) {
+ if (T->EA.data.str_offset.str->type == IS_STRING) do {
zval tmp;
zval *final_value = value;
+ if ((T->EA.data.str_offset.offset < 0)) {
+ zend_error(E_WARNING, "Illegal string offset: %d", T->EA.data.str_offset.offset);
+ break;
+ }
+ if (T->EA.data.str_offset.offset >= T->EA.data.str_offset.str->value.str.len) {
+ int i;
+
+ if (T->EA.data.str_offset.str->value.str.len==0) {
+ T->EA.data.str_offset.str->value.str.val = (char *) emalloc(T->EA.data.str_offset.offset+1+1);
+ } else {
+ T->EA.data.str_offset.str->value.str.val = (char *) erealloc(T->EA.data.str_offset.str->value.str.val, T->EA.data.str_offset.offset+1+1);
+ }
+ for (i=T->EA.data.str_offset.str->value.str.len; i<T->EA.data.str_offset.offset; i++) {
+ T->EA.data.str_offset.str->value.str.val[i] = ' ';
+ }
+ T->EA.data.str_offset.str->value.str.val[T->EA.data.str_offset.offset+1] = 0;
+ T->EA.data.str_offset.str->value.str.len = T->EA.data.str_offset.offset+1;
+ }
+
if (value->type!=IS_STRING) {
tmp = *value;
if (op2 && op2->op_type == IS_VAR) {
@@ -343,7 +361,7 @@ static inline void zend_assign_to_variable(znode *result, znode *op1, znode *op2
* the value of an assignment to a string offset is undefined
Ts[result->u.var].var = &T->EA.data.str_offset.str;
*/
- }
+ } while(0);
/* zval_ptr_dtor(&T->EA.data.str_offset.str); Nuke this line if it doesn't cause a leak */
T->tmp_var.type = IS_STRING;
}
@@ -1067,9 +1085,12 @@ ZEND_API void execute(zend_op_array *op_array ELS_DC)
EG(binary_op) = boolean_xor_function;
/* Fall through */
binary_op_addr:
- EG(binary_op)(&Ts[opline->result.u.var].tmp_var,
- get_zval_ptr(&opline->op1, Ts, &EG(free_op1), BP_VAR_R),
- get_zval_ptr(&opline->op2, Ts, &EG(free_op2), BP_VAR_R) );
+ {
+ zval *zp1 = get_zval_ptr(&opline->op1, Ts, &EG(free_op1), BP_VAR_R);
+ zval *zp2 = get_zval_ptr(&opline->op2, Ts, &EG(free_op1), BP_VAR_R);
+
+ EG(binary_op)(&Ts[opline->result.u.var].tmp_var, zp1, zp2);
+ }
FREE_OP(&opline->op1, EG(free_op1));
FREE_OP(&opline->op2, EG(free_op2));
NEXT_OPCODE();