Browse Source

Merge branch 'PHP-5.5' of git.php.net:php-src into PHP-5.5

* 'PHP-5.5' of git.php.net:php-src:
  fix the fix
  fix for bug  #63530 	mysqlnd_stmt::bind_one_parameter uses wrong alloc for stmt->param_bind
  Forgot to remove some now unused variables
  Add support for non-scalar Iterator keys in foreach
  fixed headers order
  - Updated to version 2013.2 (2013b)
  fixed the test
  Fixed bug #64370 (microtime(true) less than $_SERVER['REQUEST_TIME_FLOAT'])
  Disable zend_always_inline in debug build
pull/288/merge
Dmitry Stogov 14 years ago
parent
commit
dd1c358d1b
  1. 5
      NEWS
  2. 2
      UPGRADING
  3. 8
      UPGRADING.INTERNALS
  4. 52
      Zend/tests/generators/generator_with_nonscalar_keys.phpt
  5. 7
      Zend/zend.h
  6. 34
      Zend/zend_API.c
  7. 2
      Zend/zend_API.h
  8. 24
      Zend/zend_generators.c
  9. 18
      Zend/zend_hash.c
  10. 4
      Zend/zend_hash.h
  11. 38
      Zend/zend_interfaces.c
  12. 2
      Zend/zend_interfaces.h
  13. 7
      Zend/zend_iterators.h
  14. 1
      Zend/zend_types.h
  15. 70
      Zend/zend_vm_def.h
  16. 70
      Zend/zend_vm_execute.h
  17. 9
      ext/com_dotnet/com_iterator.c
  18. 9
      ext/com_dotnet/com_saproxy.c
  19. 1209
      ext/date/lib/timezonedb.h
  20. 7
      ext/date/php_date.c
  21. 27
      ext/dom/dom_iterators.c
  22. 10
      ext/intl/breakiterator/breakiterator_iterators.cpp
  23. 14
      ext/intl/common/common_enum.cpp
  24. 13
      ext/intl/resourcebundle/resourcebundle_iterator.c
  25. 5
      ext/mysqli/mysqli_result_iterator.c
  26. 2
      ext/mysqlnd/mysqlnd_ps.c
  27. 9
      ext/pdo/pdo_stmt.c
  28. 20
      ext/pdo_mysql/mysql_statement.c
  29. 50
      ext/phar/phar_object.c
  30. 27
      ext/simplexml/simplexml.c
  31. 19
      ext/soap/php_encoding.c
  32. 24
      ext/spl/spl_array.c
  33. 20
      ext/spl/spl_directory.c
  34. 5
      ext/spl/spl_dllist.c
  35. 8
      ext/spl/spl_fixedarray.c
  36. 5
      ext/spl/spl_heap.c
  37. 171
      ext/spl/spl_iterators.c
  38. 5
      ext/spl/spl_iterators.h
  39. 31
      ext/spl/tests/iterator_to_array_nonscalar_keys.phpt
  40. 20
      ext/spl/tests/multiple_iterator_001.phpt
  41. 74
      ext/standard/array.c
  42. 21
      ext/standard/tests/bug64370_var1.phpt
  43. 23
      ext/standard/tests/bug64370_var2.phpt
  44. 2
      win32/globals.c
  45. 4
      win32/php_win32_globals.h
  46. 133
      win32/time.c

5
NEWS

@ -8,7 +8,12 @@ PHP NEWS
. Added support for changing the process's title in CLI/CLI-Server SAPIs.
The implementation is more robust that the proctitle PECL module. More
details here: https://wiki.php.net/rfc/cli_process_title. (Keyur)
. Fixed bug #64370 (microtime(true) less than $_SERVER['REQUEST_TIME_FLOAT']).
(Anatol)
- mysqlnd
. Fixed bug #63530 (mysqlnd_stmt::bind_one_parameter crashes, uses wrong alloc
for stmt->param_bind). (Andrey)
07 Mar 2013, PHP 5.5.0 Alpha 6

2
UPGRADING

