Browse Source

- Fixed bug #46701 (Creating associative array with long values in the key fails on 32bit linux)

Patch by Shire
experimental/first_unicode_implementation
Felipe Pena 18 years ago
parent
commit
4ed88343cc
  1. 42
      Zend/tests/bug46701.phpt
  2. 6
      Zend/zend_execute.c
  3. 36
      Zend/zend_operators.c
  4. 36
      Zend/zend_operators.h
  5. 4
      Zend/zend_vm_def.h
  6. 80
      Zend/zend_vm_execute.h

42
Zend/tests/bug46701.phpt

@ -0,0 +1,42 @@
--TEST--
Bug #46701 (Creating associative array with long values in the key fails on 32bit linux)
--SKIPIF--
<?php if (PHP_INT_MAX != 4) die('skip this test is for 32bit platforms only'); ?>
--FILE--
<?php
$test_array = array(
0xcc5c4600 => 1,
0xce331a00 => 2
);
$test_array[0xce359000] = 3;
var_dump($test_array);
var_dump($test_array[0xce331a00]);
class foo {
public $x;
public function __construct() {
$this->x[0xce359000] = 3;
var_dump($this->x);
}
}
new foo;
?>
--EXPECT--
array(3) {
[-866368000]=>
int(1)
[-835511808]=>
int(2)
[-835350528]=>
int(3)
}
int(2)
array(1) {
[-835350528]=>
int(3)
}

6
Zend/zend_execute.c

@ -938,10 +938,10 @@ fetch_string_dim:
efree(offset_key.v);
}
break;
case IS_DOUBLE:
index = (long)Z_DVAL_P(dim);
case IS_DOUBLE: {
DVAL_TO_LVAL(Z_DVAL_P(dim), index);
goto num_index;
}
case IS_RESOURCE:
zend_error(E_STRICT, "Resource ID#%ld used as offset, casting to integer (%ld)", Z_LVAL_P(dim), Z_LVAL_P(dim));
/* Fall Through */

36
Zend/zend_operators.c

