1
0
mirror of https://github.com/php/php-src.git synced 2026-04-05 07:02:33 +02:00

Merge branch 'PHP-5.5'

Conflicts:
	UPGRADING
	UPGRADING.INTERNALS
This commit is contained in:
Nikita Popov
2013-03-12 17:29:54 +01:00
35 changed files with 369 additions and 501 deletions

View File

@@ -0,0 +1,52 @@
--TEST--
Generators can return non-scalar keys
--FILE--
<?php
function gen() {
yield [1, 2, 3] => [4, 5, 6];
yield (object) ['a' => 'b'] => (object) ['b' => 'a'];
yield 3.14 => 2.73;
yield false => true;
yield true => false;
yield null => null;
}
foreach (gen() as $k => $v) {
var_dump($k, $v);
}
?>
--EXPECT--
array(3) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
}
array(3) {
[0]=>
int(4)
[1]=>
int(5)
[2]=>
int(6)
}
object(stdClass)#3 (1) {
["a"]=>
string(1) "b"
}
object(stdClass)#4 (1) {
["b"]=>
string(1) "a"
}
float(3.14)
float(2.73)
bool(false)
bool(true)
bool(true)
bool(false)
NULL
NULL

View File

@@ -299,7 +299,6 @@ void zend_error_noreturn(int type, const char *format, ...) __attribute__ ((nore
/*
* zval
*/
typedef struct _zval_struct zval;
typedef struct _zend_class_entry zend_class_entry;
typedef struct _zend_guard {

View File

@@ -1502,6 +1502,40 @@ ZEND_API int add_get_index_stringl(zval *arg, ulong index, const char *str, uint
}
/* }}} */
ZEND_API int array_set_zval_key(HashTable *ht, zval *key, zval *value) /* {{{ */
{
int result;
switch (Z_TYPE_P(key)) {
case IS_STRING:
result = zend_symtable_update(ht, Z_STRVAL_P(key), Z_STRLEN_P(key) + 1, &value, sizeof(zval *), NULL);
break;
case IS_NULL:
result = zend_symtable_update(ht, "", 1, &value, sizeof(zval *), NULL);
break;
case IS_RESOURCE:
zend_error(E_STRICT, "Resource ID#%ld used as offset, casting to integer (%ld)", Z_LVAL_P(key), Z_LVAL_P(key));
/* break missing intentionally */
case IS_BOOL:
case IS_LONG:
result = zend_hash_index_update(ht, Z_LVAL_P(key), &value, sizeof(zval *), NULL);
break;
case IS_DOUBLE:
result = zend_hash_index_update(ht, zend_dval_to_lval(Z_LVAL_P(key)), &value, sizeof(zval *), NULL);
break;
default:
zend_error(E_WARNING, "Illegal offset type");
result = FAILURE;
}
if (result == SUCCESS) {
Z_ADDREF_P(value);
}
return result;
}
/* }}} */
ZEND_API int add_property_long_ex(zval *arg, const char *key, uint key_len, long n TSRMLS_DC) /* {{{ */
{
zval *tmp;

View File

@@ -426,6 +426,8 @@ ZEND_API int add_get_index_double(zval *arg, ulong idx, double d, void **dest);
ZEND_API int add_get_index_string(zval *arg, ulong idx, const char *str, void **dest, int duplicate);
ZEND_API int add_get_index_stringl(zval *arg, ulong idx, const char *str, uint length, void **dest, int duplicate);
ZEND_API int array_set_zval_key(HashTable *ht, zval *key, zval *value);
ZEND_API int add_property_long_ex(zval *arg, const char *key, uint key_len, long l TSRMLS_DC);
ZEND_API int add_property_null_ex(zval *arg, const char *key, uint key_len TSRMLS_DC);
ZEND_API int add_property_bool_ex(zval *arg, const char *key, uint key_len, int b TSRMLS_DC);

View File

@@ -755,31 +755,17 @@ static void zend_generator_iterator_get_data(zend_object_iterator *iterator, zva
}
/* }}} */
static int zend_generator_iterator_get_key(zend_object_iterator *iterator, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC) /* {{{ */
static void zend_generator_iterator_get_key(zend_object_iterator *iterator, zval *key TSRMLS_DC) /* {{{ */
{
zend_generator *generator = (zend_generator *) iterator->data;
zend_generator_ensure_initialized(generator TSRMLS_CC);
if (!generator->key) {
return HASH_KEY_NON_EXISTANT;
if (generator->key) {
ZVAL_ZVAL(key, generator->key, 1, 0);
} else {
ZVAL_NULL(key);
}
if (Z_TYPE_P(generator->key) == IS_LONG) {
*int_key = Z_LVAL_P(generator->key);
return HASH_KEY_IS_LONG;
}
if (Z_TYPE_P(generator->key) == IS_STRING) {
*str_key = estrndup(Z_STRVAL_P(generator->key), Z_STRLEN_P(generator->key));
*str_key_len = Z_STRLEN_P(generator->key) + 1;
return HASH_KEY_IS_STRING;
}
/* Waiting for Etienne's patch to allow arbitrary zval keys. Until then
* error out on non-int and non-string keys. */
zend_error_noreturn(E_ERROR, "Currently only int and string keys can be yielded");
return HASH_KEY_NON_EXISTANT; /* Nerver reached */
}
/* }}} */

View File

@@ -1171,6 +1171,24 @@ ZEND_API int zend_hash_get_current_key_ex(const HashTable *ht, char **str_index,
return HASH_KEY_NON_EXISTANT;
}
ZEND_API void zend_hash_get_current_key_zval_ex(const HashTable *ht, zval *key, HashPosition *pos) {
Bucket *p;
IS_CONSISTENT(ht);
p = pos ? (*pos) : ht->pInternalPointer;
if (!p) {
Z_TYPE_P(key) = IS_NULL;
} else if (p->nKeyLength) {
Z_TYPE_P(key) = IS_STRING;
Z_STRVAL_P(key) = IS_INTERNED(p->arKey) ? (char *) p->arKey : estrndup(p->arKey, p->nKeyLength - 1);
Z_STRLEN_P(key) = p->nKeyLength - 1;
} else {
Z_TYPE_P(key) = IS_LONG;
Z_LVAL_P(key) = p->h;
}
}
ZEND_API int zend_hash_get_current_key_type_ex(HashTable *ht, HashPosition *pos)
{

View File

@@ -170,13 +170,13 @@ ZEND_API int zend_hash_quick_exists(const HashTable *ht, const char *arKey, uint
ZEND_API int zend_hash_index_exists(const HashTable *ht, ulong h);
ZEND_API ulong zend_hash_next_free_element(const HashTable *ht);
/* traversing */
#define zend_hash_has_more_elements_ex(ht, pos) \
(zend_hash_get_current_key_type_ex(ht, pos) == HASH_KEY_NON_EXISTANT ? FAILURE : SUCCESS)
ZEND_API int zend_hash_move_forward_ex(HashTable *ht, HashPosition *pos);
ZEND_API int zend_hash_move_backwards_ex(HashTable *ht, HashPosition *pos);
ZEND_API int zend_hash_get_current_key_ex(const HashTable *ht, char **str_index, uint *str_length, ulong *num_index, zend_bool duplicate, HashPosition *pos);
ZEND_API void zend_hash_get_current_key_zval_ex(const HashTable *ht, zval *key, HashPosition *pos);
ZEND_API int zend_hash_get_current_key_type_ex(HashTable *ht, HashPosition *pos);
ZEND_API int zend_hash_get_current_data_ex(HashTable *ht, void **pData, HashPosition *pos);
ZEND_API void zend_hash_internal_pointer_reset_ex(HashTable *ht, HashPosition *pos);
@@ -199,6 +199,8 @@ ZEND_API int zend_hash_set_pointer(HashTable *ht, const HashPointer *ptr);
zend_hash_move_backwards_ex(ht, NULL)
#define zend_hash_get_current_key(ht, str_index, num_index, duplicate) \
zend_hash_get_current_key_ex(ht, str_index, NULL, num_index, duplicate, NULL)
#define zend_hash_get_current_key_zval(ht, key) \
zend_hash_get_current_key_zval_ex(ht, key, NULL)
#define zend_hash_get_current_key_type(ht) \
zend_hash_get_current_key_type_ex(ht, NULL)
#define zend_hash_get_current_data(ht, pData) \

View File

@@ -195,7 +195,7 @@ static int zend_user_it_get_current_key_default(zend_object_iterator *_iter, cha
/* }}} */
/* {{{ zend_user_it_get_current_key */
ZEND_API int zend_user_it_get_current_key(zend_object_iterator *_iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC)
ZEND_API void zend_user_it_get_current_key(zend_object_iterator *_iter, zval *key TSRMLS_DC)
{
zend_user_iterator *iter = (zend_user_iterator*)_iter;
zval *object = (zval*)iter->it.data;
@@ -203,42 +203,16 @@ ZEND_API int zend_user_it_get_current_key(zend_object_iterator *_iter, char **st
zend_call_method_with_0_params(&object, iter->ce, &iter->ce->iterator_funcs.zf_key, "key", &retval);
if (!retval) {
*int_key = 0;
if (!EG(exception))
{
if (retval) {
ZVAL_ZVAL(key, retval, 1, 1);
} else {
if (!EG(exception)) {
zend_error(E_WARNING, "Nothing returned from %s::key()", iter->ce->name);
}
return HASH_KEY_IS_LONG;
}
switch (Z_TYPE_P(retval)) {
default:
zend_error(E_WARNING, "Illegal type returned from %s::key()", iter->ce->name);
case IS_NULL:
*int_key = 0;
zval_ptr_dtor(&retval);
return HASH_KEY_IS_LONG;
case IS_STRING:
*str_key = estrndup(Z_STRVAL_P(retval), Z_STRLEN_P(retval));
*str_key_len = Z_STRLEN_P(retval)+1;
zval_ptr_dtor(&retval);
return HASH_KEY_IS_STRING;
case IS_DOUBLE:
*int_key = (long)Z_DVAL_P(retval);
zval_ptr_dtor(&retval);
return HASH_KEY_IS_LONG;
case IS_RESOURCE:
case IS_BOOL:
case IS_LONG:
*int_key = (long)Z_LVAL_P(retval);
zval_ptr_dtor(&retval);
return HASH_KEY_IS_LONG;
ZVAL_LONG(key, 0);
}
}
/* }}} */
/* {{{ zend_user_it_move_forward */
ZEND_API void zend_user_it_move_forward(zend_object_iterator *_iter TSRMLS_DC)

View File

@@ -51,7 +51,7 @@ ZEND_API zval* zend_call_method(zval **object_pp, zend_class_entry *obj_ce, zend
ZEND_API void zend_user_it_rewind(zend_object_iterator *_iter TSRMLS_DC);
ZEND_API int zend_user_it_valid(zend_object_iterator *_iter TSRMLS_DC);
ZEND_API int zend_user_it_get_current_key(zend_object_iterator *_iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC);
ZEND_API void zend_user_it_get_current_key(zend_object_iterator *_iter, zval *key TSRMLS_DC);
ZEND_API void zend_user_it_get_current_data(zend_object_iterator *_iter, zval ***data TSRMLS_DC);
ZEND_API void zend_user_it_move_forward(zend_object_iterator *_iter TSRMLS_DC);
ZEND_API void zend_user_it_invalidate_current(zend_object_iterator *_iter TSRMLS_DC);

View File

@@ -38,8 +38,11 @@ typedef struct _zend_object_iterator_funcs {
/* fetch the item data for the current element */
void (*get_current_data)(zend_object_iterator *iter, zval ***data TSRMLS_DC);
/* fetch the key for the current element (return HASH_KEY_IS_STRING or HASH_KEY_IS_LONG) (optional, may be NULL) */
int (*get_current_key)(zend_object_iterator *iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC);
/* fetch the key for the current element (optional, may be NULL). The key
* should be written into the provided zval* using the ZVAL_* macros. If
* this handler is not provided auto-incrementing integer keys will be
* used. */
void (*get_current_key)(zend_object_iterator *iter, zval *key TSRMLS_DC);
/* step forwards to next element */
void (*move_forward)(zend_object_iterator *iter TSRMLS_DC);

View File

@@ -52,6 +52,7 @@ typedef unsigned long zend_uintptr_t;
typedef unsigned int zend_object_handle;
typedef struct _zend_object_handlers zend_object_handlers;
typedef struct _zval_struct zval;
typedef struct _zend_object_value {
zend_object_handle handle;

View File

@@ -4249,13 +4249,13 @@ ZEND_VM_HANDLER(78, ZEND_FE_FETCH, VAR, ANY)
zend_free_op free_op1;
zval *array = EX_T(opline->op1.var).fe.ptr;
zval **value;
char *str_key;
uint str_key_len;
ulong int_key;
HashTable *fe_ht;
zend_object_iterator *iter = NULL;
int key_type = 0;
zend_bool use_key = (zend_bool)(opline->extended_value & ZEND_FE_FETCH_WITH_KEY);
zval *key = NULL;
if (opline->extended_value & ZEND_FE_FETCH_WITH_KEY) {
key = &EX_T((opline+1)->result.var).tmp_var;
}
SAVE_OPLINE();
@@ -4266,8 +4266,11 @@ ZEND_VM_HANDLER(78, ZEND_FE_FETCH, VAR, ANY)
ZEND_VM_JMP(EX(op_array)->opcodes+opline->op2.opline_num);
case ZEND_ITER_PLAIN_OBJECT: {
const char *class_name, *prop_name;
zend_object *zobj = zend_objects_get_address(array TSRMLS_CC);
int key_type;
char *str_key;
zend_uint str_key_len;
zend_ulong int_key;
fe_ht = Z_OBJPROP_P(array);
zend_hash_set_pointer(fe_ht, &EX_T(opline->op1.var).fe.fe_pos);
@@ -4279,15 +4282,23 @@ ZEND_VM_HANDLER(78, ZEND_FE_FETCH, VAR, ANY)
key_type = zend_hash_get_current_key_ex(fe_ht, &str_key, &str_key_len, &int_key, 0, NULL);
zend_hash_move_forward(fe_ht);
} while (key_type == HASH_KEY_NON_EXISTANT ||
(key_type != HASH_KEY_IS_LONG &&
zend_check_property_access(zobj, str_key, str_key_len-1 TSRMLS_CC) != SUCCESS));
zend_hash_get_pointer(fe_ht, &EX_T(opline->op1.var).fe.fe_pos);
if (use_key && key_type != HASH_KEY_IS_LONG) {
zend_unmangle_property_name_ex(str_key, str_key_len-1, &class_name, &prop_name, &str_key_len);
str_key = estrndup(prop_name, str_key_len);
str_key_len++;
} while (key_type != HASH_KEY_IS_LONG &&
zend_check_property_access(zobj, str_key, str_key_len - 1 TSRMLS_CC) != SUCCESS);
if (key) {
if (key_type == HASH_KEY_IS_LONG) {
ZVAL_LONG(key, int_key);
} else {
const char *class_name, *prop_name;
int prop_name_len;
zend_unmangle_property_name_ex(
str_key, str_key_len - 1, &class_name, &prop_name, &prop_name_len
);
ZVAL_STRINGL(key, prop_name, prop_name_len, 1);
}
}
zend_hash_get_pointer(fe_ht, &EX_T(opline->op1.var).fe.fe_pos);
break;
}
@@ -4298,8 +4309,8 @@ ZEND_VM_HANDLER(78, ZEND_FE_FETCH, VAR, ANY)
/* reached end of iteration */
ZEND_VM_JMP(EX(op_array)->opcodes+opline->op2.opline_num);
}
if (use_key) {
key_type = zend_hash_get_current_key_ex(fe_ht, &str_key, &str_key_len, &int_key, 1, NULL);
if (key) {
zend_hash_get_current_key_zval(fe_ht, key);
}
zend_hash_move_forward(fe_ht);
zend_hash_get_pointer(fe_ht, &EX_T(opline->op1.var).fe.fe_pos);
@@ -4334,16 +4345,15 @@ ZEND_VM_HANDLER(78, ZEND_FE_FETCH, VAR, ANY)
/* failure in get_current_data */
ZEND_VM_JMP(EX(op_array)->opcodes+opline->op2.opline_num);
}
if (use_key) {
if (key) {
if (iter->funcs->get_current_key) {
key_type = iter->funcs->get_current_key(iter, &str_key, &str_key_len, &int_key TSRMLS_CC);
iter->funcs->get_current_key(iter, key TSRMLS_CC);
if (UNEXPECTED(EG(exception) != NULL)) {
zval_ptr_dtor(&array);
HANDLE_EXCEPTION();
}
} else {
key_type = HASH_KEY_IS_LONG;
int_key = iter->index;
ZVAL_LONG(key, iter->index);
}
}
break;
@@ -4359,26 +4369,6 @@ ZEND_VM_HANDLER(78, ZEND_FE_FETCH, VAR, ANY)
AI_SET_PTR(&EX_T(opline->result.var), *value);
}
if (use_key) {
zval *key = &EX_T((opline+1)->result.var).tmp_var;
switch (key_type) {
case HASH_KEY_IS_STRING:
Z_STRVAL_P(key) = (char*)str_key;
Z_STRLEN_P(key) = str_key_len-1;
Z_TYPE_P(key) = IS_STRING;
break;
case HASH_KEY_IS_LONG:
Z_LVAL_P(key) = int_key;
Z_TYPE_P(key) = IS_LONG;
break;
default:
case HASH_KEY_NON_EXISTANT:
ZVAL_NULL(key);
break;
}
}
CHECK_EXCEPTION();
ZEND_VM_INC_OPCODE();
ZEND_VM_NEXT_OPCODE();

View File

@@ -13592,13 +13592,13 @@ static int ZEND_FASTCALL ZEND_FE_FETCH_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
zval *array = EX_T(opline->op1.var).fe.ptr;
zval **value;
char *str_key;
uint str_key_len;
ulong int_key;
HashTable *fe_ht;
zend_object_iterator *iter = NULL;
int key_type = 0;
zend_bool use_key = (zend_bool)(opline->extended_value & ZEND_FE_FETCH_WITH_KEY);
zval *key = NULL;
if (opline->extended_value & ZEND_FE_FETCH_WITH_KEY) {
key = &EX_T((opline+1)->result.var).tmp_var;
}
SAVE_OPLINE();
@@ -13609,8 +13609,11 @@ static int ZEND_FASTCALL ZEND_FE_FETCH_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
ZEND_VM_JMP(EX(op_array)->opcodes+opline->op2.opline_num);
case ZEND_ITER_PLAIN_OBJECT: {
const char *class_name, *prop_name;
zend_object *zobj = zend_objects_get_address(array TSRMLS_CC);
int key_type;
char *str_key;
zend_uint str_key_len;
zend_ulong int_key;
fe_ht = Z_OBJPROP_P(array);
zend_hash_set_pointer(fe_ht, &EX_T(opline->op1.var).fe.fe_pos);
@@ -13622,15 +13625,23 @@ static int ZEND_FASTCALL ZEND_FE_FETCH_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
key_type = zend_hash_get_current_key_ex(fe_ht, &str_key, &str_key_len, &int_key, 0, NULL);
zend_hash_move_forward(fe_ht);
} while (key_type == HASH_KEY_NON_EXISTANT ||
(key_type != HASH_KEY_IS_LONG &&
zend_check_property_access(zobj, str_key, str_key_len-1 TSRMLS_CC) != SUCCESS));
zend_hash_get_pointer(fe_ht, &EX_T(opline->op1.var).fe.fe_pos);
if (use_key && key_type != HASH_KEY_IS_LONG) {
zend_unmangle_property_name_ex(str_key, str_key_len-1, &class_name, &prop_name, &str_key_len);
str_key = estrndup(prop_name, str_key_len);
str_key_len++;
} while (key_type != HASH_KEY_IS_LONG &&
zend_check_property_access(zobj, str_key, str_key_len - 1 TSRMLS_CC) != SUCCESS);
if (key) {
if (key_type == HASH_KEY_IS_LONG) {
ZVAL_LONG(key, int_key);
} else {
const char *class_name, *prop_name;
int prop_name_len;
zend_unmangle_property_name_ex(
str_key, str_key_len - 1, &class_name, &prop_name, &prop_name_len
);
ZVAL_STRINGL(key, prop_name, prop_name_len, 1);
}
}
zend_hash_get_pointer(fe_ht, &EX_T(opline->op1.var).fe.fe_pos);
break;
}
@@ -13641,8 +13652,8 @@ static int ZEND_FASTCALL ZEND_FE_FETCH_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
/* reached end of iteration */
ZEND_VM_JMP(EX(op_array)->opcodes+opline->op2.opline_num);
}
if (use_key) {
key_type = zend_hash_get_current_key_ex(fe_ht, &str_key, &str_key_len, &int_key, 1, NULL);
if (key) {
zend_hash_get_current_key_zval(fe_ht, key);
}
zend_hash_move_forward(fe_ht);
zend_hash_get_pointer(fe_ht, &EX_T(opline->op1.var).fe.fe_pos);
@@ -13677,16 +13688,15 @@ static int ZEND_FASTCALL ZEND_FE_FETCH_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
/* failure in get_current_data */
ZEND_VM_JMP(EX(op_array)->opcodes+opline->op2.opline_num);
}
if (use_key) {
if (key) {
if (iter->funcs->get_current_key) {
key_type = iter->funcs->get_current_key(iter, &str_key, &str_key_len, &int_key TSRMLS_CC);
iter->funcs->get_current_key(iter, key TSRMLS_CC);
if (UNEXPECTED(EG(exception) != NULL)) {
zval_ptr_dtor(&array);
HANDLE_EXCEPTION();
}
} else {
key_type = HASH_KEY_IS_LONG;
int_key = iter->index;
ZVAL_LONG(key, iter->index);
}
}
break;
@@ -13702,26 +13712,6 @@ static int ZEND_FASTCALL ZEND_FE_FETCH_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
AI_SET_PTR(&EX_T(opline->result.var), *value);
}
if (use_key) {
zval *key = &EX_T((opline+1)->result.var).tmp_var;
switch (key_type) {
case HASH_KEY_IS_STRING:
Z_STRVAL_P(key) = (char*)str_key;
Z_STRLEN_P(key) = str_key_len-1;
Z_TYPE_P(key) = IS_STRING;
break;
case HASH_KEY_IS_LONG:
Z_LVAL_P(key) = int_key;
Z_TYPE_P(key) = IS_LONG;
break;
default:
case HASH_KEY_NON_EXISTANT:
ZVAL_NULL(key);
break;
}
}
CHECK_EXCEPTION();
ZEND_VM_INC_OPCODE();
ZEND_VM_NEXT_OPCODE();

View File

@@ -74,16 +74,15 @@ static void com_iter_get_data(zend_object_iterator *iter, zval ***data TSRMLS_DC
*data = &I->zdata;
}
static int com_iter_get_key(zend_object_iterator *iter, char **str_key, uint *str_key_len,
ulong *int_key TSRMLS_DC)
static void com_iter_get_key(zend_object_iterator *iter, zval *key TSRMLS_DC)
{
struct php_com_iterator *I = (struct php_com_iterator*)iter->data;
if (I->key == (ulong)-1) {
return HASH_KEY_NON_EXISTANT;
ZVAL_NULL(key);
} else {
ZVAL_LONG(key, I->key);
}
*int_key = I->key;
return HASH_KEY_IS_LONG;
}
static int com_iter_move_forwards(zend_object_iterator *iter TSRMLS_DC)

View File

@@ -519,16 +519,15 @@ static void saproxy_iter_get_data(zend_object_iterator *iter, zval ***data TSRML
*data = ptr_ptr;
}
static int saproxy_iter_get_key(zend_object_iterator *iter, char **str_key, uint *str_key_len,
ulong *int_key TSRMLS_DC)
static void saproxy_iter_get_key(zend_object_iterator *iter, zval *key TSRMLS_DC)
{
php_com_saproxy_iter *I = (php_com_saproxy_iter*)iter->data;
if (I->key == -1) {
return HASH_KEY_NON_EXISTANT;
ZVAL_NULL(key);
} else {
ZVAL_LONG(key, I->key);
}
*int_key = (ulong)I->key;
return HASH_KEY_IS_LONG;
}
static int saproxy_iter_move_forwards(zend_object_iterator *iter TSRMLS_DC)

View File

@@ -1867,11 +1867,10 @@ static void date_period_it_current_data(zend_object_iterator *iter, zval ***data
/* {{{ date_period_it_current_key */
static int date_period_it_current_key(zend_object_iterator *iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC)
static void date_period_it_current_key(zend_object_iterator *iter, zval *key TSRMLS_DC)
{
date_period_it *iterator = (date_period_it *)iter;
*int_key = iterator->current_index;
return HASH_KEY_IS_LONG;
date_period_it *iterator = (date_period_it *)iter;
ZVAL_LONG(key, iterator->current_index);
}
/* }}} */

View File

@@ -157,35 +157,22 @@ static void php_dom_iterator_current_data(zend_object_iterator *iter, zval ***da
}
/* }}} */
static int php_dom_iterator_current_key(zend_object_iterator *iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC) /* {{{ */
static void php_dom_iterator_current_key(zend_object_iterator *iter, zval *key TSRMLS_DC) /* {{{ */
{
zval *curobj;
xmlNodePtr curnode = NULL;
dom_object *intern;
zval *object;
int namelen;
php_dom_iterator *iterator = (php_dom_iterator *)iter;
object = (zval *)iterator->intern.data;
zval *object = (zval *)iterator->intern.data;
if (instanceof_function(Z_OBJCE_P(object), dom_nodelist_class_entry TSRMLS_CC)) {
*int_key = iter->index;
return HASH_KEY_IS_LONG;
ZVAL_LONG(key, iter->index);
} else {
curobj = iterator->curobj;
dom_object *intern = (dom_object *)zend_object_store_get_object(iterator->curobj TSRMLS_CC);
intern = (dom_object *)zend_object_store_get_object(curobj TSRMLS_CC);
if (intern != NULL && intern->ptr != NULL) {
curnode = (xmlNodePtr)((php_libxml_node_ptr *)intern->ptr)->node;
xmlNodePtr curnode = (xmlNodePtr)((php_libxml_node_ptr *)intern->ptr)->node;
ZVAL_STRINGL(key, (char *) curnode->name, xmlStrlen(curnode->name), 1);
} else {
return HASH_KEY_NON_EXISTANT;
ZVAL_NULL(key);
}
namelen = xmlStrlen(curnode->name);
*str_key = estrndup(curnode->name, namelen);
*str_key_len = namelen + 1;
return HASH_KEY_IS_STRING;
}
}
/* }}} */

View File

@@ -139,14 +139,10 @@ static void _breakiterator_parts_destroy_it(zend_object_iterator *iter TSRMLS_DC
zval_ptr_dtor(reinterpret_cast<zval**>(&iter->data));
}
static int _breakiterator_parts_get_current_key(zend_object_iterator *iter,
char **str_key,
uint *str_key_len,
ulong *int_key TSRMLS_DC)
static void _breakiterator_parts_get_current_key(zend_object_iterator *iter, zval *key TSRMLS_DC)
{
/* the actual work is done in move_forward and rewind */
*int_key = iter->index;
return HASH_KEY_IS_LONG;
ZVAL_LONG(key, iter->index);
}
static void _breakiterator_parts_move_forward(zend_object_iterator *iter TSRMLS_DC)
@@ -343,4 +339,4 @@ U_CFUNC void breakiterator_register_IntlPartsIterator_class(TSRMLS_D)
PARTSITER_DECL_LONG_CONST(KEY_RIGHT);
#undef PARTSITER_DECL_LONG_CONST
}
}

View File

@@ -251,19 +251,7 @@ static PHP_METHOD(IntlIterator, key)
INTLITERATOR_METHOD_FETCH_OBJECT;
if (ii->iterator->funcs->get_current_key) {
char *str_key;
uint str_key_len;
ulong int_key;
switch (ii->iterator->funcs->get_current_key(
ii->iterator, &str_key, &str_key_len, &int_key TSRMLS_CC)) {
case HASH_KEY_IS_LONG:
RETURN_LONG(int_key);
break;
case HASH_KEY_IS_STRING:
RETURN_STRINGL(str_key, str_key_len-1, 0);
break;
}
ii->iterator->funcs->get_current_key(ii->iterator, return_value TSRMLS_CC);
} else {
RETURN_LONG(ii->iterator->index);
}

View File

@@ -101,21 +101,18 @@ static void resourcebundle_iterator_current( zend_object_iterator *iter, zval **
/* }}} */
/* {{{ resourcebundle_iterator_key */
static int resourcebundle_iterator_key( zend_object_iterator *iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC )
static void resourcebundle_iterator_key( zend_object_iterator *iter, zval *key TSRMLS_DC )
{
ResourceBundle_iterator *iterator = (ResourceBundle_iterator *) iter;
if (!iterator->current) {
resourcebundle_iterator_read( iterator TSRMLS_CC);
}
if (iterator->is_table) {
*str_key = estrdup( iterator->currentkey );
*str_key_len = strlen( iterator->currentkey ) + 1;
return HASH_KEY_IS_STRING;
}
else {
*int_key = iterator->i;
return HASH_KEY_IS_LONG;
ZVAL_STRING(key, iterator->currentkey, 1);
} else {
ZVAL_LONG(key, iterator->i);
}
}
/* }}} */

View File

@@ -150,12 +150,11 @@ static void php_mysqli_result_iterator_rewind(zend_object_iterator *iter TSRMLS_
/* {{{ php_mysqli_result_iterator_current_key */
static int php_mysqli_result_iterator_current_key(zend_object_iterator *iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC)
static void php_mysqli_result_iterator_current_key(zend_object_iterator *iter, zval *key TSRMLS_DC)
{
php_mysqli_result_iterator *iterator = (php_mysqli_result_iterator*) iter;
*int_key = (ulong) iterator->row_num;
return HASH_KEY_IS_LONG;
ZVAL_LONG(key, iterator->row_num);
}
/* }}} */

View File

@@ -2499,16 +2499,15 @@ static void pdo_stmt_iter_get_data(zend_object_iterator *iter, zval ***data TSRM
*data = &I->fetch_ahead;
}
static int pdo_stmt_iter_get_key(zend_object_iterator *iter, char **str_key, uint *str_key_len,
ulong *int_key TSRMLS_DC)
static void pdo_stmt_iter_get_key(zend_object_iterator *iter, zval *key TSRMLS_DC)
{
struct php_pdo_iterator *I = (struct php_pdo_iterator*)iter->data;
if (I->key == (ulong)-1) {
return HASH_KEY_NON_EXISTANT;
ZVAL_NULL(key);
} else {
ZVAL_LONG(key, I->key);
}
*int_key = I->key;
return HASH_KEY_IS_LONG;
}
static void pdo_stmt_iter_move_forwards(zend_object_iterator *iter TSRMLS_DC)

View File

@@ -1434,16 +1434,13 @@ struct _phar_t {
static int phar_build(zend_object_iterator *iter, void *puser TSRMLS_DC) /* {{{ */
{
zval **value;
zend_uchar key_type;
zend_bool close_fp = 1;
ulong int_key;
struct _phar_t *p_obj = (struct _phar_t*) puser;
uint str_key_len, base_len = p_obj->l, fname_len;
phar_entry_data *data;
php_stream *fp;
size_t contents_len;
char *fname, *error = NULL, *base = p_obj->b, *opened, *save = NULL, *temp = NULL;
phar_zstr key;
char *str_key;
zend_class_entry *ce = p_obj->c;
phar_archive_object *phar_obj = p_obj->p;
@@ -1478,35 +1475,24 @@ static int phar_build(zend_object_iterator *iter, void *puser TSRMLS_DC) /* {{{
}
if (iter->funcs->get_current_key) {
key_type = iter->funcs->get_current_key(iter, &key, &str_key_len, &int_key TSRMLS_CC);
zval key;
iter->funcs->get_current_key(iter, &key TSRMLS_CC);
if (EG(exception)) {
return ZEND_HASH_APPLY_STOP;
}
if (key_type == HASH_KEY_IS_LONG) {
if (Z_TYPE(key) != IS_STRING) {
zval_dtor(&key);
zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC, "Iterator %v returned an invalid key (must return a string)", ce->name);
return ZEND_HASH_APPLY_STOP;
}
if (key_type > 9) { /* IS_UNICODE == 10 */
#if PHP_VERSION_ID < 60000
/* this can never happen, but fixes a compile warning */
spprintf(&str_key, 0, "%s", key);
#else
spprintf(&str_key, 0, "%v", key);
ezfree(key);
#endif
} else {
PHAR_STR(key, str_key);
}
str_key_len = Z_STRLEN(key);
str_key = estrndup(Z_STRVAL(key), str_key_len);
save = str_key;
if (str_key[str_key_len - 1] == '\0') {
str_key_len--;
}
zval_dtor(&key);
} else {
zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC, "Iterator %v returned an invalid key (must return a string)", ce->name);
return ZEND_HASH_APPLY_STOP;
@@ -1641,32 +1627,24 @@ phar_spl_fileinfo:
}
} else {
if (iter->funcs->get_current_key) {
key_type = iter->funcs->get_current_key(iter, &key, &str_key_len, &int_key TSRMLS_CC);
zval key;
iter->funcs->get_current_key(iter, &key TSRMLS_CC);
if (EG(exception)) {
return ZEND_HASH_APPLY_STOP;
}
if (key_type == HASH_KEY_IS_LONG) {
if (Z_TYPE(key) != IS_STRING) {
zval_dtor(&key);
zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC, "Iterator %v returned an invalid key (must return a string)", ce->name);
return ZEND_HASH_APPLY_STOP;
}
if (key_type > 9) { /* IS_UNICODE == 10 */
#if PHP_VERSION_ID < 60000
/* this can never happen, but fixes a compile warning */
spprintf(&str_key, 0, "%s", key);
#else
spprintf(&str_key, 0, "%v", key);
ezfree(key);
#endif
} else {
PHAR_STR(key, str_key);
}
str_key_len = Z_STRLEN(key);
str_key = estrndup(Z_STRVAL(key), str_key_len);
save = str_key;
if (str_key[str_key_len - 1] == '\0') str_key_len--;
zval_dtor(&key);
} else {
zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC, "Iterator %v returned an invalid key (must return a string)", ce->name);
return ZEND_HASH_APPLY_STOP;

View File

@@ -59,7 +59,7 @@ static zval *sxe_get_value(zval *z TSRMLS_DC);
static void php_sxe_iterator_dtor(zend_object_iterator *iter TSRMLS_DC);
static int php_sxe_iterator_valid(zend_object_iterator *iter TSRMLS_DC);
static void php_sxe_iterator_current_data(zend_object_iterator *iter, zval ***data TSRMLS_DC);
static int php_sxe_iterator_current_key(zend_object_iterator *iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC);
static void php_sxe_iterator_current_key(zend_object_iterator *iter, zval *key TSRMLS_DC);
static void php_sxe_iterator_move_forward(zend_object_iterator *iter TSRMLS_DC);
static void php_sxe_iterator_rewind(zend_object_iterator *iter TSRMLS_DC);
@@ -2376,29 +2376,22 @@ static void php_sxe_iterator_current_data(zend_object_iterator *iter, zval ***da
}
/* }}} */
static int php_sxe_iterator_current_key(zend_object_iterator *iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC) /* {{{ */
static void php_sxe_iterator_current_key(zend_object_iterator *iter, zval *key TSRMLS_DC) /* {{{ */
{
zval *curobj;
xmlNodePtr curnode = NULL;
php_sxe_object *intern;
int namelen;
php_sxe_iterator *iterator = (php_sxe_iterator *)iter;
curobj = iterator->sxe->iter.data;
zval *curobj = iterator->sxe->iter.data;
php_sxe_object *intern = (php_sxe_object *)zend_object_store_get_object(curobj TSRMLS_CC);
intern = (php_sxe_object *)zend_object_store_get_object(curobj TSRMLS_CC);
xmlNodePtr curnode = NULL;
if (intern != NULL && intern->node != NULL) {
curnode = (xmlNodePtr)((php_libxml_node_ptr *)intern->node)->node;
}
if (!curnode) {
return HASH_KEY_NON_EXISTANT;
if (curnode) {
ZVAL_STRINGL(key, (char *) curnode->name, xmlStrlen(curnode->name), 1);
} else {
ZVAL_NULL(key);
}
namelen = xmlStrlen(curnode->name);
*str_key = estrndup((char *)curnode->name, namelen);
*str_key_len = namelen + 1;
return HASH_KEY_IS_STRING;
}
/* }}} */

View File

@@ -2313,10 +2313,6 @@ static xmlNodePtr to_xml_array(encodeTypePtr type, zval *data, int style, xmlNod
zend_object_iterator *iter;
zend_class_entry *ce = Z_OBJCE_P(data);
zval **val;
char *str_key;
uint str_key_len;
ulong int_key;
int key_type;
ALLOC_ZVAL(array_copy);
INIT_PZVAL(array_copy);
@@ -2345,19 +2341,14 @@ static xmlNodePtr to_xml_array(encodeTypePtr type, zval *data, int style, xmlNod
goto iterator_done;
}
if (iter->funcs->get_current_key) {
key_type = iter->funcs->get_current_key(iter, &str_key, &str_key_len, &int_key TSRMLS_CC);
zval key;
iter->funcs->get_current_key(iter, &key TSRMLS_CC);
if (EG(exception)) {
goto iterator_done;
}
switch(key_type) {
case HASH_KEY_IS_STRING:
add_assoc_zval_ex(array_copy, str_key, str_key_len, *val);
efree(str_key);
break;
case HASH_KEY_IS_LONG:
add_index_zval(array_copy, int_key, *val);
break;
}
array_set_zval_key(Z_ARRVAL_P(array_copy), &key, *val);
zval_ptr_dtor(val);
zval_dtor(&key);
} else {
add_next_index_zval(array_copy, *val);
}

View File

@@ -1018,20 +1018,20 @@ static void spl_array_it_get_current_data(zend_object_iterator *iter, zval ***da
}
/* }}} */
static int spl_array_it_get_current_key(zend_object_iterator *iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC) /* {{{ */
static void spl_array_it_get_current_key(zend_object_iterator *iter, zval *key TSRMLS_DC) /* {{{ */
{
spl_array_it *iterator = (spl_array_it *)iter;
spl_array_object *object = iterator->object;
HashTable *aht = spl_array_get_hash_table(object, 0 TSRMLS_CC);
if (object->ar_flags & SPL_ARRAY_OVERLOADED_KEY) {
return zend_user_it_get_current_key(iter, str_key, str_key_len, int_key TSRMLS_CC);
zend_user_it_get_current_key(iter, key TSRMLS_CC);
} else {
if (spl_array_object_verify_pos_ex(object, aht, "ArrayIterator::current(): " TSRMLS_CC) == FAILURE) {
return HASH_KEY_NON_EXISTANT;
ZVAL_NULL(key);
} else {
zend_hash_get_current_key_zval_ex(aht, key, &object->pos);
}
return zend_hash_get_current_key_ex(aht, str_key, str_key_len, int_key, 1, &object->pos);
}
}
/* }}} */
@@ -1556,16 +1556,7 @@ void spl_array_iterator_key(zval *object, zval *return_value TSRMLS_DC) /* {{{ *
return;
}
switch (zend_hash_get_current_key_ex(aht, &string_key, &string_length, &num_key, 1, &intern->pos)) {
case HASH_KEY_IS_STRING:
RETVAL_STRINGL(string_key, string_length - 1, 0);
break;
case HASH_KEY_IS_LONG:
RETVAL_LONG(num_key);
break;
case HASH_KEY_NON_EXISTANT:
return;
}
zend_hash_get_current_key_zval_ex(aht, return_value, &intern->pos);
}
/* }}} */

View File

@@ -1621,7 +1621,7 @@ SPL_METHOD(GlobIterator, count)
static void spl_filesystem_dir_it_dtor(zend_object_iterator *iter TSRMLS_DC);
static int spl_filesystem_dir_it_valid(zend_object_iterator *iter TSRMLS_DC);
static void spl_filesystem_dir_it_current_data(zend_object_iterator *iter, zval ***data TSRMLS_DC);
static int spl_filesystem_dir_it_current_key(zend_object_iterator *iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC);
static void spl_filesystem_dir_it_current_key(zend_object_iterator *iter, zval *key TSRMLS_DC);
static void spl_filesystem_dir_it_move_forward(zend_object_iterator *iter TSRMLS_DC);
static void spl_filesystem_dir_it_rewind(zend_object_iterator *iter TSRMLS_DC);
@@ -1698,12 +1698,11 @@ static void spl_filesystem_dir_it_current_data(zend_object_iterator *iter, zval
/* }}} */
/* {{{ spl_filesystem_dir_it_current_key */
static int spl_filesystem_dir_it_current_key(zend_object_iterator *iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC)
static void spl_filesystem_dir_it_current_key(zend_object_iterator *iter, zval *key TSRMLS_DC)
{
spl_filesystem_object *object = spl_filesystem_iterator_to_object((spl_filesystem_iterator *)iter);
*int_key = object->u.dir.index;
return HASH_KEY_IS_LONG;
ZVAL_LONG(key, object->u.dir.index);
}
/* }}} */
@@ -1777,19 +1776,16 @@ static void spl_filesystem_tree_it_current_data(zend_object_iterator *iter, zval
/* }}} */
/* {{{ spl_filesystem_tree_it_current_key */
static int spl_filesystem_tree_it_current_key(zend_object_iterator *iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC)
static void spl_filesystem_tree_it_current_key(zend_object_iterator *iter, zval *key TSRMLS_DC)
{
spl_filesystem_object *object = spl_filesystem_iterator_to_object((spl_filesystem_iterator *)iter);
if (SPL_FILE_DIR_KEY(object, SPL_FILE_DIR_KEY_AS_FILENAME)) {
*str_key_len = strlen(object->u.dir.entry.d_name) + 1;
*str_key = estrndup(object->u.dir.entry.d_name, *str_key_len - 1);
ZVAL_STRING(key, object->u.dir.entry.d_name, 1);
} else {
spl_filesystem_object_get_file_name(object TSRMLS_CC);
*str_key_len = object->file_name_len + 1;
*str_key = estrndup(object->file_name, object->file_name_len);
ZVAL_STRINGL(key, object->file_name, object->file_name_len, 1);
}
return HASH_KEY_IS_STRING;
}
/* }}} */

View File

@@ -1023,12 +1023,11 @@ static void spl_dllist_it_get_current_data(zend_object_iterator *iter, zval ***d
}
/* }}} */
static int spl_dllist_it_get_current_key(zend_object_iterator *iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC) /* {{{ */
static void spl_dllist_it_get_current_key(zend_object_iterator *iter, zval *key TSRMLS_DC) /* {{{ */
{
spl_dllist_it *iterator = (spl_dllist_it *)iter;
*int_key = (ulong) iterator->traverse_position;
return HASH_KEY_IS_LONG;
ZVAL_LONG(key, iterator->traverse_position);
}
/* }}} */

View File

@@ -948,18 +948,16 @@ static void spl_fixedarray_it_get_current_data(zend_object_iterator *iter, zval
}
/* }}} */
static int spl_fixedarray_it_get_current_key(zend_object_iterator *iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC) /* {{{ */
static void spl_fixedarray_it_get_current_key(zend_object_iterator *iter, zval *key TSRMLS_DC) /* {{{ */
{
spl_fixedarray_it *iterator = (spl_fixedarray_it *)iter;
spl_fixedarray_object *intern = iterator->object;
if (intern->flags & SPL_FIXEDARRAY_OVERLOADED_KEY) {
return zend_user_it_get_current_key(iter, str_key, str_key_len, int_key TSRMLS_CC);
zend_user_it_get_current_key(iter, key TSRMLS_CC);
} else {
*int_key = (ulong) iterator->object->current;
return HASH_KEY_IS_LONG;
ZVAL_LONG(key, iterator->object->current);
}
}
/* }}} */

View File

@@ -949,12 +949,11 @@ static void spl_pqueue_it_get_current_data(zend_object_iterator *iter, zval ***d
}
/* }}} */
static int spl_heap_it_get_current_key(zend_object_iterator *iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC) /* {{{ */
static void spl_heap_it_get_current_key(zend_object_iterator *iter, zval *key TSRMLS_DC) /* {{{ */
{
spl_heap_it *iterator = (spl_heap_it *)iter;
*int_key = (ulong) iterator->object->heap->count - 1;
return HASH_KEY_IS_LONG;
ZVAL_LONG(key, iterator->object->heap->count - 1);
}
/* }}} */

View File

@@ -190,16 +190,15 @@ static void spl_recursive_it_get_current_data(zend_object_iterator *iter, zval *
sub_iter->funcs->get_current_data(sub_iter, data TSRMLS_CC);
}
static int spl_recursive_it_get_current_key(zend_object_iterator *iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC)
static void spl_recursive_it_get_current_key(zend_object_iterator *iter, zval *key TSRMLS_DC)
{
spl_recursive_it_object *object = (spl_recursive_it_object*)iter->data;
zend_object_iterator *sub_iter = object->iterators[object->level].iterator;
if (sub_iter->funcs->get_current_key) {
return sub_iter->funcs->get_current_key(sub_iter, str_key, str_key_len, int_key TSRMLS_CC);
sub_iter->funcs->get_current_key(sub_iter, key TSRMLS_CC);
} else {
*int_key = iter->index;
return HASH_KEY_IS_LONG;
ZVAL_LONG(key, iter->index);
}
}
@@ -617,20 +616,7 @@ SPL_METHOD(RecursiveIteratorIterator, key)
}
if (iterator->funcs->get_current_key) {
char *str_key;
uint str_key_len;
ulong int_key;
switch (iterator->funcs->get_current_key(iterator, &str_key, &str_key_len, &int_key TSRMLS_CC)) {
case HASH_KEY_IS_LONG:
RETURN_LONG(int_key);
break;
case HASH_KEY_IS_STRING:
RETURN_STRINGL(str_key, str_key_len-1, 0);
break;
default:
RETURN_NULL();
}
iterator->funcs->get_current_key(iterator, return_value TSRMLS_CC);
} else {
RETURN_NULL();
}
@@ -1171,20 +1157,7 @@ SPL_METHOD(RecursiveTreeIterator, key)
}
if (iterator->funcs->get_current_key) {
char *str_key;
uint str_key_len;
ulong int_key;
switch (iterator->funcs->get_current_key(iterator, &str_key, &str_key_len, &int_key TSRMLS_CC)) {
case HASH_KEY_IS_LONG:
ZVAL_LONG(&key, int_key);
break;
case HASH_KEY_IS_STRING:
ZVAL_STRINGL(&key, str_key, str_key_len-1, 0);
break;
default:
ZVAL_NULL(&key);
}
iterator->funcs->get_current_key(iterator, &key TSRMLS_CC);
} else {
ZVAL_NULL(&key);
}
@@ -1590,9 +1563,9 @@ static inline void spl_dual_it_free(spl_dual_it_object *intern TSRMLS_DC)
zval_ptr_dtor(&intern->current.data);
intern->current.data = NULL;
}
if (intern->current.str_key) {
efree(intern->current.str_key);
intern->current.str_key = NULL;
if (intern->current.key) {
zval_ptr_dtor(&intern->current.key);
intern->current.key = NULL;
}
if (intern->dit_type == DIT_CachingIterator || intern->dit_type == DIT_RecursiveCachingIterator) {
if (intern->u.caching.zstr) {
@@ -1635,11 +1608,16 @@ static inline int spl_dual_it_fetch(spl_dual_it_object *intern, int check_more T
intern->current.data = *data;
Z_ADDREF_P(intern->current.data);
}
MAKE_STD_ZVAL(intern->current.key);
if (intern->inner.iterator->funcs->get_current_key) {
intern->current.key_type = intern->inner.iterator->funcs->get_current_key(intern->inner.iterator, &intern->current.str_key, &intern->current.str_key_len, &intern->current.int_key TSRMLS_CC);
intern->inner.iterator->funcs->get_current_key(intern->inner.iterator, intern->current.key TSRMLS_CC);
if (EG(exception)) {
zval_ptr_dtor(&intern->current.key);
intern->current.key = NULL;
}
} else {
intern->current.key_type = HASH_KEY_IS_LONG;
intern->current.int_key = intern->current.pos;
ZVAL_LONG(intern->current.key, intern->current.pos);
}
return EG(exception) ? FAILURE : SUCCESS;
}
@@ -1711,12 +1689,8 @@ SPL_METHOD(dual_it, key)
SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis());
if (intern->current.data) {
if (intern->current.key_type == HASH_KEY_IS_STRING) {
RETURN_STRINGL(intern->current.str_key, intern->current.str_key_len-1, 1);
} else {
RETURN_LONG(intern->current.int_key);
}
if (intern->current.key) {
RETURN_ZVAL(intern->current.key, 1, 0);
}
RETURN_NULL();
} /* }}} */
@@ -1927,27 +1901,18 @@ SPL_METHOD(CallbackFilterIterator, accept)
zend_fcall_info *fci = &intern->u.cbfilter->fci;
zend_fcall_info_cache *fcc = &intern->u.cbfilter->fcc;
zval **params[3];
zval zkey;
zval *zkey_p = &zkey;
zval *result;
if (zend_parse_parameters_none() == FAILURE) {
return;
}
if (intern->current.data == NULL) {
if (intern->current.data == NULL || intern->current.key == NULL) {
RETURN_FALSE;
}
INIT_PZVAL(&zkey);
if (intern->current.key_type == HASH_KEY_IS_LONG) {
ZVAL_LONG(&zkey, intern->current.int_key);
} else {
ZVAL_STRINGL(&zkey, intern->current.str_key, intern->current.str_key_len-1, 0);
}
params[0] = &intern->current.data;
params[1] = &zkey_p;
params[1] = &intern->current.key;
params[2] = &intern->inner.zobject;
fci->retval_ptr_ptr = &result;
@@ -1971,9 +1936,9 @@ SPL_METHOD(CallbackFilterIterator, accept)
SPL_METHOD(RegexIterator, accept)
{
spl_dual_it_object *intern;
char *subject, tmp[32], *result;
char *subject, *result;
int subject_len, use_copy, count = 0, result_len;
zval subject_copy, zcount, *replacement, tmp_replacement;
zval *subject_ptr, subject_copy, zcount, *replacement, tmp_replacement;
if (zend_parse_parameters_none() == FAILURE) {
return;
@@ -1986,24 +1951,18 @@ SPL_METHOD(RegexIterator, accept)
}
if (intern->u.regex.flags & REGIT_USE_KEY) {
if (intern->current.key_type == HASH_KEY_IS_LONG) {
subject_len = slprintf(tmp, sizeof(tmp), "%ld", intern->current.int_key);
subject = &tmp[0];
use_copy = 0;
} else {
subject_len = intern->current.str_key_len - 1;
subject = estrndup(intern->current.str_key, subject_len);
use_copy = 1;
}
subject_ptr = intern->current.key;
} else {
zend_make_printable_zval(intern->current.data, &subject_copy, &use_copy);
if (use_copy) {
subject = Z_STRVAL(subject_copy);
subject_len = Z_STRLEN(subject_copy);
} else {
subject = Z_STRVAL_P(intern->current.data);
subject_len = Z_STRLEN_P(intern->current.data);
}
subject_ptr = intern->current.data;
}
zend_make_printable_zval(subject_ptr, &subject_copy, &use_copy);
if (use_copy) {
subject = Z_STRVAL(subject_copy);
subject_len = Z_STRLEN(subject_copy);
} else {
subject = Z_STRVAL_P(subject_ptr);
subject_len = Z_STRLEN_P(subject_ptr);
}
switch (intern->u.regex.mode)
@@ -2051,12 +2010,9 @@ SPL_METHOD(RegexIterator, accept)
result = php_pcre_replace_impl(intern->u.regex.pce, subject, subject_len, replacement, 0, &result_len, -1, &count TSRMLS_CC);
if (intern->u.regex.flags & REGIT_USE_KEY) {
if (intern->current.key_type != HASH_KEY_IS_LONG) {
efree(intern->current.str_key);
}
intern->current.key_type = HASH_KEY_IS_STRING;
intern->current.str_key = result;
intern->current.str_key_len = result_len + 1;
zval_ptr_dtor(&intern->current.key);
MAKE_STD_ZVAL(intern->current.key);
ZVAL_STRINGL(intern->current.key, result, result_len, 0);
} else {
zval_ptr_dtor(&intern->current.data);
MAKE_STD_ZVAL(intern->current.data);
@@ -2590,14 +2546,14 @@ static inline void spl_caching_it_next(spl_dual_it_object *intern TSRMLS_DC)
/* Full cache ? */
if (intern->u.caching.flags & CIT_FULL_CACHE) {
zval *zcacheval;
zval *key = intern->current.key;
MAKE_STD_ZVAL(zcacheval);
ZVAL_ZVAL(zcacheval, intern->current.data, 1, 0);
if (intern->current.key_type == HASH_KEY_IS_LONG) {
add_index_zval(intern->u.caching.zcache, intern->current.int_key, zcacheval);
} else {
zend_symtable_update(HASH_OF(intern->u.caching.zcache), intern->current.str_key, intern->current.str_key_len, &zcacheval, sizeof(void*), NULL);
}
array_set_zval_key(HASH_OF(intern->u.caching.zcache), key, zcacheval);
zval_ptr_dtor(&zcacheval);
}
/* Recursion ? */
if (intern->dit_type == DIT_RecursiveCachingIterator) {
@@ -2755,13 +2711,9 @@ SPL_METHOD(CachingIterator, __toString)
return;
}
if (intern->u.caching.flags & CIT_TOSTRING_USE_KEY) {
if (intern->current.key_type == HASH_KEY_IS_STRING) {
RETURN_STRINGL(intern->current.str_key, intern->current.str_key_len-1, 1);
} else {
RETVAL_LONG(intern->current.int_key);
convert_to_string(return_value);
return;
}
MAKE_COPY_ZVAL(&intern->current.key, return_value);
convert_to_string(return_value);
return;
} else if (intern->u.caching.flags & CIT_TOSTRING_USE_CURRENT) {
MAKE_COPY_ZVAL(&intern->current.data, return_value);
convert_to_string(return_value);
@@ -3123,19 +3075,7 @@ SPL_METHOD(NoRewindIterator, key)
SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis());
if (intern->inner.iterator->funcs->get_current_key) {
char *str_key;
uint str_key_len;
ulong int_key;
switch (intern->inner.iterator->funcs->get_current_key(intern->inner.iterator, &str_key, &str_key_len, &int_key TSRMLS_CC)) {
case HASH_KEY_IS_LONG:
RETURN_LONG(int_key);
break;
case HASH_KEY_IS_STRING:
RETURN_STRINGL(str_key, str_key_len-1, 0);
break;
default:
RETURN_NULL();
}
intern->inner.iterator->funcs->get_current_key(intern->inner.iterator, return_value TSRMLS_CC);
} else {
RETURN_NULL();
}
@@ -3502,11 +3442,7 @@ done:
static int spl_iterator_to_array_apply(zend_object_iterator *iter, void *puser TSRMLS_DC) /* {{{ */
{
zval **data, *return_value = (zval*)puser;
char *str_key;
uint str_key_len;
ulong int_key;
int key_type;
zval **data, *return_value = (zval*)puser;
iter->funcs->get_current_data(iter, &data TSRMLS_CC);
if (EG(exception)) {
@@ -3516,20 +3452,13 @@ static int spl_iterator_to_array_apply(zend_object_iterator *iter, void *puser T
return ZEND_HASH_APPLY_STOP;
}
if (iter->funcs->get_current_key) {
key_type = iter->funcs->get_current_key(iter, &str_key, &str_key_len, &int_key TSRMLS_CC);
zval key;
iter->funcs->get_current_key(iter, &key TSRMLS_CC);
if (EG(exception)) {
return ZEND_HASH_APPLY_STOP;
}
Z_ADDREF_PP(data);
switch(key_type) {
case HASH_KEY_IS_STRING:
add_assoc_zval_ex(return_value, str_key, str_key_len, *data);
efree(str_key);
break;
case HASH_KEY_IS_LONG:
add_index_zval(return_value, int_key, *data);
break;
}
array_set_zval_key(Z_ARRVAL_P(return_value), &key, *data);
zval_dtor(&key);
} else {
Z_ADDREF_PP(data);
add_next_index_zval(return_value, *data);

View File

@@ -133,10 +133,7 @@ typedef struct _spl_dual_it_object {
} inner;
struct {
zval *data;
char *str_key;
uint str_key_len;
ulong int_key;
int key_type; /* HASH_KEY_IS_STRING or HASH_KEY_IS_LONG */
zval *key;
int pos;
} current;
dual_it_type dit_type;

View File

@@ -0,0 +1,31 @@
--TEST--
Tests iterator_to_array() with non-scalar keys
--FILE--
<?php
function gen() {
yield "foo" => 0;
yield 1 => 1;
yield 2.5 => 2;
yield null => 3;
yield [] => 4;
yield new stdClass => 5;
}
var_dump(iterator_to_array(gen()));
?>
--EXPECTF--
Warning: Illegal offset type in %s on line %d
Warning: Illegal offset type in %s on line %d
array(4) {
["foo"]=>
int(0)
[1]=>
int(1)
[0]=>
int(2)
[""]=>
int(3)
}

View File

@@ -23,8 +23,8 @@ echo "-- Default flags, MultipleIterator::MIT_NEED_ALL | MultipleIterator::MIT_K
var_dump($m->getFlags() === (MultipleIterator::MIT_NEED_ALL | MultipleIterator::MIT_KEYS_NUMERIC));
foreach($m as $value) {
var_dump($m->key(), $value);
foreach($m as $key => $value) {
var_dump($key, $value);
}
try {
$m->current();
@@ -42,8 +42,8 @@ echo "-- Flags = MultipleIterator::MIT_NEED_ANY | MultipleIterator::MIT_KEYS_NUM
$m->setFlags(MultipleIterator::MIT_NEED_ANY | MultipleIterator::MIT_KEYS_NUMERIC);
var_dump($m->getFlags() === (MultipleIterator::MIT_NEED_ANY | MultipleIterator::MIT_KEYS_NUMERIC));
foreach($m as $value) {
var_dump($m->key(), $value);
foreach($m as $key => $value) {
var_dump($key, $value);
}
echo "-- Default flags, added element --\n";
@@ -51,8 +51,8 @@ echo "-- Default flags, added element --\n";
$m->setFlags(MultipleIterator::MIT_NEED_ALL | MultipleIterator::MIT_KEYS_NUMERIC);
$iter2[] = 3;
foreach($m as $value) {
var_dump($m->key(), $value);
foreach($m as $key => $value) {
var_dump($key, $value);
}
echo "-- Flags |= MultipleIterator::MIT_KEYS_ASSOC, with iterator associated with NULL --\n";
@@ -71,8 +71,8 @@ $m->attachIterator($iter1, "iter1");
$m->attachIterator($iter2, b"iter2");
$m->attachIterator($iter3, 3);
foreach($m as $value) {
var_dump($m->key(), $value);
foreach($m as $key => $value) {
var_dump($key, $value);
}
echo "-- Associate with invalid value --\n";
@@ -98,8 +98,8 @@ var_dump($m->containsIterator($iter2));
var_dump($m->detachIterator($iter2));
var_dump($m->countIterators());
var_dump($m->containsIterator($iter2));
foreach($m as $value) {
var_dump($m->key(), $value);
foreach($m as $key => $value) {
var_dump($key, $value);
}
?>

View File

@@ -935,16 +935,7 @@ PHP_FUNCTION(key)
return;
}
switch (zend_hash_get_current_key_ex(array, &string_key, &string_length, &num_key, 0, NULL)) {
case HASH_KEY_IS_STRING:
RETVAL_STRINGL(string_key, string_length - 1, 1);
break;
case HASH_KEY_IS_LONG:
RETVAL_LONG(num_key);
break;
case HASH_KEY_NON_EXISTANT:
return;
}
zend_hash_get_current_key_zval(array, return_value);
}
/* }}} */
@@ -1055,9 +1046,6 @@ static int php_array_walk(HashTable *target_hash, zval *userdata, int recursive
zval **args[3], /* Arguments to userland function */
*retval_ptr, /* Return value - unused */
*key=NULL; /* Entry key */
char *string_key;
uint string_key_len;
ulong num_key;
/* Set up known arguments */
args[1] = &key;
@@ -1103,17 +1091,7 @@ static int php_array_walk(HashTable *target_hash, zval *userdata, int recursive
} else {
/* Allocate space for key */
MAKE_STD_ZVAL(key);
/* Set up the key */
switch (zend_hash_get_current_key_ex(target_hash, &string_key, &string_key_len, &num_key, 0, NULL)) {
case HASH_KEY_IS_LONG:
Z_TYPE_P(key) = IS_LONG;
Z_LVAL_P(key) = num_key;
break;
case HASH_KEY_IS_STRING:
ZVAL_STRINGL(key, string_key, string_key_len - 1, 1);
break;
}
zend_hash_get_current_key_zval(target_hash, key);
/* Call the userland function */
if (zend_call_function(&BG(array_walk_fci), &BG(array_walk_fci_cache) TSRMLS_CC) == SUCCESS) {
@@ -1225,15 +1203,8 @@ static void php_search_array(INTERNAL_FUNCTION_PARAMETERS, int behavior) /* {{{
if (behavior == 0) {
RETURN_TRUE;
} else {
/* Return current key */
switch (zend_hash_get_current_key_ex(Z_ARRVAL_P(array), &string_key, &str_key_len, &num_key, 0, &pos)) {
case HASH_KEY_IS_STRING:
RETURN_STRINGL(string_key, str_key_len - 1, 1);
break;
case HASH_KEY_IS_LONG:
RETURN_LONG(num_key);
break;
}
zend_hash_get_current_key_zval_ex(Z_ARRVAL_P(array), return_value, &pos);
return;
}
}
zend_hash_move_forward_ex(Z_ARRVAL_P(array), &pos);
@@ -2480,19 +2451,8 @@ PHP_FUNCTION(array_keys)
if (add_key) {
MAKE_STD_ZVAL(new_val);
switch (zend_hash_get_current_key_ex(Z_ARRVAL_P(input), &string_key, &string_key_len, &num_key, 1, &pos)) {
case HASH_KEY_IS_STRING:
ZVAL_STRINGL(new_val, string_key, string_key_len - 1, 0);
zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &new_val, sizeof(zval *), NULL);
break;
case HASH_KEY_IS_LONG:
Z_TYPE_P(new_val) = IS_LONG;
Z_LVAL_P(new_val) = num_key;
zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &new_val, sizeof(zval *), NULL);
break;
}
zend_hash_get_current_key_zval_ex(Z_ARRVAL_P(input), new_val, &pos);
zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &new_val, sizeof(zval *), NULL);
}
zend_hash_move_forward_ex(Z_ARRVAL_P(input), &pos);
@@ -2705,15 +2665,7 @@ PHP_FUNCTION(array_flip)
zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(array), &pos);
while (zend_hash_get_current_data_ex(Z_ARRVAL_P(array), (void **)&entry, &pos) == SUCCESS) {
MAKE_STD_ZVAL(data);
switch (zend_hash_get_current_key_ex(Z_ARRVAL_P(array), &string_key, &str_key_len, &num_key, 1, &pos)) {
case HASH_KEY_IS_STRING:
ZVAL_STRINGL(data, string_key, str_key_len - 1, 0);
break;
case HASH_KEY_IS_LONG:
Z_TYPE_P(data) = IS_LONG;
Z_LVAL_P(data) = num_key;
break;
}
zend_hash_get_current_key_zval_ex(Z_ARRVAL_P(array), data, &pos);
if (Z_TYPE_PP(entry) == IS_LONG) {
zend_hash_index_update(Z_ARRVAL_P(return_value), Z_LVAL_PP(entry), &data, sizeof(data), NULL);