@ -81,6 +81,8 @@ PHP 5.5 UPGRADE NOTES
a string constant. (https://wiki.php.net/rfc/class_name_scalars)
- Support for changing the process's title in CLI/CLI-Server SAPIs. (Keyur)
(https://wiki.php.net/rfc/cli_process_title)
- Added support for non-scalar Iterator keys in foreach.
(https://wiki.php.net/rfc/foreach-non-scalar-keys).
========================================
2. Changes in SAPI modules

8
UPGRADING.INTERNALS

@ -64,6 +64,14 @@ void zend_qsort_r(void *base, size_t nmemb, size_t siz, compare_r_func_t compare
The extra argument it has (relatively to zend_qsort()) is passed to the
comparison function.
d. get_current_key
The signature of the get_current_key iteration handler has been changed to:
void (*get_current_key)(zend_object_iterator *iter, zval *key TSRMLS_DC);
The key should be written into the zval* using the ZVAL_* macros.
========================
2. Build system changes
========================

52
Zend/tests/generators/generator_with_nonscalar_keys.phpt

@ -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

7
Zend/zend.h

@ -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 {
@ -365,6 +364,10 @@ struct _zval_struct {
#define Z_UNSET_ISREF(z) Z_UNSET_ISREF_P(&(z))
#define Z_SET_ISREF_TO(z, isref) Z_SET_ISREF_TO_P(&(z), isref)
#if ZEND_DEBUG
#define zend_always_inline inline
#define zend_never_inline
#else
#if defined(__GNUC__)
#if __GNUC__ >= 3
#define zend_always_inline inline __attribute__((always_inline))
@ -373,7 +376,6 @@ struct _zval_struct {
#define zend_always_inline inline
#define zend_never_inline
#endif
#elif defined(_MSC_VER)
#define zend_always_inline __forceinline
#define zend_never_inline
@ -381,6 +383,7 @@ struct _zval_struct {
#define zend_always_inline inline
#define zend_never_inline
#endif
#endif /* ZEND_DEBUG */
#if (defined (__GNUC__) && __GNUC__ > 2 ) && !defined(DARWIN) && !defined(__hpux) && !defined(_AIX)
# define EXPECTED(condition) __builtin_expect(condition, 1)

34
Zend/zend_API.c

@ -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;

2
Zend/zend_API.h

@ -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);

24
Zend/zend_generators.c

@ -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 (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;
if (generator->key) {
ZVAL_ZVAL(key, generator->key, 1, 0);
} else {
ZVAL_NULL(key);
}
/* 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 */
}
/* }}} */

18
Zend/zend_hash.c

@ -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)
{

4
Zend/zend_hash.h

@ -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) \

38
Zend/zend_interfaces.c

@ -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)

2
Zend/zend_interfaces.h

@ -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);

7
Zend/zend_iterators.h

@ -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);

1
Zend/zend_types.h

@ -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;

70
Zend/zend_vm_def.h

@ -4231,13 +4231,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();
@ -4248,8 +4248,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);
@ -4261,15 +4264,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;
}
@ -4280,8 +4291,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);
@ -4316,16 +4327,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;
@ -4341,26 +4351,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();

70
Zend/zend_vm_execute.h

@ -13546,13 +13546,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();
@ -13563,8 +13563,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);
@ -13576,15 +13579,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;
}
@ -13595,8 +13606,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);
@ -13631,16 +13642,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;
@ -13656,26 +13666,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();

9
ext/com_dotnet/com_iterator.c

@ -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)

9
ext/com_dotnet/com_saproxy.c

@ -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)

1209
ext/date/lib/timezonedb.h
File diff suppressed because it is too large
View File

7
ext/date/php_date.c

@ -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);
}
/* }}} */

27
ext/dom/dom_iterators.c

@ -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;
}
}
/* }}} */

10
ext/intl/breakiterator/breakiterator_iterators.cpp

@ -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
}
}

14
ext/intl/common/common_enum.cpp

@ -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);
}

13
ext/intl/resourcebundle/resourcebundle_iterator.c

@ -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);
}
}
/* }}} */

5
ext/mysqli/mysqli_result_iterator.c

@ -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);
}
/* }}} */

2
ext/mysqlnd/mysqlnd_ps.c