@ -268,42 +268,6 @@ ZEND_API int convert_scalar_to_number(zval *op TSRMLS_DC) /* {{{ */
/* }}} */
/* {{{ DVAL_TO_LVAL */
#define MAX_UNSIGNED_INT ((double) LONG_MAX * 2) + 1
#ifdef _WIN64
# define DVAL_TO_LVAL(d, l) \
if ((d) > LONG_MAX) { \
(l) = (long)(unsigned long)(__int64) (d); \
} else { \
(l) = (long) (d); \
}
#elif !defined(_WIN64) && __WORDSIZE == 64
# define DVAL_TO_LVAL(d, l) \
if ((d) >= LONG_MAX) { \
(l) = LONG_MAX; \
} else if ((d) <= LONG_MIN) { \
(l) = LONG_MIN; \
} else {\
(l) = (long) (d); \
}
#else
# define DVAL_TO_LVAL(d, l) \
if ((d) > LONG_MAX) { \
if ((d) > MAX_UNSIGNED_INT) { \
(l) = LONG_MAX; \
} else { \
(l) = (unsigned long) (d); \
} \
} else { \
if((d) < LONG_MIN) { \
(l) = LONG_MIN; \
} else { \
(l) = (long) (d); \
} \
}
#endif
/* }}} */
/* {{{ zendi_convert_to_long */
#define zendi_convert_to_long(op, holder, result) \
if (op == result) { \

36
Zend/zend_operators.h

@ -78,6 +78,42 @@ ZEND_API unsigned long zend_u_strtoul(const UChar *nptr, UChar **endptr, int bas
ZEND_API double zend_u_strtod(const UChar *nptr, UChar **endptr);
END_EXTERN_C()
/* {{{ DVAL_TO_LVAL */
#define MAX_UNSIGNED_INT ((double) LONG_MAX * 2) + 1
#ifdef _WIN64
# define DVAL_TO_LVAL(d, l) \
if ((d) > LONG_MAX) { \
(l) = (long)(unsigned long)(__int64) (d); \
} else { \
(l) = (long) (d); \
}
#elif !defined(_WIN64) && __WORDSIZE == 64
# define DVAL_TO_LVAL(d, l) \
if ((d) >= LONG_MAX) { \
(l) = LONG_MAX; \
} else if ((d) <= LONG_MIN) { \
(l) = LONG_MIN; \
} else {\
(l) = (long) (d); \
}
#else
# define DVAL_TO_LVAL(d, l) \
if ((d) > LONG_MAX) { \
if ((d) > MAX_UNSIGNED_INT) { \
(l) = LONG_MAX; \
} else { \
(l) = (unsigned long) (d); \
} \
} else { \
if((d) < LONG_MIN) { \
(l) = LONG_MIN; \
} else { \
(l) = (long) (d); \
} \
}
#endif
/* }}} */
static inline zend_uchar is_numeric_string(char *str, int length, long *lval, double *dval, int allow_errors)
{
long local_lval;

4
Zend/zend_vm_def.h

@ -3150,9 +3150,11 @@ ZEND_VM_HANDLER(72, ZEND_ADD_ARRAY_ELEMENT, CONST|TMP|VAR|CV, CONST|TMP|VAR|UNUS
}
}
if (offset) {
long l;
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
zend_hash_index_update(Z_ARRVAL_P(array_ptr), (long) Z_DVAL_P(offset), &expr_ptr, sizeof(zval *), NULL);
DVAL_TO_LVAL(Z_DVAL_P(offset), l);
zend_hash_index_update(Z_ARRVAL_P(array_ptr), l, &expr_ptr, sizeof(zval *), NULL);
break;
case IS_LONG:
case IS_BOOL:

80
Zend/zend_vm_execute.h

@ -2920,9 +2920,11 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CONST_HANDLER(ZEND_O
}
}
if (offset) {
long l;
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
zend_hash_index_update(Z_ARRVAL_P(array_ptr), (long) Z_DVAL_P(offset), &expr_ptr, sizeof(zval *), NULL);
DVAL_TO_LVAL(Z_DVAL_P(offset), l);
zend_hash_index_update(Z_ARRVAL_P(array_ptr), l, &expr_ptr, sizeof(zval *), NULL);
break;
case IS_LONG:
case IS_BOOL:
@ -3453,9 +3455,11 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMP_HANDLER(ZEND_OPC
}
}
if (offset) {
long l;
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
zend_hash_index_update(Z_ARRVAL_P(array_ptr), (long) Z_DVAL_P(offset), &expr_ptr, sizeof(zval *), NULL);
DVAL_TO_LVAL(Z_DVAL_P(offset), l);
zend_hash_index_update(Z_ARRVAL_P(array_ptr), l, &expr_ptr, sizeof(zval *), NULL);
break;
case IS_LONG:
case IS_BOOL:
@ -3933,9 +3937,11 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_VAR_HANDLER(ZEND_OPC
}
}
if (offset) {
long l;
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
zend_hash_index_update(Z_ARRVAL_P(array_ptr), (long) Z_DVAL_P(offset), &expr_ptr, sizeof(zval *), NULL);
DVAL_TO_LVAL(Z_DVAL_P(offset), l);
zend_hash_index_update(Z_ARRVAL_P(array_ptr), l, &expr_ptr, sizeof(zval *), NULL);
break;
case IS_LONG:
case IS_BOOL:
@ -4137,9 +4143,11 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_UNUSED_HANDLER(ZEND_
}
}
if (offset) {
long l;
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
zend_hash_index_update(Z_ARRVAL_P(array_ptr), (long) Z_DVAL_P(offset), &expr_ptr, sizeof(zval *), NULL);
DVAL_TO_LVAL(Z_DVAL_P(offset), l);
zend_hash_index_update(Z_ARRVAL_P(array_ptr), l, &expr_ptr, sizeof(zval *), NULL);
break;
case IS_LONG:
case IS_BOOL:
@ -4616,9 +4624,11 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CV_HANDLER(ZEND_OPCO
}
}
if (offset) {
long l;
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
zend_hash_index_update(Z_ARRVAL_P(array_ptr), (long) Z_DVAL_P(offset), &expr_ptr, sizeof(zval *), NULL);
DVAL_TO_LVAL(Z_DVAL_P(offset), l);
zend_hash_index_update(Z_ARRVAL_P(array_ptr), l, &expr_ptr, sizeof(zval *), NULL);
break;
case IS_LONG:
case IS_BOOL:
@ -6285,9 +6295,11 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CONST_HANDLER(ZEND_OPC
}
}
if (offset) {
long l;
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
zend_hash_index_update(Z_ARRVAL_P(array_ptr), (long) Z_DVAL_P(offset), &expr_ptr, sizeof(zval *), NULL);
DVAL_TO_LVAL(Z_DVAL_P(offset), l);
zend_hash_index_update(Z_ARRVAL_P(array_ptr), l, &expr_ptr, sizeof(zval *), NULL);
break;
case IS_LONG:
case IS_BOOL:
@ -6758,9 +6770,11 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMP_HANDLER(ZEND_OPCOD
}
}
if (offset) {
long l;
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
zend_hash_index_update(Z_ARRVAL_P(array_ptr), (long) Z_DVAL_P(offset), &expr_ptr, sizeof(zval *), NULL);
DVAL_TO_LVAL(Z_DVAL_P(offset), l);
zend_hash_index_update(Z_ARRVAL_P(array_ptr), l, &expr_ptr, sizeof(zval *), NULL);
break;
case IS_LONG:
case IS_BOOL:
@ -7231,9 +7245,11 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_VAR_HANDLER(ZEND_OPCOD
}
}
if (offset) {
long l;
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
zend_hash_index_update(Z_ARRVAL_P(array_ptr), (long) Z_DVAL_P(offset), &expr_ptr, sizeof(zval *), NULL);
DVAL_TO_LVAL(Z_DVAL_P(offset), l);
zend_hash_index_update(Z_ARRVAL_P(array_ptr), l, &expr_ptr, sizeof(zval *), NULL);
break;
case IS_LONG:
case IS_BOOL:
@ -7325,9 +7341,11 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_UNUSED_HANDLER(ZEND_OP
}
}
if (offset) {
long l;
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
zend_hash_index_update(Z_ARRVAL_P(array_ptr), (long) Z_DVAL_P(offset), &expr_ptr, sizeof(zval *), NULL);
DVAL_TO_LVAL(Z_DVAL_P(offset), l);
zend_hash_index_update(Z_ARRVAL_P(array_ptr), l, &expr_ptr, sizeof(zval *), NULL);
break;
case IS_LONG:
case IS_BOOL:
@ -7795,9 +7813,11 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CV_HANDLER(ZEND_OPCODE
}
}
if (offset) {
long l;
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
zend_hash_index_update(Z_ARRVAL_P(array_ptr), (long) Z_DVAL_P(offset), &expr_ptr, sizeof(zval *), NULL);
DVAL_TO_LVAL(Z_DVAL_P(offset), l);
zend_hash_index_update(Z_ARRVAL_P(array_ptr), l, &expr_ptr, sizeof(zval *), NULL);
break;
case IS_LONG:
case IS_BOOL:
@ -10981,9 +11001,11 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CONST_HANDLER(ZEND_OPC
}
}
if (offset) {
long l;
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
zend_hash_index_update(Z_ARRVAL_P(array_ptr), (long) Z_DVAL_P(offset), &expr_ptr, sizeof(zval *), NULL);
DVAL_TO_LVAL(Z_DVAL_P(offset), l);
zend_hash_index_update(Z_ARRVAL_P(array_ptr), l, &expr_ptr, sizeof(zval *), NULL);
break;
case IS_LONG:
case IS_BOOL:
@ -12825,9 +12847,11 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMP_HANDLER(ZEND_OPCOD
}
}
if (offset) {
long l;
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
zend_hash_index_update(Z_ARRVAL_P(array_ptr), (long) Z_DVAL_P(offset), &expr_ptr, sizeof(zval *), NULL);
DVAL_TO_LVAL(Z_DVAL_P(offset), l);
zend_hash_index_update(Z_ARRVAL_P(array_ptr), l, &expr_ptr, sizeof(zval *), NULL);
break;
case IS_LONG:
case IS_BOOL:
@ -14720,9 +14744,11 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_VAR_HANDLER(ZEND_OPCOD
}
}
if (offset) {
long l;
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
zend_hash_index_update(Z_ARRVAL_P(array_ptr), (long) Z_DVAL_P(offset), &expr_ptr, sizeof(zval *), NULL);
DVAL_TO_LVAL(Z_DVAL_P(offset), l);
zend_hash_index_update(Z_ARRVAL_P(array_ptr), l, &expr_ptr, sizeof(zval *), NULL);
break;
case IS_LONG:
case IS_BOOL:
@ -15671,9 +15697,11 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_UNUSED_HANDLER(ZEND_OP
}
}
if (offset) {
long l;
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
zend_hash_index_update(Z_ARRVAL_P(array_ptr), (long) Z_DVAL_P(offset), &expr_ptr, sizeof(zval *), NULL);
DVAL_TO_LVAL(Z_DVAL_P(offset), l);
zend_hash_index_update(Z_ARRVAL_P(array_ptr), l, &expr_ptr, sizeof(zval *), NULL);
break;
case IS_LONG:
case IS_BOOL:
@ -17231,9 +17259,11 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CV_HANDLER(ZEND_OPCODE
}
}
if (offset) {
long l;
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
zend_hash_index_update(Z_ARRVAL_P(array_ptr), (long) Z_DVAL_P(offset), &expr_ptr, sizeof(zval *), NULL);
DVAL_TO_LVAL(Z_DVAL_P(offset), l);
zend_hash_index_update(Z_ARRVAL_P(array_ptr), l, &expr_ptr, sizeof(zval *), NULL);
break;
case IS_LONG:
case IS_BOOL:
@ -25320,9 +25350,11 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CONST_HANDLER(ZEND_OPCO
}
}
if (offset) {
long l;
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
zend_hash_index_update(Z_ARRVAL_P(array_ptr), (long) Z_DVAL_P(offset), &expr_ptr, sizeof(zval *), NULL);
DVAL_TO_LVAL(Z_DVAL_P(offset), l);
zend_hash_index_update(Z_ARRVAL_P(array_ptr), l, &expr_ptr, sizeof(zval *), NULL);
break;
case IS_LONG:
case IS_BOOL:
@ -27042,9 +27074,11 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMP_HANDLER(ZEND_OPCODE
}
}
if (offset) {
long l;
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
zend_hash_index_update(Z_ARRVAL_P(array_ptr), (long) Z_DVAL_P(offset), &expr_ptr, sizeof(zval *), NULL);
DVAL_TO_LVAL(Z_DVAL_P(offset), l);
zend_hash_index_update(Z_ARRVAL_P(array_ptr), l, &expr_ptr, sizeof(zval *), NULL);
break;
case IS_LONG:
case IS_BOOL:
@ -28814,9 +28848,11 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_VAR_HANDLER(ZEND_OPCODE
}
}
if (offset) {
long l;
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
zend_hash_index_update(Z_ARRVAL_P(array_ptr), (long) Z_DVAL_P(offset), &expr_ptr, sizeof(zval *), NULL);
DVAL_TO_LVAL(Z_DVAL_P(offset), l);
zend_hash_index_update(Z_ARRVAL_P(array_ptr), l, &expr_ptr, sizeof(zval *), NULL);
break;
case IS_LONG:
case IS_BOOL:
@ -29649,9 +29685,11 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_UNUSED_HANDLER(ZEND_OPC
}
}
if (offset) {
long l;
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
zend_hash_index_update(Z_ARRVAL_P(array_ptr), (long) Z_DVAL_P(offset), &expr_ptr, sizeof(zval *), NULL);
DVAL_TO_LVAL(Z_DVAL_P(offset), l);
zend_hash_index_update(Z_ARRVAL_P(array_ptr), l, &expr_ptr, sizeof(zval *), NULL);
break;
case IS_LONG:
case IS_BOOL:
@ -31090,9 +31128,11 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CV_HANDLER(ZEND_OPCODE_
}
}
if (offset) {
long l;
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
zend_hash_index_update(Z_ARRVAL_P(array_ptr), (long) Z_DVAL_P(offset), &expr_ptr, sizeof(zval *), NULL);
DVAL_TO_LVAL(Z_DVAL_P(offset), l);
zend_hash_index_update(Z_ARRVAL_P(array_ptr), l, &expr_ptr, sizeof(zval *), NULL);
break;
case IS_LONG:
case IS_BOOL:

Loading…
Cancel
Save