@ -1463,7 +1463,7 @@ MYSQLND_METHOD(mysqlnd_stmt, bind_one_parameter)(MYSQLND_STMT * const s, unsigne
if (stmt->param_count) {
if (!stmt->param_bind) {
stmt->param_bind = mnd_ecalloc(stmt->param_count, sizeof(MYSQLND_PARAM_BIND));
stmt->param_bind = mnd_pecalloc(stmt->param_count, sizeof(MYSQLND_PARAM_BIND), stmt->persistent);
if (!stmt->param_bind) {
DBG_RETURN(FAIL);
}

9
ext/pdo/pdo_stmt.c

@ -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)

20
ext/pdo_mysql/mysql_statement.c

@ -343,7 +343,6 @@ static int pdo_mysql_stmt_next_rowset(pdo_stmt_t *stmt TSRMLS_DC) /* {{{ */
pdo_mysql_stmt *S = (pdo_mysql_stmt*)stmt->driver_data;
pdo_mysql_db_handle *H = S->H;
long row_count;
int ret;
PDO_DBG_ENTER("pdo_mysql_stmt_next_rowset");
PDO_DBG_INF_FMT("stmt=%p", S->stmt);
@ -412,26 +411,21 @@ static int pdo_mysql_stmt_next_rowset(pdo_stmt_t *stmt TSRMLS_DC) /* {{{ */
S->result = NULL;
}
ret = mysql_next_result(H->server);
if (!mysql_more_results(H->server)) {
/* No more results */
PDO_DBG_RETURN(0);
}
#if PDO_USE_MYSQLND
/* for whatever reason mysqlnd breaks with libmysql compatibility at the C level, no -1 */
if (PASS != ret) {
if (mysql_next_result(H->server) == FAIL) {
pdo_mysql_error_stmt(stmt);
PDO_DBG_RETURN(0);
}
if (mysql_more_results(H->server)) {
PDO_DBG_RETURN(pdo_mysql_fill_stmt_from_result(stmt TSRMLS_CC));
} else {
/* No more results */
PDO_DBG_RETURN(0);
PDO_DBG_RETURN(pdo_mysql_fill_stmt_from_result(stmt TSRMLS_CC));
}
#else
if (ret > 0) {
if (mysql_next_result(H->server) > 0) {
pdo_mysql_error_stmt(stmt);
PDO_DBG_RETURN(0);
} else if (ret < 0) {
/* No more results */
PDO_DBG_RETURN(0);
} else {
PDO_DBG_RETURN(pdo_mysql_fill_stmt_from_result(stmt TSRMLS_CC));
}

50
ext/phar/phar_object.c

@ -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;

27
ext/simplexml/simplexml.c

@ -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;
}
namelen = xmlStrlen(curnode->name);
*str_key = estrndup((char *)curnode->name, namelen);
*str_key_len = namelen + 1;
return HASH_KEY_IS_STRING;
if (curnode) {
ZVAL_STRINGL(key, (char *) curnode->name, xmlStrlen(curnode->name), 1);
} else {
ZVAL_NULL(key);
}
}
/* }}} */

19
ext/soap/php_encoding.c

@ -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);
}

24
ext/spl/spl_array.c

@ -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);
}
}
/* }}} */
@ -1547,25 +1547,13 @@ SPL_METHOD(Array, key)
void spl_array_iterator_key(zval *object, zval *return_value TSRMLS_DC) /* {{{ */
{
spl_array_object *intern = (spl_array_object*)zend_object_store_get_object(object TSRMLS_CC);
char *string_key;
uint string_length;
ulong num_key;
HashTable *aht = spl_array_get_hash_table(intern, 0 TSRMLS_CC);
if (spl_array_object_verify_pos(intern, aht TSRMLS_CC) == FAILURE) {
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);
}
/* }}} */

20
ext/spl/spl_directory.c

@ -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;
}
/* }}} */

5
ext/spl/spl_dllist.c

@ -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);
}
/* }}} */

8
ext/spl/spl_fixedarray.c

@ -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);
}
}
/* }}} */

5
ext/spl/spl_heap.c

@ -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);
}
/* }}} */

171
ext/spl/spl_iterators.c

@ -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);

5
ext/spl/spl_iterators.h

@ -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;

31
ext/spl/tests/iterator_to_array_nonscalar_keys.phpt

@ -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)
}

20
ext/spl/tests/multiple_iterator_001.phpt

@ -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);
}
?>

74
ext/standard/array.c

@ -927,24 +927,12 @@ PHP_FUNCTION(current)
PHP_FUNCTION(key)
{
HashTable *array;
char *string_key;
uint string_length;
ulong num_key;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "H", &array) == FAILURE) {
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 +1043,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 +1088,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) {
@ -1205,9 +1180,6 @@ static void php_search_array(INTERNAL_FUNCTION_PARAMETERS, int behavior) /* {{{
res; /* comparison result */
HashPosition pos; /* hash iterator */
zend_bool strict = 0; /* strict comparison or not */
ulong num_key;
uint str_key_len;
char *string_key;
int (*is_equal_func)(zval *, zval *, zval * TSRMLS_DC) = is_equal_function;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "za|b", &value, &array, &strict) == FAILURE) {
@ -1225,15 +1197,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);
@ -2447,9 +2412,6 @@ PHP_FUNCTION(array_keys)
res, /* Result of comparison */
*new_val; /* New value */
int add_key; /* Flag to indicate whether a key should be added */
char *string_key; /* String key */
uint string_key_len;
ulong num_key; /* Numeric key */
zend_bool strict = 0; /* do strict comparison */
HashPosition pos;
int (*is_equal_func)(zval *, zval *, zval * TSRMLS_DC) = is_equal_function;
@ -2480,19 +2442,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);
@ -2691,9 +2642,6 @@ PHP_FUNCTION(array_pad)
PHP_FUNCTION(array_flip)
{
zval *array, **entry, *data;
char *string_key;
uint str_key_len;
ulong num_key;
HashPosition pos;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &array) == FAILURE) {
@ -2705,15 +2653,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);

21
ext/standard/tests/bug64370_var1.phpt

@ -0,0 +1,21 @@
--TEST--
Test bug #64370 microtime(true) less than $_SERVER['REQUEST_TIME_FLOAT']
--FILE--
<?php
echo "\$_SERVER['REQUEST_TIME']: {$_SERVER['REQUEST_TIME']}\n";
echo "\$_SERVER['REQUEST_TIME_FLOAT']: {$_SERVER['REQUEST_TIME_FLOAT']}\n";
echo "time(): " . time() . "\n";
echo "microtime(true): " . microtime(true) . "\n";
$d = (microtime(true)-$_SERVER['REQUEST_TIME_FLOAT'])*1000;
echo "created in $d ms\n";
echo ((bool)($d >= 0)) . "\n";
?>
===DONE===
--EXPECTF--
$_SERVER['REQUEST_TIME']: %d
$_SERVER['REQUEST_TIME_FLOAT']: %f
time(): %d
microtime(true): %f
created in %f ms
1
===DONE===

23
ext/standard/tests/bug64370_var2.phpt

@ -0,0 +1,23 @@
--TEST--
Test bug #64370 sequential microtime(true) calls
--FILE--
<?php
$i = 0;
while(100000 > $i++) {
$m0 = microtime(true);
$m1 = microtime(true);
$d = $m1 - $m0;
/*echo "$d\n";*/
if ($d < 0) {
die("failed in {$i}th iteration");
}
}
echo "ok\n";
?>
===DONE===
--EXPECT--
ok
===DONE===

2
win32/globals.c

@ -65,8 +65,6 @@ PHP_RSHUTDOWN_FUNCTION(win32_core_globals)
;
closelog();
wg->starttime.tv_sec = 0;
wg->lasttime = 0;
return SUCCESS;
}

4
win32/php_win32_globals.h

@ -38,10 +38,6 @@ struct _php_win32_core_globals {
char *log_header;
HANDLE log_source;
/* time */
struct timeval starttime;
__int64 lasttime, freq;
HKEY registry_key;
HANDLE registry_event;
HashTable *registry_directories;

133
win32/time.c

@ -12,13 +12,6 @@
/* $Id$ */
/**
*
* 04-Feb-2001
* - Added patch by "Vanhanen, Reijo" <Reijo.Vanhanen@helsoft.fi>
* Improves accuracy of msec
*/
/* Include stuff ************************************************************ */
#include <config.w32.h>
@ -32,98 +25,56 @@
#include <errno.h>
#include "php_win32_globals.h"
int getfilesystemtime(struct timeval *time_Info)
typedef VOID (WINAPI *MyGetSystemTimeAsFileTime)(LPFILETIME lpSystemTimeAsFileTime);
static MyGetSystemTimeAsFileTime get_time_func(void)
{
FILETIME ft;
__int64 ff;
ULARGE_INTEGER convFromft;
GetSystemTimeAsFileTime(&ft); /* 100 ns blocks since 01-Jan-1641 */
/* resolution seems to be 0.01 sec */
/*
* Do not cast a pointer to a FILETIME structure to either a
* ULARGE_INTEGER* or __int64* value because it can cause alignment faults on 64-bit Windows.
* via http://technet.microsoft.com/en-us/library/ms724284(v=vs.85).aspx
*/
convFromft.HighPart = ft.dwHighDateTime;
convFromft.LowPart = ft.dwLowDateTime;
ff = convFromft.QuadPart;
time_Info->tv_sec = (int)(ff/(__int64)10000000-(__int64)11644473600);
time_Info->tv_usec = (int)(ff % 10000000)/10;
return 0;
MyGetSystemTimeAsFileTime timefunc = NULL;
HMODULE hMod = LoadLibrary("kernel32.dll");
if (hMod) {
/* Max possible resolution <1us, win8/server2012 */
timefunc = (MyGetSystemTimeAsFileTime)GetProcAddress(hMod, "GetSystemTimePreciseAsFileTime");
if(!timefunc) {
/* 100ns blocks since 01-Jan-1641 */
timefunc = (MyGetSystemTimeAsFileTime)GetProcAddress(hMod, "GetSystemTimeAsFileTime");
}
}
return timefunc;
}
int getfilesystemtime(struct timeval *tv)
{
FILETIME ft;
unsigned __int64 ff = 0;
MyGetSystemTimeAsFileTime timefunc;
timefunc = get_time_func();
if (timefunc) {
timefunc(&ft);
} else {
GetSystemTimeAsFileTime(&ft);
}
ff |= ft.dwHighDateTime;
ff <<= 32;
ff |= ft.dwLowDateTime;
ff /= 10; /* convert to microseconds */
ff -= 11644473600000000Ui64; /* convert to unix epoch */
tv->tv_sec = (long)(ff / 1000000UL);
tv->tv_usec = (long)(ff % 1000000UL);
return 0;
}
PHPAPI int gettimeofday(struct timeval *time_Info, struct timezone *timezone_Info)
{
__int64 timer;
LARGE_INTEGER li;
BOOL b;
double dt;
TSRMLS_FETCH();
/* Get the time, if they want it */
if (time_Info != NULL) {
if (PW32G(starttime).tv_sec == 0) {
b = QueryPerformanceFrequency(&li);
if (!b) {
PW32G(starttime).tv_sec = -1;
}
else {
PW32G(freq) = li.QuadPart;
b = QueryPerformanceCounter(&li);
if (!b) {
PW32G(starttime).tv_sec = -1;
}
else {
getfilesystemtime(&PW32G(starttime));
timer = li.QuadPart;
dt = (double)timer/PW32G(freq);
PW32G(starttime).tv_usec -= (int)((dt-(int)dt)*1000000);
if (PW32G(starttime).tv_usec < 0) {
PW32G(starttime).tv_usec += 1000000;
--PW32G(starttime).tv_sec;
}
PW32G(starttime).tv_sec -= (int)dt;
}
}
}
if (PW32G(starttime).tv_sec > 0) {
b = QueryPerformanceCounter(&li);
if (!b) {
PW32G(starttime).tv_sec = -1;
}
else {
timer = li.QuadPart;
if (timer < PW32G(lasttime)) {
getfilesystemtime(time_Info);
dt = (double)timer/PW32G(freq);
PW32G(starttime) = *time_Info;
PW32G(starttime).tv_usec -= (int)((dt-(int)dt)*1000000);
if (PW32G(starttime).tv_usec < 0) {
PW32G(starttime).tv_usec += 1000000;
--PW32G(starttime).tv_sec;
}
PW32G(starttime).tv_sec -= (int)dt;
}
else {
PW32G(lasttime) = timer;
dt = (double)timer/PW32G(freq);
time_Info->tv_sec = PW32G(starttime).tv_sec + (int)dt;
time_Info->tv_usec = PW32G(starttime).tv_usec + (int)((dt-(int)dt)*1000000);
if (time_Info->tv_usec >= 1000000) {
time_Info->tv_usec -= 1000000;
++time_Info->tv_sec;
}
}
}
}
if (PW32G(starttime).tv_sec < 0) {
getfilesystemtime(time_Info);
}
getfilesystemtime(time_Info);
}
/* Get the timezone, if they want it */
if (timezone_Info != NULL) {

Loading…
Cancel
Save