com php-src: Merge remote-tracking branch 'origin/PHP-5.6' into str_size_and_int64_56_backport: Zend/zend .h Zend/zend_API.c Zend/zend_ast.c
Zend/zend_ compile.c Zend/zend_compile.h Zend/zend_constants .c Zend/zend_execute.c Zend/zend_execute.h Zend /zend_execute_API.c Zend/zend_highlight.c
Zend/ze nd_language_parser.y Zend/zend_object_handlers.c Zend/zend_variables.c Zend/zend_vm_def.h Zend/ zend_vm_execute.h
ext/com_dotnet/com_variant.c ext/curl/mult
| From: | Anatol Belski | Date: | Tue, 15 Apr 2014 07:53:02 +0000 |
| Subject: | com php-src: Merge remote-tracking branch 'origin/PHP-5.6' into str_size_and_int64_56_backport: Zend/zend .h Zend/zend_API.c Zend/zend_ast.c Zend/zend_ compile.c Zend/zend_compile.h Zend/zend_constants .c Zend/zend_execute.c Zend/zend_execute.h Zend /zend_execute_API.c Zend/zend_highlight.c Zend/ze nd_language_parser.y Zend/zend_object_handlers.c Zend/zend_variables.c Zend/zend_vm_def.h Zend/ zend_vm_execute.h ext/com_dotnet/com_variant.c ext/curl/mult |
||
| Groups: | php.cvs | ||
| Request: | Send a blank email to php-cvs+get-76903@lists.php.net to get a copy of this message | ||
Commit: f1662376262cf74bb0d439e4bb32bba4cece27e2
Author: Anatol Belski <ab@php.net> Tue, 15 Apr 2014 09:53:02 +0200
Parents: 9112c2f122c61f3e9629516e8d86c39e610d184a 9e76e87ca961b57737f8f9db68972c5a9ce9b1f7
Branches: str_size_and_int64_56_backport
Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=f1662376262cf74bb0d439e4bb32bba4cece27e2
Log:
Merge remote-tracking branch 'origin/PHP-5.6' into str_size_and_int64_56_backport
* origin/PHP-5.6: (41 commits)
fix crash in MINFO when no mysqlnd plugins are loaded
backported some ext/intl tests from 5.6 into 5.4
test fixes for ICU 53.1
Fixed bug #67033 Remove reference to Windows 95
fix NEWS
Fixed bug #64604
Fix #66562: Consistency bug where curl_multi_getcontent behaves different from curl_exec
Fix bug #66482, replace wrong item name 'priority' with 'process..priority' in
php-fpm.conf
Fix windows build
Fix bug #66721
fix apr_psprintf format string from e0df4e3dba7c4ab92442b9e82c1de01fdbaa3cce
Fixed bug #67024 - getimagesize should recognize BMP files with negative height
Bug #66840: Fix broken build when extension built separately
Reverted to 5a0da281e5a9fa02db18b4822d8b103c65849fa9 Discussion: http://news.php.net/php.cvs/76836
Forgot title in phpt for bug #67064
Updated NEWS
Fix bug #67064 in a BC safe way You can use an optional parameter now when implementing the
Countable interface to get the $mode passed to count().
Added UPGRAING notice for bug #66015 in BC break section
Add new zend_hash_* APIs to UPGRADING.INTERNALS
Add str_* macros to UPGRADING.INTERNALS
...
Conflicts:
Zend/zend_compile.c
Zend/zend_execute_API.c
Zend/zend_language_parser.y
ext/mysqli/mysqli.c
ext/mysqlnd/mysqlnd.c
ext/mysqlnd/mysqlnd.h
ext/mysqlnd/mysqlnd_ps.c
ext/mysqlnd/mysqlnd_result.c
ext/mysqlnd/mysqlnd_result.h
ext/mysqlnd/mysqlnd_structs.h
ext/mysqlnd/mysqlnd_wireprotocol.c
ext/mysqlnd/mysqlnd_wireprotocol.h
ext/opcache/zend_accelerator_util_funcs.c
ext/spl/spl_observer.c
ext/standard/array..c
Bugs:
https://bugs.php.net/67033
https://bugs.php.net/64604
https://bugs.php.net/66562
https://bugs.php.net/66482
https://bugs.php.net/66721
https://bugs.php.net/67024
https://bugs.php.net/66840
https://bugs.php.net/67064
https://bugs.php.net/66015
Changed paths:
MM Zend/zend.h
MM Zend/zend_API.c
MM Zend/zend_ast.c
MM Zend/zend_compile.c
MM Zend/zend_compile.h
MM Zend/zend_constants.c
MM Zend/zend_execute.c
MM Zend/zend_execute.h
MM Zend/zend_execute_API.c
MM Zend/zend_highlight.c
MM Zend/zend_language_parser.y
MM Zend/zend_object_handlers.c
MM Zend/zend_variables.c
MM Zend/zend_vm_def.h
MM Zend/zend_vm_execute.h
MM ext/com_dotnet/com_variant.c
MM ext/curl/multi.c
MM ext/date/php_date.c
MM ext/interbase/ibase_blobs.c
MM ext/interbase/ibase_events.c
MM ext/interbase/ibase_query.c
MM ext/interbase/ibase_service.c
MM ext/interbase/interbase.c
MM ext/interbase/php_ibase_includes.h
MM ext/interbase/php_ibase_udf.c
MM ext/json/json.c
MM ext/mysql/php_mysql.c
MM ext/mysqli/mysqli.c
MM ext/mysqli/mysqli_api.c
MM ext/mysqli/mysqli_nonapi.c
MM ext/mysqli/mysqli_priv.h
MM ext/mysqlnd/mysqlnd.c
MM ext/mysqlnd/mysqlnd.h
MM ext/mysqlnd/mysqlnd_ps.c
MM ext/mysqlnd/mysqlnd_result.c
MM ext/mysqlnd/mysqlnd_result.h
MM ext/mysqlnd/mysqlnd_structs.h
MM ext/mysqlnd/mysqlnd_wireprotocol.c
MM ext/mysqlnd/mysqlnd_wireprotocol.h
MM ext/mysqlnd/php_mysqlnd.c
MM ext/opcache/ZendAccelerator.c
MM ext/opcache/zend_accelerator_module.c
MM ext/opcache/zend_accelerator_util_funcs.c
MM ext/opcache/zend_persist.c
MM ext/opcache/zend_persist_calc.c
MM ext/openssl/xp_ssl.c
MM ext/pdo_firebird/firebird_driver.c
MM ext/pdo_firebird/firebird_statement.c
MM ext/pdo_firebird/pdo_firebird.c
MM ext/pdo_firebird/php_pdo_firebird_int.h
MM ext/pdo_mysql/mysql_driver.c
MM ext/pgsql/pgsql.c
MM ext/phar/phar_object.c
MM ext/reflection/php_reflection.c
MM ext/soap/php_encoding.c
MM ext/spl/spl_observer.c
MM ext/standard/array.c
MM ext/standard/basic_functions.c
MM ext/standard/image.c
MM ext/standard/php_array.h
MM ext/standard/url.c
MM ext/xmlrpc/xmlrpc-epi-php.c
MM main/SAPI.c
MM main/php_variables.c
MM sapi/apache2handler/sapi_apache2.c
MM sapi/cgi/cgi_main.c
diff --cc Zend/zend_compile.c index 5686c21,beb5340..ef88eb3 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@@ -3461,9 -3461,9 +3461,9 @@@ static char * zend_get_function_declara *zv = *precv->op2.zv; zval_copy_ctor(zv); INIT_PZVAL(zv); - zval_update_constant_ex(&zv, (void*)1, fptr->common.scope TSRMLS_CC); + zval_update_constant_ex(&zv, 1, fptr->common.scope TSRMLS_CC); if (Z_TYPE_P(zv) == IS_BOOL) { - if (Z_LVAL_P(zv)) { + if (Z_IVAL_P(zv)) { memcpy(offset, "true", 4); offset += 4; } else { @@@ -5440,12 -5440,8 +5440,8 @@@ void zend_do_declare_class_constant(zno { zval *property; const char *cname = NULL; - zend_ulong hash; + zend_uint_t hash; - if(Z_TYPE(value->u.constant) == IS_CONSTANT_ARRAY) { - zend_error_noreturn(E_COMPILE_ERROR, "Arrays are not allowed in class constants"); - return; - } if ((CG(active_class_entry)->ce_flags & ZEND_ACC_TRAIT) == ZEND_ACC_TRAIT) { zend_error_noreturn(E_COMPILE_ERROR, "Traits cannot have constants"); return; @@@ -5887,52 -5883,25 +5883,25 @@@ void zend_do_add_array_element(znode *r } /* }}} */ - void zend_do_add_static_array_element(znode *result, znode *offset, const znode *expr) /* {{{ */ + void zend_do_add_static_array_element(zval *result, zval *offset, const zval *expr) /* {{{ */ { - zval *element; - - ALLOC_ZVAL(element); - *element = expr->u.constant; if (offset) { - switch (Z_TYPE(offset->u.constant) & IS_CONSTANT_TYPE_MASK) { - case IS_CONSTANT: - /* Ugly hack to denote that this value has a constant index */ - Z_TYPE_P(element) |= IS_CONSTANT_INDEX; - Z_STRVAL(offset->u.constant) = erealloc(Z_STRVAL(offset->u.constant), Z_STRSIZE(offset->u.constant)+3); - Z_STRVAL(offset->u.constant)[Z_STRSIZE(offset->u.constant)+1] = Z_TYPE(offset->u.constant); - Z_STRVAL(offset->u.constant)[Z_STRSIZE(offset->u.constant)+2] = 0; - zend_symtable_update(Z_ARRVAL(result->u.constant), Z_STRVAL(offset->u.constant), Z_STRSIZE(offset->u.constant)+3, &element, sizeof(zval *), NULL); - zval_dtor(&offset->u.constant); - break; - case IS_CONSTANT_AST: { - /* Another ugly hack to store the data about the AST in the array */ - char* key; - int len = sizeof(zend_ast *); - Z_TYPE_P(element) |= IS_CONSTANT_INDEX; - - key = emalloc(len + 2); - *(zend_ast **)key = Z_AST(offset->u.constant); - key[len] = Z_TYPE(offset->u.constant); - key[len + 1] = 0; - zend_symtable_update(Z_ARRVAL(result->u.constant), key, len + 2, &element, sizeof(zval *), NULL); - efree(key); - break; - } + switch (Z_TYPE_P(offset)) { case IS_STRING: - zend_symtable_update(Z_ARRVAL(result->u.constant), Z_STRVAL(offset->u.constant), Z_STRSIZE(offset->u.constant)+1, &element, sizeof(zval *), NULL); - zval_dtor(&offset->u.constant); - zend_symtable_update(Z_ARRVAL_P(result), Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, &expr, sizeof(zval *), NULL); ++ zend_symtable_update(Z_ARRVAL_P(result), Z_STRVAL_P(offset), Z_STRSIZE_P(offset)+1, &expr, sizeof(zval *), NULL); + zval_dtor(offset); break; case IS_NULL: - zend_symtable_update(Z_ARRVAL(result->u.constant), "", 1, &element, sizeof(zval *), NULL); + zend_symtable_update(Z_ARRVAL_P(result), "", 1, &expr, sizeof(zval *), NULL); break; - case IS_LONG: + case IS_INT: case IS_BOOL: - zend_hash_index_update(Z_ARRVAL(result->u.constant), Z_IVAL(offset->u.constant), &element, sizeof(zval *), NULL); - zend_hash_index_update(Z_ARRVAL_P(result), Z_LVAL_P(offset), &expr, sizeof(zval *), NULL); ++ zend_hash_index_update(Z_ARRVAL_P(result), Z_IVAL_P(offset), &expr, sizeof(zval *), NULL); break; case IS_DOUBLE: - zend_hash_index_update(Z_ARRVAL(result->u.constant), zend_dval_to_ival(Z_DVAL(offset->u.constant)), &element, sizeof(zval *), NULL); - zend_hash_index_update(Z_ARRVAL_P(result), zend_dval_to_lval(Z_DVAL_P(offset)), &expr, sizeof(zval *), NULL); ++ zend_hash_index_update(Z_ARRVAL_P(result), zend_dval_to_ival(Z_DVAL_P(offset)), &expr, sizeof(zval *), NULL); break; - case IS_CONSTANT_ARRAY: + case IS_ARRAY: zend_error(E_ERROR, "Illegal offset type"); break; } diff --cc Zend/zend_execute.h index 08af239,9bde312..0b81399 --- a/Zend/zend_execute.h +++ b/Zend/zend_execute.h @@@ -352,16 -352,18 +352,18 @@@ void execute_new_code(TSRMLS_D) ZEND_API const char *get_active_class_name(const char **space TSRMLS_DC); ZEND_API const char *get_active_function_name(TSRMLS_D); ZEND_API const char *zend_get_executed_filename(TSRMLS_D); -ZEND_API uint zend_get_executed_lineno(TSRMLS_D); +ZEND_API zend_size_t zend_get_executed_lineno(TSRMLS_D); ZEND_API zend_bool zend_is_executing(TSRMLS_D); -ZEND_API void zend_set_timeout(long seconds, int reset_signals); +ZEND_API void zend_set_timeout(zend_int_t seconds, int reset_signals); ZEND_API void zend_unset_timeout(TSRMLS_D); ZEND_API void zend_timeout(int dummy); -ZEND_API zend_class_entry *zend_fetch_class(const char *class_name, uint class_name_len, int fetch_type TSRMLS_DC); -ZEND_API zend_class_entry *zend_fetch_class_by_name(const char *class_name, uint class_name_len, const zend_literal *key, int fetch_type TSRMLS_DC); +ZEND_API zend_class_entry *zend_fetch_class(const char *class_name, zend_size_t class_name_len, int fetch_type TSRMLS_DC); +ZEND_API zend_class_entry *zend_fetch_class_by_name(const char *class_name, zend_size_t class_name_len, const zend_literal *key, int fetch_type TSRMLS_DC); void zend_verify_abstract_class(zend_class_entry *ce TSRMLS_DC); + ZEND_API void zend_fetch_dimension_by_zval(zval **result, zval *container, zval *dim TSRMLS_DC); + #ifdef ZEND_WIN32 void zend_init_timeout_thread(void); void zend_shutdown_timeout_thread(void); diff --cc Zend/zend_language_parser.y index d72f73e,56e702e..8887bac --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@@ -996,7 -994,9 +994,9 @@@ static_scalar_value | static_class_name_scalar { $$.u.ast = zend_ast_create_constant(&$1.u.constant); } | namespace_name { zend_do_fetch_constant(&$$, NULL, &$1, ZEND_CT, 1 TSRMLS_CC); $$.u.ast = zend_ast_create_constant(&$$.u.constant); } | T_NAMESPACE T_NS_SEPARATOR namespace_name { $$.op_type = IS_CONST; ZVAL_EMPTY_STRING(&$$.u.constant); zend_do_build_namespace_name(&$$, &$$, &$3 TSRMLS_CC); $3 = $$; zend_do_fetch_constant(&$$, NULL, &$3, ZEND_CT, 0 TSRMLS_CC); $$.u.ast = zend_ast_create_constant(&$$.u.constant); } - | T_NS_SEPARATOR namespace_name { char *tmp = estrndup(Z_STRVAL($2.u.constant), Z_STRLEN($2.u.constant)+1); memcpy(&(tmp[1]), Z_STRVAL($2.u.constant), Z_STRLEN($2.u.constant)+1); tmp[0] = '\\'; efree(Z_STRVAL($2.u.constant)); Z_STRVAL($2.u.constant) = tmp; ++Z_STRLEN($2.u.constant); zend_do_fetch_constant(&$$, NULL, &$2, ZEND_CT, 0 TSRMLS_CC); $$.u.ast = zend_ast_create_constant(&$$.u.constant); } + | T_NS_SEPARATOR namespace_name { char *tmp = estrndup(Z_STRVAL($2.u.constant), Z_STRSIZE($2.u.constant)+1); memcpy(&(tmp[1]), Z_STRVAL($2.u.constant), Z_STRSIZE($2.u.constant)+1); tmp[0] = '\\'; efree(Z_STRVAL($2.u.constant)); Z_STRVAL($2.u.constant) = tmp; ++Z_STRSIZE($2.u.constant); zend_do_fetch_constant(&$$, NULL, &$2, ZEND_CT, 0 TSRMLS_CC); $$.u.ast = zend_ast_create_constant(&$$.u.constant); } + | T_ARRAY '(' static_array_pair_list ')' { $$ = $3; } + | '[' static_array_pair_list ']' { $$ = $2; } | static_class_constant { $$.u.ast = zend_ast_create_constant(&$1.u.constant); } | T_CLASS_C { $$.u.ast = zend_ast_create_constant(&$1.u.constant); } | static_operation { $$ = $1; } diff --cc ext/json/json.c index 2794bf9,d4cb39f..4d434e0 --- a/ext/json/json.c +++ b/ext/json/json.c @@@ -228,9 -228,9 +228,9 @@@ static inline void json_pretty_print_in /* }}} */ -static void json_encode_array(smart_str *buf, zval **val, int options TSRMLS_DC) /* {{{ */ +static void json_encode_array(smart_str *buf, zval **val, php_int_t options TSRMLS_DC) /* {{{ */ { - int i, r; + int i, r, need_comma = 0; HashTable *myht; if (Z_TYPE_PP(val) == IS_ARRAY) { @@@ -262,11 -261,10 +261,10 @@@ { char *key; zval **data; - ulong index; - uint key_len; + php_uint_t index; + php_size_t key_len; HashPosition pos; HashTable *tmp_ht; - int need_comma = 0; zend_hash_internal_pointer_reset_ex(myht, &pos); for (;; zend_hash_move_forward_ex(myht, &pos)) { diff --cc ext/mysqli/mysqli.c index 9e1ba3a,b23d7e3..a475e78 --- a/ext/mysqli/mysqli.c +++ b/ext/mysqli/mysqli.c @@@ -709,18 -709,19 +709,19 @@@ PHP_MINIT_FUNCTION(mysqli #endif /* mysqli_real_connect flags */ - REGISTER_LONG_CONSTANT("MYSQLI_CLIENT_SSL", CLIENT_SSL, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("MYSQLI_CLIENT_COMPRESS",CLIENT_COMPRESS, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("MYSQLI_CLIENT_INTERACTIVE", CLIENT_INTERACTIVE, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("MYSQLI_CLIENT_IGNORE_SPACE", CLIENT_IGNORE_SPACE, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("MYSQLI_CLIENT_NO_SCHEMA", CLIENT_NO_SCHEMA, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("MYSQLI_CLIENT_FOUND_ROWS", CLIENT_FOUND_ROWS, CONST_CS | CONST_PERSISTENT); + REGISTER_INT_CONSTANT("MYSQLI_CLIENT_SSL", CLIENT_SSL, CONST_CS | CONST_PERSISTENT); + REGISTER_INT_CONSTANT("MYSQLI_CLIENT_COMPRESS",CLIENT_COMPRESS, CONST_CS | CONST_PERSISTENT); + REGISTER_INT_CONSTANT("MYSQLI_CLIENT_INTERACTIVE", CLIENT_INTERACTIVE, CONST_CS | CONST_PERSISTENT); + REGISTER_INT_CONSTANT("MYSQLI_CLIENT_IGNORE_SPACE", CLIENT_IGNORE_SPACE, CONST_CS | CONST_PERSISTENT); + REGISTER_INT_CONSTANT("MYSQLI_CLIENT_NO_SCHEMA", CLIENT_NO_SCHEMA, CONST_CS | CONST_PERSISTENT); + REGISTER_INT_CONSTANT("MYSQLI_CLIENT_FOUND_ROWS", CLIENT_FOUND_ROWS, CONST_CS | CONST_PERSISTENT); /* for mysqli_query */ - REGISTER_LONG_CONSTANT("MYSQLI_STORE_RESULT", MYSQLI_STORE_RESULT, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("MYSQLI_USE_RESULT", MYSQLI_USE_RESULT, CONST_CS | CONST_PERSISTENT); + REGISTER_INT_CONSTANT("MYSQLI_STORE_RESULT", MYSQLI_STORE_RESULT, CONST_CS | CONST_PERSISTENT); + REGISTER_INT_CONSTANT("MYSQLI_USE_RESULT", MYSQLI_USE_RESULT, CONST_CS | CONST_PERSISTENT); #if defined (MYSQLI_USE_MYSQLND) - REGISTER_LONG_CONSTANT("MYSQLI_ASYNC", MYSQLI_ASYNC, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("MYSQLI_STORE_RESULT_COPY_DATA", MYSQLI_STORE_RESULT_COPY_DATA, CONST_CS | CONST_PERSISTENT); + REGISTER_INT_CONSTANT("MYSQLI_ASYNC", MYSQLI_ASYNC, CONST_CS | CONST_PERSISTENT); ++ REGISTER_INT_CONSTANT("MYSQLI_STORE_RESULT_COPY_DATA", MYSQLI_STORE_RESULT_COPY_DATA, CONST_CS | CONST_PERSISTENT); #endif /* for mysqli_fetch_assoc */ diff --cc ext/mysqlnd/mysqlnd.c index 65b3941,893a144..625d111 --- a/ext/mysqlnd/mysqlnd.c +++ b/ext/mysqlnd/mysqlnd.c @@@ -1107,11 -1107,12 +1107,12 @@@ MYSQLND_METHOD(mysqlnd_conn, connect)(M /* {{{ mysqlnd_connect */ PHPAPI MYSQLND * mysqlnd_connect(MYSQLND * conn_handle, const char * host, const char * user, - const char * passwd, unsigned int passwd_len, - const char * db, unsigned int db_len, - unsigned int port, + const char * passwd, php_size_t passwd_len, + const char * db, php_size_t db_len, + php_uint_t port, const char * socket_or_pipe, - php_uint_t mysql_flags - unsigned int mysql_flags, - unsigned int client_api_flags ++ php_uint_t mysql_flags, ++ php_uint_t client_api_flags TSRMLS_DC) { enum_func_status ret = FAIL; diff --cc ext/mysqlnd/mysqlnd.h index a3b56c4,f373ea5..042bd1d --- a/ext/mysqlnd/mysqlnd.h +++ b/ext/mysqlnd/mysqlnd.h @@@ -85,15 -85,16 +85,16 @@@ PHPAPI const MYSQLND_CHARSET * mysqlnd_ /* Connect */ - #define mysqlnd_init(persistent) _mysqlnd_init((persistent) TSRMLS_CC) - PHPAPI MYSQLND * _mysqlnd_init(zend_bool persistent TSRMLS_DC); + #define mysqlnd_init(client_flags, persistent) _mysqlnd_init((client_flags), (persistent) TSRMLS_CC) + PHPAPI MYSQLND * _mysqlnd_init(unsigned int client_flags, zend_bool persistent TSRMLS_DC); PHPAPI MYSQLND * mysqlnd_connect(MYSQLND * conn, const char * host, const char * user, - const char * passwd, unsigned int passwd_len, - const char * db, unsigned int db_len, - unsigned int port, + const char * passwd, php_size_t passwd_len, + const char * db, php_size_t db_len, + php_uint_t port, const char * socket_or_pipe, - php_uint_t mysql_flags - unsigned int mysql_flags, - unsigned int client_api_flags ++ php_uint_t mysql_flags, ++ php_uint_t client_api_flags TSRMLS_DC); #define mysqlnd_change_user(conn, user, passwd, db, silent) ((conn)->data)->m->change_user((conn)->data, (user), (passwd), (db), (silent), strlen((passwd)) TSRMLS_CC) @@@ -270,18 -271,19 +271,19 @@@ ZEND_BEGIN_MODULE_GLOBALS(mysqlnd char * trace_alloc_settings; /* The actual string */ MYSQLND_DEBUG * dbg; /* The DBG object for standard tracing */ MYSQLND_DEBUG * trace_alloc; /* The DBG object for allocation tracing */ - long net_cmd_buffer_size; - long net_read_buffer_size; - long log_mask; - long net_read_timeout; - long mempool_default_size; - long debug_emalloc_fail_threshold; - long debug_ecalloc_fail_threshold; - long debug_erealloc_fail_threshold; - long debug_malloc_fail_threshold; - long debug_calloc_fail_threshold; - long debug_realloc_fail_threshold; + php_int_t net_cmd_buffer_size; + php_int_t net_read_buffer_size; + php_int_t log_mask; + php_int_t net_read_timeout; + php_int_t mempool_default_size; + php_int_t debug_emalloc_fail_threshold; + php_int_t debug_ecalloc_fail_threshold; + php_int_t debug_erealloc_fail_threshold; + php_int_t debug_malloc_fail_threshold; + php_int_t debug_calloc_fail_threshold; + php_int_t debug_realloc_fail_threshold; char * sha256_server_public_key; + zend_bool fetch_data_copy; ZEND_END_MODULE_GLOBALS(mysqlnd) PHPAPI ZEND_EXTERN_MODULE_GLOBALS(mysqlnd) diff --cc ext/mysqlnd/mysqlnd_ps.c index 61583f5,bee8e1d..550f7f0 --- a/ext/mysqlnd/mysqlnd_ps.c +++ b/ext/mysqlnd/mysqlnd_ps.c @@@ -733,46 -736,48 +736,48 @@@ mysqlnd_stmt_fetch_row_buffered(MYSQLND { MYSQLND_STMT * s = (MYSQLND_STMT *) param; MYSQLND_STMT_DATA * stmt = s? s->data:NULL; - MYSQLND_RES_BUFFERED *set = result->stored_data; const MYSQLND_RES_METADATA * const meta = result->meta; - unsigned int field_count = meta->field_count; + php_uint_t field_count = meta->field_count; DBG_ENTER("mysqlnd_stmt_fetch_row_buffered"); *fetched_anything = FALSE; DBG_INF_FMT("stmt=%lu", stmt != NULL ? stmt->stmt_id : 0L); /* If we haven't read everything */ - if (set->data_cursor && - (set->data_cursor - set->data) < (set->row_count * field_count)) - { - /* The user could have skipped binding - don't crash*/ - if (stmt->result_bind) { - php_uint_t i; - zval **current_row = set->data_cursor; - - if (NULL == current_row[0]) { - uint64_t row_num = (set->data_cursor - set->data) / field_count; - enum_func_status rc = result->stored_data->m.row_decoder(set->row_buffers[row_num], - current_row, - meta->field_count, - meta->fields, - result->conn->options->int_and_float_native, - result->conn->stats TSRMLS_CC); - if (PASS != rc) { - DBG_RETURN(FAIL); - } - set->initialized_rows++; - if (stmt->update_max_length) { - for (i = 0; i < result->field_count; i++) { - /* - NULL fields are 0 length, 0 is not more than 0 - String of zero size, definitely can't be the next max_length. - Thus for NULL and zero-length we are quite efficient. - */ - if (Z_TYPE_P(current_row[i]) >= IS_STRING) { - php_uint_t len = Z_STRSIZE_P(current_row[i]); - if (meta->fields[i].max_length < len) { - meta->fields[i].max_length = len; + if (result->stored_data->type == MYSQLND_BUFFERED_TYPE_ZVAL) { + MYSQLND_RES_BUFFERED_ZVAL * set = (MYSQLND_RES_BUFFERED_ZVAL *) result->stored_data; + if (set->data_cursor && + (set->data_cursor - set->data) < (result->stored_data->row_count * field_count)) + { + /* The user could have skipped binding - don't crash*/ + if (stmt->result_bind) { - unsigned int i; ++ php_uint_t i; + zval **current_row = set->data_cursor; + + if (NULL == current_row[0]) { + uint64_t row_num = (set->data_cursor - set->data) / field_count; + enum_func_status rc = result->stored_data->m.row_decoder(result->stored_data->row_buffers[row_num], + current_row, + meta->field_count, + meta->fields, + result->conn->options->int_and_float_native, + result->conn->stats TSRMLS_CC); + if (PASS != rc) { + DBG_RETURN(FAIL); + } + result->stored_data->initialized_rows++; + if (stmt->update_max_length) { + for (i = 0; i < result->field_count; i++) { + /* + NULL fields are 0 length, 0 is not more than 0 + String of zero size, definitely can't be the next max_length. + Thus for NULL and zero-length we are quite efficient. + */ + if (Z_TYPE_P(current_row[i]) >= IS_STRING) { - unsigned long len = Z_STRLEN_P(current_row[i]); ++ php_size_t len = Z_STRSIZE_P(current_row[i]); + if (meta->fields[i].max_length < len) { + meta->fields[i].max_length = len; + } } } } diff --cc ext/mysqlnd/mysqlnd_result.c index 78f4010,0112a13..98cba21 --- a/ext/mysqlnd/mysqlnd_result.c +++ b/ext/mysqlnd/mysqlnd_result.c @@@ -32,29 -32,30 +32,30 @@@ #define MYSQLND_SILENT - - /* {{{ mysqlnd_result_buffered::initialize_result_set_rest */ + /* {{{ mysqlnd_result_buffered_zval::initialize_result_set_rest */ static enum_func_status - MYSQLND_METHOD(mysqlnd_result_buffered, initialize_result_set_rest)(MYSQLND_RES_BUFFERED * const result, MYSQLND_RES_METADATA * const meta, - MYSQLND_STATS * stats, zend_bool int_and_float_native TSRMLS_DC) + MYSQLND_METHOD(mysqlnd_result_buffered_zval, initialize_result_set_rest)(MYSQLND_RES_BUFFERED * const result, MYSQLND_RES_METADATA * const meta, + MYSQLND_STATS * stats, zend_bool int_and_float_native TSRMLS_DC) { - unsigned int i; + php_uint_t i; - zval **data_cursor = result->data; - zval **data_begin = result->data; - php_uint_t field_count = meta->field_count; - uint64_t row_count = result->row_count; enum_func_status ret = PASS; - DBG_ENTER("mysqlnd_result_buffered::initialize_result_set_rest"); + const unsigned int field_count = meta->field_count; + const uint64_t row_count = result->row_count; + enum_func_status rc; + + zval **data_begin = ((MYSQLND_RES_BUFFERED_ZVAL *) result)->data; + zval **data_cursor = data_begin; + + DBG_ENTER("mysqlnd_result_buffered_zval::initialize_result_set_rest"); if (!data_cursor || row_count == result->initialized_rows) { DBG_RETURN(ret); } - while ((data_cursor - data_begin) < (int)(row_count * field_count)) { + while ((data_cursor - data_begin) < (ptrdiff_t)(row_count * field_count)) { if (NULL == data_cursor[0]) { - enum_func_status rc = result->m.row_decoder( - result->row_buffers[(data_cursor - data_begin) / field_count], + rc = result->m.row_decoder(result->row_buffers[(data_cursor - data_begin) / field_count], data_cursor, - meta->field_count, + field_count, meta->fields, int_and_float_native, stats TSRMLS_CC); @@@ -84,6 -85,62 +85,62 @@@ /* }}} */ + /* {{{ mysqlnd_result_buffered_c::initialize_result_set_rest */ + static enum_func_status + MYSQLND_METHOD(mysqlnd_result_buffered_c, initialize_result_set_rest)(MYSQLND_RES_BUFFERED * const result, MYSQLND_RES_METADATA * const meta, + MYSQLND_STATS * stats, zend_bool int_and_float_native TSRMLS_DC) + { + unsigned int i; + enum_func_status ret = PASS; + const unsigned int field_count = meta->field_count; + const uint64_t row_count = result->row_count; + enum_func_status rc; + DBG_ENTER("mysqlnd_result_buffered_c::initialize_result_set_rest"); + + if (result->initialized_rows < row_count) { + zend_uchar * initialized = ((MYSQLND_RES_BUFFERED_C *) result)->initialized; + zval ** current_row = mnd_emalloc(field_count * sizeof(zval *)); + + if (!current_row) { + DBG_RETURN(FAIL); + } + + for (i = 0; i < result->row_count; i++) { + /* (i / 8) & the_bit_for_i*/ + if (initialized[i >> 3] & (1 << (i & 7))) { + continue; + } + + rc = result->m.row_decoder(result->row_buffers[i], current_row, field_count, meta->fields, int_and_float_native, stats TSRMLS_CC); + + if (rc != PASS) { + ret = FAIL; + break; + } + result->initialized_rows++; + initialized[i >> 3] |= (1 << (i & 7)); + for (i = 0; i < field_count; i++) { + /* + NULL fields are 0 length, 0 is not more than 0 + String of zero size, definitely can't be the next max_length. + Thus for NULL and zero-length we are quite efficient. + */ + if (Z_TYPE_P(current_row[i]) >= IS_STRING) { - unsigned long len = Z_STRLEN_P(current_row[i]); ++ unsigned long len = Z_STRSIZE_P(current_row[i]); + if (meta->fields[i].max_length < len) { + meta->fields[i].max_length = len; + } + } + zval_ptr_dtor(¤t_row[i]); + } + } + mnd_efree(current_row); + } + DBG_RETURN(ret); + } + /* }}} */ + + /* {{{ mysqlnd_rset_zval_ptr_dtor */ static void mysqlnd_rset_zval_ptr_dtor(zval **zv, enum_mysqlnd_res_type type, zend_bool * copy_ctor_called TSRMLS_DC) @@@ -205,25 -262,23 +262,23 @@@ MYSQLND_METHOD(mysqlnd_result_unbuffere /* }}} */ - /* {{{ mysqlnd_result_buffered::free_result */ + /* {{{ mysqlnd_result_buffered_zval::free_result */ static void - MYSQLND_METHOD(mysqlnd_result_buffered, free_result)(MYSQLND_RES_BUFFERED * const set TSRMLS_DC) + MYSQLND_METHOD(mysqlnd_result_buffered_zval, free_result)(MYSQLND_RES_BUFFERED_ZVAL * const set TSRMLS_DC) { - php_uint_t field_count = set->field_count; - int64_t row; + zval ** data = set->data; - DBG_ENTER("mysqlnd_res::free_buffered_data"); - DBG_INF_FMT("Freeing "MYSQLND_LLU_SPEC" row(s)", set->row_count); + DBG_ENTER("mysqlnd_result_buffered_zval::free_result"); - if (set->data) { + set->data = NULL; /* prevent double free if following loop is interrupted */ + if (data) { - unsigned int copy_on_write_performed = 0; - unsigned int copy_on_write_saved = 0; - unsigned int field_count = set->field_count; + php_uint_t copy_on_write_performed = 0; + php_uint_t copy_on_write_saved = 0; - zval **data = set->data; - set->data = NULL; /* prevent double free if following loop is interrupted */ - ++ php_uint_t field_count = set->field_count; + int64_t row; + for (row = set->row_count - 1; row >= 0; row--) { zval **current_row = data + row * field_count; - MYSQLND_MEMORY_POOL_CHUNK *current_buffer = set->row_buffers[row]; int64_t col; if (current_row != NULL) { @@@ -589,13 -678,10 +678,10 @@@ mysqlnd_query_read_result_set_header(MY of PHP, to be called as separate function. But let's have it for completeness. */ -static unsigned long * +static php_uint_t * - MYSQLND_METHOD(mysqlnd_result_buffered, fetch_lengths)(MYSQLND_RES_BUFFERED * const result TSRMLS_DC) + MYSQLND_METHOD(mysqlnd_result_buffered_zval, fetch_lengths)(MYSQLND_RES_BUFFERED * const result TSRMLS_DC) { - php_uint_t i; - zval **previous_row; - MYSQLND_RES_BUFFERED *set = result; - + const MYSQLND_RES_BUFFERED_ZVAL * set = (MYSQLND_RES_BUFFERED_ZVAL *) result; /* If: - unbuffered result @@@ -767,7 -874,7 +874,7 @@@ MYSQLND_METHOD(mysqlnd_result_unbuffere /* {{{ mysqlnd_result_unbuffered::fetch_row */ static enum_func_status - MYSQLND_METHOD(mysqlnd_result_unbuffered, fetch_row)(MYSQLND_RES * result, void * param, php_uint_t flags, zend_bool * fetched_anything TSRMLS_DC) -MYSQLND_METHOD(mysqlnd_result_unbuffered, fetch_row)(MYSQLND_RES * result, void * param, const unsigned int flags, zend_bool * fetched_anything TSRMLS_DC) ++MYSQLND_METHOD(mysqlnd_result_unbuffered, fetch_row)(MYSQLND_RES * result, void * param, const php_uint_t flags, zend_bool * fetched_anything TSRMLS_DC) { enum_func_status ret; zval *row = (zval *) param; @@@ -941,23 -1048,114 +1048,114 @@@ oom /* {{{ mysqlnd_result_buffered::fetch_row_c */ static enum_func_status -MYSQLND_METHOD(mysqlnd_result_buffered, fetch_row_c)(MYSQLND_RES * result, void * param, unsigned int flags, zend_bool * fetched_anything TSRMLS_DC) +MYSQLND_METHOD(mysqlnd_result_buffered, fetch_row_c)(MYSQLND_RES * result, void * param, php_uint_t flags, zend_bool * fetched_anything TSRMLS_DC) { MYSQLND_ROW_C * row = (MYSQLND_ROW_C *) param; - MYSQLND_RES_BUFFERED * set = result->stored_data; const MYSQLND_RES_METADATA * const meta = result->meta; - unsigned int field_count = meta->field_count; + php_uint_t field_count = meta->field_count; enum_func_status ret = FAIL; - DBG_ENTER("mysqlnd_result_buffered::fetch_row_c"); + if (result->stored_data->type == MYSQLND_BUFFERED_TYPE_ZVAL) { + MYSQLND_RES_BUFFERED_ZVAL * set = (MYSQLND_RES_BUFFERED_ZVAL *) result->stored_data; + + /* If we haven't read everything */ + if (set->data_cursor && + (set->data_cursor - set->data) < (result->stored_data->row_count * field_count)) + { + zval **current_row = set->data_cursor; + unsigned int i; + + if (NULL == current_row[0]) { + uint64_t row_num = (set->data_cursor - set->data) / field_count; + enum_func_status rc = set->m.row_decoder(set->row_buffers[row_num], + current_row, + field_count, + meta->fields, + result->conn->options->int_and_float_native, + result->conn->stats TSRMLS_CC); + if (rc != PASS) { + DBG_RETURN(FAIL); + } + set->initialized_rows++; + for (i = 0; i < field_count; i++) { + /* + NULL fields are 0 length, 0 is not more than 0 + String of zero size, definitely can't be the next max_length. + Thus for NULL and zero-length we are quite efficient. + */ + if (Z_TYPE_P(current_row[i]) >= IS_STRING) { - unsigned long len = Z_STRLEN_P(current_row[i]); ++ unsigned long len = Z_STRSIZE_P(current_row[i]); + if (meta->fields[i].max_length < len) { + meta->fields[i].max_length = len; + } + } + } + } + + /* BEGIN difference between normal normal fetch and _c */ + /* there is no conn handle in this function thus we can't set OOM in error_info */ + *row = mnd_malloc(field_count * sizeof(char *)); + if (*row) { + for (i = 0; i < field_count; i++) { + zval * data = current_row[i]; + - set->lengths[i] = (Z_TYPE_P(data) == IS_NULL)? 0:Z_STRLEN_P(data); ++ set->lengths[i] = (Z_TYPE_P(data) == IS_NULL)? 0:Z_STRSIZE_P(data); + + if (Z_TYPE_P(data) != IS_NULL) { + convert_to_string(data); + (*row)[i] = Z_STRVAL_P(data); + } else { + (*row)[i] = NULL; + } + } + set->data_cursor += field_count; + MYSQLND_INC_GLOBAL_STATISTIC(STAT_ROWS_FETCHED_FROM_CLIENT_NORMAL_BUF); + } else { + SET_OOM_ERROR(*result->conn->error_info); + } + /* END difference between normal normal fetch and _c */ + + *fetched_anything = *row? TRUE:FALSE; + ret = *row? PASS:FAIL; + } else { + set->data_cursor = NULL; + DBG_INF("EOF reached"); + *fetched_anything = FALSE; + ret = PASS; + } + } else if (result->stored_data->type == MYSQLND_BUFFERED_TYPE_C) { + /* + We don't support _C with pdo because it uses the data in a different way - just references it. + We will either leak or give nirvana pointers + */ + *fetched_anything = FALSE; + DBG_RETURN(FAIL); + } + DBG_INF_FMT("ret=PASS fetched=%u", *fetched_anything); + DBG_RETURN(ret); + } + /* }}} */ + + + /* {{{ mysqlnd_result_buffered_zval::fetch_row */ + static enum_func_status + MYSQLND_METHOD(mysqlnd_result_buffered_zval, fetch_row)(MYSQLND_RES * result, void * param, const unsigned int flags, zend_bool * fetched_anything TSRMLS_DC) + { + zval * row = (zval *) param; + const MYSQLND_RES_METADATA * const meta = result->meta; - unsigned int field_count = meta->field_count; ++ php_uint_t field_count = meta->field_count; + enum_func_status ret = FAIL; + MYSQLND_RES_BUFFERED_ZVAL * set = (MYSQLND_RES_BUFFERED_ZVAL *) result->stored_data; + + DBG_ENTER("mysqlnd_result_buffered_zval::fetch_row"); + /* If we haven't read everything */ if (set->data_cursor && (set->data_cursor - set->data) < (set->row_count * field_count)) { - zval **current_row = set->data_cursor; - MYSQLND_FIELD * field = meta->fields; - unsigned int i; + php_uint_t i; + zval **current_row = set->data_cursor; if (NULL == current_row[0]) { uint64_t row_num = (set->data_cursor - set->data) / field_count; @@@ -978,26 -1176,42 +1176,42 @@@ Thus for NULL and zero-length we are quite efficient. */ if (Z_TYPE_P(current_row[i]) >= IS_STRING) { - php_uint_t len = Z_STRSIZE_P(current_row[i]); - if (field->max_length < len) { - field->max_length = len; - unsigned long len = Z_STRLEN_P(current_row[i]); ++ php_size_t len = Z_STRSIZE_P(current_row[i]); + if (meta->fields[i].max_length < len) { + meta->fields[i].max_length = len; } } } } - /* BEGIN difference between normal normal fetch and _c */ - /* there is no conn handle in this function thus we can't set OOM in error_info */ - *row = mnd_malloc(field_count * sizeof(char *)); - if (ret) { - for (i = 0; i < field_count; i++) { - zval * data = current_row[i]; + for (i = 0; i < field_count; i++) { + zval * data = current_row[i]; - if (Z_TYPE_P(data) != IS_NULL) { - convert_to_string(data); - (*row)[i] = Z_STRVAL_P(data); - set->lengths[i] = (Z_TYPE_P(data) == IS_NULL)? 0:Z_STRLEN_P(data); ++ set->lengths[i] = (Z_TYPE_P(data) == IS_NULL)? 0:Z_STRSIZE_P(data); + + if (flags & MYSQLND_FETCH_NUM) { + Z_ADDREF_P(data); + zend_hash_next_index_insert(Z_ARRVAL_P(row), &data, sizeof(zval *), NULL); + } + if (flags & MYSQLND_FETCH_ASSOC) { + /* zend_hash_quick_update needs length + trailing zero */ + /* QQ: Error handling ? */ + /* + zend_hash_quick_update does not check, as add_assoc_zval_ex do, whether + the index is a numeric and convert it to it. This however means constant + hashing of the column name, which is not needed as it can be precomputed. + */ + Z_ADDREF_P(data); + if (meta->zend_hash_keys[i].is_numeric == FALSE) { + zend_hash_quick_update(Z_ARRVAL_P(row), + meta->fields[i].name, + meta->fields[i].name_length + 1, + meta->zend_hash_keys[i].key, + (void *) &data, sizeof(zval *), NULL); } else { - (*row)[i] = NULL; + zend_hash_index_update(Z_ARRVAL_P(row), + meta->zend_hash_keys[i].key, + (void *) &data, sizeof(zval *), NULL); } } } @@@ -1019,38 -1231,45 +1231,45 @@@ /* }}} */ - /* {{{ mysqlnd_result_buffered::fetch_row */ + /* {{{ mysqlnd_result_buffered_c::fetch_row */ static enum_func_status - MYSQLND_METHOD(mysqlnd_result_buffered, fetch_row)(MYSQLND_RES * result, void * param, php_uint_t flags, zend_bool * fetched_anything TSRMLS_DC) -MYSQLND_METHOD(mysqlnd_result_buffered_c, fetch_row)(MYSQLND_RES * result, void * param, const unsigned int flags, zend_bool * fetched_anything TSRMLS_DC) ++MYSQLND_METHOD(mysqlnd_result_buffered_c, fetch_row)(MYSQLND_RES * result, void * param, const php_uint_t flags, zend_bool * fetched_anything TSRMLS_DC) { zval * row = (zval *) param; - MYSQLND_RES_BUFFERED * set = result->stored_data; const MYSQLND_RES_METADATA * const meta = result->meta; - unsigned int field_count = meta->field_count; + php_uint_t field_count = meta->field_count; enum_func_status ret = FAIL; - DBG_ENTER("mysqlnd_result_buffered::fetch_row"); + MYSQLND_RES_BUFFERED_C * set = (MYSQLND_RES_BUFFERED_C *) result->stored_data; + + DBG_ENTER("mysqlnd_result_buffered_c::fetch_row"); /* If we haven't read everything */ - if (set->data_cursor && - (set->data_cursor - set->data) < (set->row_count * field_count)) - { - zval **current_row = set->data_cursor; - MYSQLND_FIELD * field = meta->fields; + if (set->current_row < set->row_count) { + zval **current_row; + enum_func_status rc; - unsigned int i; + php_uint_t i; - if (NULL == current_row[0]) { - uint64_t row_num = (set->data_cursor - set->data) / field_count; - enum_func_status rc = set->m.row_decoder(set->row_buffers[row_num], - current_row, - field_count, - meta->fields, - result->conn->options->int_and_float_native, - result->conn->stats TSRMLS_CC); - if (rc != PASS) { - DBG_RETURN(FAIL); - } + current_row = mnd_emalloc(field_count * sizeof(zval *)); + if (!current_row) { + SET_OOM_ERROR(*result->conn->error_info); + DBG_RETURN(FAIL); + } + + rc = result->stored_data->m.row_decoder(result->stored_data->row_buffers[set->current_row], + current_row, + field_count, + meta->fields, + result->conn->options->int_and_float_native, + result->conn->stats TSRMLS_CC); + if (rc != PASS) { + DBG_RETURN(FAIL); + } + if (!(set->initialized[set->current_row >> 3] & (1 << (set->current_row & 7)))) { + set->initialized[set->current_row >> 3] |= (1 << (set->current_row & 7)); /* mark initialized */ + set->initialized_rows++; + for (i = 0; i < field_count; i++) { /* NULL fields are 0 length, 0 is not more than 0 @@@ -1058,17 -1277,19 +1277,19 @@@ Thus for NULL and zero-length we are quite efficient. */ if (Z_TYPE_P(current_row[i]) >= IS_STRING) { - php_uint_t len = Z_STRSIZE_P(current_row[i]); - if (field->max_length < len) { - field->max_length = len; - unsigned long len = Z_STRLEN_P(current_row[i]); ++ php_size_t len = Z_STRSIZE_P(current_row[i]); + if (meta->fields[i].max_length < len) { + meta->fields[i].max_length = len; } } } } - for (i = 0; i < field_count; i++, field++) { + for (i = 0; i < field_count; i++) { zval * data = current_row[i]; - set->lengths[i] = (Z_TYPE_P(data) == IS_NULL)? 0:Z_STRLEN_P(data); ++ set->lengths[i] = (Z_TYPE_P(data) == IS_NULL)? 0:Z_STRSIZE_P(data); + if (flags & MYSQLND_FETCH_NUM) { Z_ADDREF_P(data); zend_hash_next_index_insert(Z_ARRVAL_P(row), &data, sizeof(zval *), NULL); @@@ -1113,7 -1345,7 +1345,7 @@@ /* {{{ mysqlnd_res::fetch_row */ static enum_func_status - MYSQLND_METHOD(mysqlnd_res, fetch_row)(MYSQLND_RES * result, void * param, php_uint_t flags, zend_bool *fetched_anything TSRMLS_DC) -MYSQLND_METHOD(mysqlnd_res, fetch_row)(MYSQLND_RES * result, void * param, const unsigned int flags, zend_bool *fetched_anything TSRMLS_DC) ++MYSQLND_METHOD(mysqlnd_res, fetch_row)(MYSQLND_RES * result, void * param, const php_uint_t flags, zend_bool *fetched_anything TSRMLS_DC) { const mysqlnd_fetch_row_func f = result->stored_data? result->stored_data->m.fetch_row:(result->unbuf? result->unbuf->m.fetch_row:NULL); if (f) { @@@ -1539,7 -1807,7 +1807,7 @@@ MYSQLND_METHOD(mysqlnd_res, field_tell) /* {{{ mysqlnd_res::fetch_into */ static void - MYSQLND_METHOD(mysqlnd_res, fetch_into)(MYSQLND_RES * result, php_uint_t flags, -MYSQLND_METHOD(mysqlnd_res, fetch_into)(MYSQLND_RES * result, const unsigned int flags, ++MYSQLND_METHOD(mysqlnd_res, fetch_into)(MYSQLND_RES * result, const php_uint_t flags, zval *return_value, enum_mysqlnd_extension extension TSRMLS_DC ZEND_FILE_LINE_DC) { @@@ -1600,10 -1868,10 +1868,10 @@@ MYSQLND_METHOD(mysqlnd_res, fetch_row_c /* {{{ mysqlnd_res::fetch_all */ static void - MYSQLND_METHOD(mysqlnd_res, fetch_all)(MYSQLND_RES * result, php_uint_t flags, zval *return_value TSRMLS_DC ZEND_FILE_LINE_DC) -MYSQLND_METHOD(mysqlnd_res, fetch_all)(MYSQLND_RES * result, const unsigned int flags, zval *return_value TSRMLS_DC ZEND_FILE_LINE_DC) ++MYSQLND_METHOD(mysqlnd_res, fetch_all)(MYSQLND_RES * result, const php_uint_t flags, zval *return_value TSRMLS_DC ZEND_FILE_LINE_DC) { zval *row; - ulong i = 0; + php_uint_t i = 0; MYSQLND_RES_BUFFERED *set = result->stored_data; DBG_ENTER("mysqlnd_res::fetch_all"); @@@ -1786,14 -2054,14 +2054,14 @@@ mysqlnd_result_unbuffered_init(php_uint /* }}} */ - /* {{{ mysqlnd_result_buffered_init */ - PHPAPI MYSQLND_RES_BUFFERED * - mysqlnd_result_buffered_init(php_uint_t field_count, zend_bool ps, zend_bool persistent TSRMLS_DC) + /* {{{ mysqlnd_result_buffered_zval_init */ + PHPAPI MYSQLND_RES_BUFFERED_ZVAL * -mysqlnd_result_buffered_zval_init(unsigned int field_count, zend_bool ps, zend_bool persistent TSRMLS_DC) ++mysqlnd_result_buffered_zval_init(php_uint_t field_count, zend_bool ps, zend_bool persistent TSRMLS_DC) { - size_t alloc_size = sizeof(MYSQLND_RES_BUFFERED) + mysqlnd_plugin_count() * sizeof(void *); - MYSQLND_RES_BUFFERED * ret = mnd_pecalloc(1, alloc_size, persistent); + size_t alloc_size = sizeof(MYSQLND_RES_BUFFERED_ZVAL) + mysqlnd_plugin_count() * sizeof(void *); + MYSQLND_RES_BUFFERED_ZVAL * ret = mnd_pecalloc(1, alloc_size, persistent); - DBG_ENTER("mysqlnd_result_buffered_init"); + DBG_ENTER("mysqlnd_result_buffered_zval_init"); if (!ret) { DBG_RETURN(NULL); @@@ -1812,6 -2080,50 +2080,50 @@@ ret->field_count= field_count; ret->ps = ps; ret->m = *mysqlnd_result_buffered_get_methods(); + ret->type = MYSQLND_BUFFERED_TYPE_ZVAL; + + if (ps) { + ret->m.fetch_lengths = NULL; /* makes no sense */ + ret->m.row_decoder = php_mysqlnd_rowp_read_binary_protocol; + } else { + ret->m.row_decoder = php_mysqlnd_rowp_read_text_protocol_zval; + } + ret->m.fetch_row = MYSQLND_METHOD(mysqlnd_result_buffered_zval, fetch_row); + ret->m.fetch_lengths = MYSQLND_METHOD(mysqlnd_result_buffered_zval, fetch_lengths); + ret->m.data_seek = MYSQLND_METHOD(mysqlnd_result_buffered_zval, data_seek); + ret->m.initialize_result_set_rest = MYSQLND_METHOD(mysqlnd_result_buffered_zval, initialize_result_set_rest); + DBG_RETURN(ret); + } + /* }}} */ + + + /* {{{ mysqlnd_result_buffered_c_init */ + PHPAPI MYSQLND_RES_BUFFERED_C * -mysqlnd_result_buffered_c_init(unsigned int field_count, zend_bool ps, zend_bool persistent TSRMLS_DC) ++mysqlnd_result_buffered_c_init(php_uint_t field_count, zend_bool ps, zend_bool persistent TSRMLS_DC) + { + size_t alloc_size = sizeof(MYSQLND_RES_BUFFERED_C) + mysqlnd_plugin_count() * sizeof(void *); + MYSQLND_RES_BUFFERED_C * ret = mnd_pecalloc(1, alloc_size, persistent); + + DBG_ENTER("mysqlnd_result_buffered_c_init"); + + if (!ret) { + DBG_RETURN(NULL); + } - if (!(ret->lengths = mnd_pecalloc(field_count, sizeof(unsigned long), persistent))) { ++ if (!(ret->lengths = mnd_pecalloc(field_count, sizeof(php_uint_t), persistent))) { + mnd_pefree(ret, persistent); + DBG_RETURN(NULL); + } + if (!(ret->result_set_memory_pool = mysqlnd_mempool_create(MYSQLND_G(mempool_default_size) TSRMLS_CC))) { + mnd_efree(ret->lengths); + mnd_pefree(ret, persistent); + DBG_RETURN(NULL); + } + + ret->persistent = persistent; + ret->field_count= field_count; + ret->ps = ps; + ret->m = *mysqlnd_result_buffered_get_methods(); + ret->type = MYSQLND_BUFFERED_TYPE_C; if (ps) { ret->m.fetch_lengths = NULL; /* makes no sense */ diff --cc ext/mysqlnd/mysqlnd_result.h index 09e0f81,f7e22a1..9c536e5 --- a/ext/mysqlnd/mysqlnd_result.h +++ b/ext/mysqlnd/mysqlnd_result.h @@@ -23,9 -23,10 +23,10 @@@ #ifndef MYSQLND_RESULT_H #define MYSQLND_RESULT_H -PHPAPI MYSQLND_RES * mysqlnd_result_init(unsigned int field_count, zend_bool persistent TSRMLS_DC); -PHPAPI MYSQLND_RES_UNBUFFERED * mysqlnd_result_unbuffered_init(unsigned int field_count, zend_bool ps, zend_bool persistent TSRMLS_DC); -PHPAPI MYSQLND_RES_BUFFERED_ZVAL * mysqlnd_result_buffered_zval_init(unsigned int field_count, zend_bool ps, zend_bool persistent TSRMLS_DC); -PHPAPI MYSQLND_RES_BUFFERED_C * mysqlnd_result_buffered_c_init(unsigned int field_count, zend_bool ps, zend_bool persistent TSRMLS_DC); +PHPAPI MYSQLND_RES * mysqlnd_result_init(php_uint_t field_count, zend_bool persistent TSRMLS_DC); +PHPAPI MYSQLND_RES_UNBUFFERED * mysqlnd_result_unbuffered_init(php_uint_t field_count, zend_bool ps, zend_bool persistent TSRMLS_DC); - PHPAPI MYSQLND_RES_BUFFERED * mysqlnd_result_buffered_init(php_uint_t field_count, zend_bool ps, zend_bool persistent TSRMLS_DC); ++PHPAPI MYSQLND_RES_BUFFERED_ZVAL * mysqlnd_result_buffered_zval_init(php_uint_t field_count, zend_bool ps, zend_bool persistent TSRMLS_DC); ++PHPAPI MYSQLND_RES_BUFFERED_C * mysqlnd_result_buffered_c_init(php_uint_t field_count, zend_bool ps, zend_bool persistent TSRMLS_DC); enum_func_status mysqlnd_query_read_result_set_header(MYSQLND_CONN_DATA * conn, MYSQLND_STMT * stmt TSRMLS_DC); diff --cc ext/mysqlnd/mysqlnd_structs.h index 3b653e5,66920e4..a21e71d --- a/ext/mysqlnd/mysqlnd_structs.h +++ b/ext/mysqlnd/mysqlnd_structs.h @@@ -244,7 -246,7 +246,7 @@@ typedef struct st_mysqlnd_debug MYSQLND typedef MYSQLND_RES* (*mysqlnd_stmt_use_or_store_func)(MYSQLND_STMT * const TSRMLS_DC); typedef enum_func_status (*mysqlnd_fetch_row_func)(MYSQLND_RES *result, void * param, - php_uint_t flags, - const unsigned int flags, ++ const php_uint_t flags, zend_bool * fetched_anything TSRMLS_DC); @@@ -614,13 -624,13 +624,13 @@@ typedef enum_func_status (*func_mysqlnd typedef MYSQLND_RES * (*func_mysqlnd_res__use_result)(MYSQLND_RES * const result, zend_bool ps_protocol TSRMLS_DC); -typedef MYSQLND_RES * (*func_mysqlnd_res__store_result)(MYSQLND_RES * result, MYSQLND_CONN_DATA * const conn, const unsigned int flags TSRMLS_DC); -typedef void (*func_mysqlnd_res__fetch_into)(MYSQLND_RES *result, const unsigned int flags, zval *return_value, enum_mysqlnd_extension ext TSRMLS_DC ZEND_FILE_LINE_DC); +typedef MYSQLND_RES * (*func_mysqlnd_res__store_result)(MYSQLND_RES * result, MYSQLND_CONN_DATA * const conn, const php_uint_t flags TSRMLS_DC); - typedef void (*func_mysqlnd_res__fetch_into)(MYSQLND_RES *result, php_uint_t flags, zval *return_value, enum_mysqlnd_extension ext TSRMLS_DC ZEND_FILE_LINE_DC); ++typedef void (*func_mysqlnd_res__fetch_into)(MYSQLND_RES *result, const php_uint_t flags, zval *return_value, enum_mysqlnd_extension ext TSRMLS_DC ZEND_FILE_LINE_DC); typedef MYSQLND_ROW_C (*func_mysqlnd_res__fetch_row_c)(MYSQLND_RES *result TSRMLS_DC); - typedef void (*func_mysqlnd_res__fetch_all)(MYSQLND_RES *result, php_uint_t flags, zval *return_value TSRMLS_DC ZEND_FILE_LINE_DC); -typedef void (*func_mysqlnd_res__fetch_all)(MYSQLND_RES *result, const unsigned int flags, zval *return_value TSRMLS_DC ZEND_FILE_LINE_DC); -typedef void (*func_mysqlnd_res__fetch_field_data)(MYSQLND_RES *result, unsigned int offset, zval *return_value TSRMLS_DC); ++typedef void (*func_mysqlnd_res__fetch_all)(MYSQLND_RES *result, const php_uint_t flags, zval *return_value TSRMLS_DC ZEND_FILE_LINE_DC); +typedef void (*func_mysqlnd_res__fetch_field_data)(MYSQLND_RES *result, php_uint_t offset, zval *return_value TSRMLS_DC); typedef uint64_t (*func_mysqlnd_res__num_rows)(const MYSQLND_RES * const result TSRMLS_DC); -typedef unsigned int (*func_mysqlnd_res__num_fields)(const MYSQLND_RES * const result TSRMLS_DC); +typedef php_uint_t (*func_mysqlnd_res__num_fields)(const MYSQLND_RES * const result TSRMLS_DC); typedef enum_func_status (*func_mysqlnd_res__skip_result)(MYSQLND_RES * const result TSRMLS_DC); typedef enum_func_status (*func_mysqlnd_res__seek_data)(MYSQLND_RES * const result, const uint64_t row TSRMLS_DC); typedef MYSQLND_FIELD_OFFSET (*func_mysqlnd_res__seek_field)(MYSQLND_RES * const result, const MYSQLND_FIELD_OFFSET field_offset TSRMLS_DC); @@@ -630,8 -640,8 +640,8 @@@ typedef const MYSQLND_FIELD *(*func_mys typedef const MYSQLND_FIELD *(*func_mysqlnd_res__fetch_fields)(MYSQLND_RES * const result TSRMLS_DC); typedef enum_func_status (*func_mysqlnd_res__read_result_metadata)(MYSQLND_RES * result, MYSQLND_CONN_DATA * conn TSRMLS_DC); -typedef unsigned long * (*func_mysqlnd_res__fetch_lengths)(MYSQLND_RES * const result TSRMLS_DC); +typedef php_uint_t * (*func_mysqlnd_res__fetch_lengths)(MYSQLND_RES * const result TSRMLS_DC); - typedef enum_func_status (*func_mysqlnd_res__store_result_fetch_data)(MYSQLND_CONN_DATA * const conn, MYSQLND_RES * result, MYSQLND_RES_METADATA *meta, zend_bool binary_protocol TSRMLS_DC); + typedef enum_func_status (*func_mysqlnd_res__store_result_fetch_data)(MYSQLND_CONN_DATA * const conn, MYSQLND_RES * result, MYSQLND_RES_METADATA * meta, MYSQLND_MEMORY_POOL_CHUNK *** row_buffers, zend_bool binary_protocol TSRMLS_DC); typedef void (*func_mysqlnd_res__free_result_buffers)(MYSQLND_RES * result TSRMLS_DC); /* private */ typedef enum_func_status (*func_mysqlnd_res__free_result)(MYSQLND_RES * result, zend_bool implicit TSRMLS_DC); @@@ -942,14 -952,11 +952,11 @@@ struct st_mysqlnd_connection_dat The result set objects can determine by inspecting 'quit_sent' whether the connection is still valid. */ - unsigned int refcount; + php_uint_t refcount; /* Temporal storage for mysql_query */ - unsigned int field_count; + php_uint_t field_count; - /* persistent connection */ - zend_bool persistent; - /* options */ MYSQLND_OPTIONS * options; MYSQLND_OPTIONS options_impl; @@@ -991,31 -1003,51 +1003,50 @@@ struct st_mysqlnd_result_metadat }; - struct st_mysqlnd_buffered_result - { - zval **data; - zval **data_cursor; - MYSQLND_MEMORY_POOL_CHUNK **row_buffers; - uint64_t row_count; - uint64_t initialized_rows; + #define def_mysqlnd_buffered_result_parent \ + MYSQLND_MEMORY_POOL_CHUNK **row_buffers; \ + uint64_t row_count; \ + uint64_t initialized_rows; \ + \ + /* Column lengths of current row - both buffered and unbuffered. For buffered results it duplicates the data found in **data */ \ + unsigned long *lengths; \ + \ + MYSQLND_MEMORY_POOL *result_set_memory_pool; \ + \ + unsigned int references; \ + \ + MYSQLND_ERROR_INFO error_info; \ + \ + unsigned int field_count; \ + zend_bool ps; \ + zend_bool persistent; \ + struct st_mysqlnd_result_buffered_methods m; \ + enum mysqlnd_buffered_type type; \ + void * unused1; \ + void * unused2; \ + void * unused3 - /* - Column lengths of current row - both buffered and unbuffered. - For buffered results it duplicates the data found in **data - */ - php_uint_t *lengths; + + struct st_mysqlnd_buffered_result_parent + { + def_mysqlnd_buffered_result_parent; + }; - MYSQLND_MEMORY_POOL *result_set_memory_pool; - + struct st_mysqlnd_buffered_result_zval + { + def_mysqlnd_buffered_result_parent; - php_uint_t references; + zval **data; + zval **data_cursor; + }; - MYSQLND_ERROR_INFO error_info; - php_uint_t field_count; - zend_bool ps; - zend_bool persistent; + struct st_mysqlnd_buffered_result_c + { + def_mysqlnd_buffered_result_parent; - struct st_mysqlnd_result_buffered_methods m; + zend_uchar *initialized; /* every row is a single bit */ + uint64_t current_row; }; diff --cc ext/mysqlnd/mysqlnd_wireprotocol.c index fe821e9,ecce71d..375fa09 --- a/ext/mysqlnd/mysqlnd_wireprotocol.c +++ b/ext/mysqlnd/mysqlnd_wireprotocol.c @@@ -1572,14 -1572,14 +1572,14 @@@ php_mysqlnd_rowp_read_binary_protocol(M } /* }}} */ - /* {{{ php_mysqlnd_rowp_read_text_protocol */ enum_func_status - php_mysqlnd_rowp_read_text_protocol(MYSQLND_MEMORY_POOL_CHUNK * row_buffer, zval ** fields, + php_mysqlnd_rowp_read_text_protocol_aux(MYSQLND_MEMORY_POOL_CHUNK * row_buffer, zval ** fields, - unsigned int field_count, const MYSQLND_FIELD * fields_metadata, + php_uint_t field_count, const MYSQLND_FIELD * fields_metadata, - zend_bool as_int_or_float, MYSQLND_STATS * stats TSRMLS_DC) + zend_bool as_int_or_float, zend_bool copy_data, MYSQLND_STATS * stats TSRMLS_DC) { + - unsigned int i; + php_uint_t i; zend_bool last_field_was_string = FALSE; zval **current_field, **end_field, **start_field; zend_uchar * p = row_buffer->ptr; @@@ -1606,9 -1606,9 +1606,9 @@@ /* Don't reverse the order. It is significant!*/ zend_uchar *this_field_len_pos = p; /* php_mysqlnd_net_field_length() call should be after *this_field_len_pos = p; */ - unsigned long len = php_mysqlnd_net_field_length(&p); + php_uint_t len = php_mysqlnd_net_field_length(&p); - if (current_field > start_field && last_field_was_string) { + if (copy_data == FALSE && current_field > start_field && last_field_was_string) { /* Normal queries: We have to put \0 now to the end of the previous field, if it was @@@ -1731,18 -1731,18 +1731,18 @@@ later in this function there will be an advancement. */ p -= len; - if (Z_TYPE_PP(current_field) == IS_LONG) { - bit_area += 1 + sprintf((char *)start, "%ld", Z_LVAL_PP(current_field)); + if (Z_TYPE_PP(current_field) == IS_INT) { + bit_area += 1 + sprintf((char *)start, ZEND_INT_FMT, Z_IVAL_PP(current_field)); - ZVAL_STRINGL(*current_field, (char *) start, bit_area - start - 1, 0); + ZVAL_STRINGL(*current_field, (char *) start, bit_area - start - 1, copy_data); } else if (Z_TYPE_PP(current_field) == IS_STRING){ - memcpy(bit_area, Z_STRVAL_PP(current_field), Z_STRLEN_PP(current_field)); - bit_area += Z_STRLEN_PP(current_field); + memcpy(bit_area, Z_STRVAL_PP(current_field), Z_STRSIZE_PP(current_field)); + bit_area += Z_STRSIZE_PP(current_field); *bit_area++ = '\0'; zval_dtor(*current_field); - ZVAL_STRINGL(*current_field, (char *) start, bit_area - start - 1, 0); + ZVAL_STRINGL(*current_field, (char *) start, bit_area - start - 1, copy_data); } } else { - ZVAL_STRINGL(*current_field, (char *)p, len, 0); + ZVAL_STRINGL(*current_field, (char *)p, len, copy_data); } p += len; last_field_was_string = TRUE; diff --cc ext/mysqlnd/mysqlnd_wireprotocol.h index 43aff57,7e8b962..f658b25 --- a/ext/mysqlnd/mysqlnd_wireprotocol.h +++ b/ext/mysqlnd/mysqlnd_wireprotocol.h @@@ -312,8 -312,12 +312,12 @@@ enum_func_status php_mysqlnd_rowp_read_ zend_bool as_int_or_float, MYSQLND_STATS * stats TSRMLS_DC); - enum_func_status php_mysqlnd_rowp_read_text_protocol(MYSQLND_MEMORY_POOL_CHUNK * row_buffer, zval ** fields, + enum_func_status php_mysqlnd_rowp_read_text_protocol_zval(MYSQLND_MEMORY_POOL_CHUNK * row_buffer, zval ** fields, - unsigned int field_count, const MYSQLND_FIELD * fields_metadata, ++ php_uint_t field_count, const MYSQLND_FIELD * fields_metadata, + zend_bool as_int_or_float, MYSQLND_STATS * stats TSRMLS_DC); + + enum_func_status php_mysqlnd_rowp_read_text_protocol_c(MYSQLND_MEMORY_POOL_CHUNK * row_buffer, zval ** fields, - unsigned int field_count, const MYSQLND_FIELD * fields_metadata, + php_uint_t field_count, const MYSQLND_FIELD * fields_metadata, zend_bool as_int_or_float, MYSQLND_STATS * stats TSRMLS_DC); diff --cc ext/opcache/zend_accelerator_util_funcs.c index 8de2426,ae33e76..d17bc99 --- a/ext/opcache/zend_accelerator_util_funcs.c +++ b/ext/opcache/zend_accelerator_util_funcs.c @@@ -237,11 -237,13 +237,13 @@@ static zend_ast *zend_ast_clone(zend_as if ((Z_TYPE_P(ast->u.val) & IS_CONSTANT_TYPE_MASK) >= IS_ARRAY) { switch ((Z_TYPE_P(ast->u.val) & IS_CONSTANT_TYPE_MASK)) { case IS_STRING: - case IS_CONSTANT: + case IS_CONSTANT: - Z_STRVAL_P(node->u.val) = (char *) interned_estrndup(Z_STRVAL_P(ast->u.val), Z_STRLEN_P(ast->u.val)); + Z_STRVAL_P(node->u.val) = (char *) interned_estrndup(Z_STRVAL_P(ast->u.val), Z_STRSIZE_P(ast->u.val)); break; case IS_ARRAY: - case IS_CONSTANT_ARRAY: + #if ZEND_EXTENSION_API_NO <= PHP_5_5_API_NO + case IS_CONSTANT_ARRAY: + #endif if (ast->u.val->value.ht && ast->u.val->value.ht != &EG(symbol_table)) { ALLOC_HASHTABLE(node->u.val->value.ht); zend_hash_clone_zval(node->u.val->value.ht, ast->u.val->value.ht, 0); @@@ -295,11 -297,13 +297,13 @@@ static inline zval* zend_clone_zval(zva switch ((Z_TYPE_P(ret) & ~IS_CONSTANT_INDEX)) { #endif case IS_STRING: - case IS_CONSTANT: + case IS_CONSTANT: - Z_STRVAL_P(ret) = (char *) interned_estrndup(Z_STRVAL_P(ret), Z_STRLEN_P(ret)); + Z_STRVAL_P(ret) = (char *) interned_estrndup(Z_STRVAL_P(ret), Z_STRSIZE_P(ret)); break; case IS_ARRAY: - case IS_CONSTANT_ARRAY: + #if ZEND_EXTENSION_API_NO <= PHP_5_5_API_NO + case IS_CONSTANT_ARRAY: + #endif if (ret->value.ht && ret->value.ht != &EG(symbol_table)) { ALLOC_HASHTABLE(ret->value.ht); zend_hash_clone_zval(ret->value.ht, src->value.ht, 0); @@@ -417,11 -421,13 +421,13 @@@ static void zend_hash_clone_zval(HashTa switch ((Z_TYPE_P((zval*)p->pDataPtr) & ~IS_CONSTANT_INDEX)) { #endif case IS_STRING: - case IS_CONSTANT: + case IS_CONSTANT: - Z_STRVAL_P(ppz) = (char *) interned_estrndup(Z_STRVAL_P((zval*)p->pDataPtr), Z_STRLEN_P((zval*)p->pDataPtr)); + Z_STRVAL_P(ppz) = (char *) interned_estrndup(Z_STRVAL_P((zval*)p->pDataPtr), Z_STRSIZE_P((zval*)p->pDataPtr)); break; case IS_ARRAY: - case IS_CONSTANT_ARRAY: + #if ZEND_EXTENSION_API_NO <= PHP_5_5_API_NO + case IS_CONSTANT_ARRAY: + #endif if (((zval*)p->pDataPtr)->value.ht && ((zval*)p->pDataPtr)->value.ht != &EG(symbol_table)) { ALLOC_HASHTABLE(ppz->value.ht); zend_hash_clone_zval(ppz->value.ht, ((zval*)p->pDataPtr)->value.ht, 0); diff --cc ext/opcache/zend_persist_calc.c index 8d42b1d,a01d834..95da751 --- a/ext/opcache/zend_persist_calc.c +++ b/ext/opcache/zend_persist_calc.c @@@ -126,10 -126,12 +126,12 @@@ static uint zend_persist_zval_calc(zva #endif case IS_STRING: case IS_CONSTANT: - ADD_INTERNED_STRING(Z_STRVAL_P(z), Z_STRLEN_P(z) + 1); + ADD_INTERNED_STRING(Z_STRVAL_P(z), Z_STRSIZE_P(z) + 1); break; case IS_ARRAY: + #if ZEND_EXTENSION_API_NO <= PHP_5_5_API_NO case IS_CONSTANT_ARRAY: + #endif ADD_DUP_SIZE(z->value.ht, sizeof(HashTable)); ADD_SIZE(zend_hash_persist_calc(z->value.ht, (int (*)(void* TSRMLS_DC)) zend_persist_zval_ptr_calc, sizeof(zval**) TSRMLS_CC)); break; diff --cc ext/phar/phar_object.c index 17d51e9,407edda..77ba903 --- a/ext/phar/phar_object.c +++ b/ext/phar/phar_object.c @@@ -1939,13 -1934,15 +1939,15 @@@ PHP_METHOD(Phar, buildFromIterator */ PHP_METHOD(Phar, count) { + /* mode can be ignored, maximum depth is 1 */ + long mode; PHAR_ARCHIVE_OBJECT(); - if (zend_parse_parameters_none() == FAILURE) { - return; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &mode) == FAILURE) { + RETURN_FALSE; } - RETURN_LONG(zend_hash_num_elements(&phar_obj->arc.archive->manifest)); + RETURN_INT(zend_hash_num_elements(&phar_obj->arc.archive->manifest)); } /* }}} */ diff --cc ext/reflection/php_reflection.c index 3110145,703e141..ac6f1e9 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@@ -733,9 -733,9 +733,9 @@@ static void _parameter_string(string *s *zv = *precv->op2.zv; zval_copy_ctor(zv); INIT_PZVAL(zv); - zval_update_constant_ex(&zv, (void*)1, fptr->common.scope TSRMLS_CC); + zval_update_constant_ex(&zv, 1, fptr->common.scope TSRMLS_CC); if (Z_TYPE_P(zv) == IS_BOOL) { - if (Z_LVAL_P(zv)) { + if (Z_IVAL_P(zv)) { string_write(str, "true", sizeof("true")-1); } else { string_write(str, "false", sizeof("false")-1); diff --cc ext/spl/spl_observer.c index 5f1f740,91830ab..f7951b9 --- a/ext/spl/spl_observer.c +++ b/ext/spl/spl_observer.c @@@ -623,12 -622,28 +624,28 @@@ SPL_METHOD(SplObjectStorage, contains SPL_METHOD(SplObjectStorage, count) { spl_SplObjectStorage *intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC); - - if (zend_parse_parameters_none() == FAILURE) { - long mode = COUNT_NORMAL; ++ php_int_t mode = COUNT_NORMAL; + - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &mode) == FAILURE) { ++ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|i", &mode) == FAILURE) { return; } - + + if (mode == COUNT_RECURSIVE) { - long ret = zend_hash_num_elements(&intern->storage); ++ php_int_t ret = zend_hash_num_elements(&intern->storage); + HashPosition position; + zval *element; + + for (zend_hash_internal_pointer_reset_ex(&intern->storage, &position); + zend_hash_get_current_data_ex(&intern->storage, (void**) &element, &position) == SUCCESS; + zend_hash_move_forward_ex(&intern->storage, &position)) { + ret += php_count_recursive(element, mode TSRMLS_CC); + } + - RETURN_LONG(ret); ++ RETURN_INT(ret); + return; + } + - RETURN_LONG(zend_hash_num_elements(&intern->storage)); + RETURN_INT(zend_hash_num_elements(&intern->storage)); } /* }}} */ /* {{{ proto void SplObjectStorage::rewind() diff --cc ext/standard/array.c index 646d122,4f98331..357b905 --- a/ext/standard/array.c +++ b/ext/standard/array.c @@@ -274,9 -271,9 +271,9 @@@ PHP_FUNCTION(ksort } /* }}} */ - static php_int_t php_count_recursive(zval *array, php_int_t mode TSRMLS_DC) /* {{{ */ -PHPAPI int php_count_recursive(zval *array, long mode TSRMLS_DC) /* {{{ */ ++PHPAPI php_int_t php_count_recursive(zval *array, php_int_t mode TSRMLS_DC) /* {{{ */ { - long cnt = 0; + php_int_t cnt = 0; zval **element; if (Z_TYPE_P(array) == IS_ARRAY) { @@@ -336,12 -333,17 +333,17 @@@ PHP_FUNCTION(count #ifdef HAVE_SPL /* if not and the object implements Countable we call its count() method */ if (Z_OBJ_HT_P(array)->get_class_entry && instanceof_function(Z_OBJCE_P(array), spl_ce_Countable TSRMLS_CC)) { - zend_call_method_with_0_params(&array, NULL, NULL, "count", &retval); + zval *mode_zv; + MAKE_STD_ZVAL(mode_zv); - ZVAL_LONG(mode_zv, mode); ++ ZVAL_INT(mode_zv, mode); + zend_call_method_with_1_params(&array, NULL, NULL, "count", &retval, mode_zv); if (retval) { - convert_to_long_ex(&retval); - RETVAL_LONG(Z_LVAL_P(retval)); + convert_to_int_ex(&retval); + RETVAL_INT(Z_IVAL_P(retval)); zval_ptr_dtor(&retval); } + zval_dtor(mode_zv); + efree(mode_zv); return; } #endif
diff --cc Zend/zend_compile.c index 5686c21,beb5340..ef88eb3 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@@ -3461,9 -3461,9 +3461,9 @@@ static char * zend_get_function_declara *zv = *precv->op2.zv; zval_copy_ctor(zv); INIT_PZVAL(zv); - zval_update_constant_ex(&zv, (void*)1, fptr->common.scope TSRMLS_CC); + zval_update_constant_ex(&zv, 1, fptr->common.scope TSRMLS_CC); if (Z_TYPE_P(zv) == IS_BOOL) { - if (Z_LVAL_P(zv)) { + if (Z_IVAL_P(zv)) { memcpy(offset, "true", 4); offset += 4; } else { @@@ -5440,12 -5440,8 +5440,8 @@@ void zend_do_declare_class_constant(zno { zval *property; const char *cname = NULL; - zend_ulong hash; + zend_uint_t hash; - if(Z_TYPE(value->u.constant) == IS_CONSTANT_ARRAY) { - zend_error_noreturn(E_COMPILE_ERROR, "Arrays are not allowed in class constants"); - return; - } if ((CG(active_class_entry)->ce_flags & ZEND_ACC_TRAIT) == ZEND_ACC_TRAIT) { zend_error_noreturn(E_COMPILE_ERROR, "Traits cannot have constants"); return; @@@ -5887,52 -5883,25 +5883,25 @@@ void zend_do_add_array_element(znode *r } /* }}} */ - void zend_do_add_static_array_element(znode *result, znode *offset, const znode *expr) /* {{{ */ + void zend_do_add_static_array_element(zval *result, zval *offset, const zval *expr) /* {{{ */ { - zval *element; - - ALLOC_ZVAL(element); - *element = expr->u.constant; if (offset) { - switch (Z_TYPE(offset->u.constant) & IS_CONSTANT_TYPE_MASK) { - case IS_CONSTANT: - /* Ugly hack to denote that this value has a constant index */ - Z_TYPE_P(element) |= IS_CONSTANT_INDEX; - Z_STRVAL(offset->u.constant) = erealloc(Z_STRVAL(offset->u.constant), Z_STRSIZE(offset->u.constant)+3); - Z_STRVAL(offset->u.constant)[Z_STRSIZE(offset->u.constant)+1] = Z_TYPE(offset->u.constant); - Z_STRVAL(offset->u.constant)[Z_STRSIZE(offset->u.constant)+2] = 0; - zend_symtable_update(Z_ARRVAL(result->u.constant), Z_STRVAL(offset->u.constant), Z_STRSIZE(offset->u.constant)+3, &element, sizeof(zval *), NULL); - zval_dtor(&offset->u.constant); - break; - case IS_CONSTANT_AST: { - /* Another ugly hack to store the data about the AST in the array */ - char* key; - int len = sizeof(zend_ast *); - Z_TYPE_P(element) |= IS_CONSTANT_INDEX; - - key = emalloc(len + 2); - *(zend_ast **)key = Z_AST(offset->u.constant); - key[len] = Z_TYPE(offset->u.constant); - key[len + 1] = 0; - zend_symtable_update(Z_ARRVAL(result->u.constant), key, len + 2, &element, sizeof(zval *), NULL); - efree(key); - break; - } + switch (Z_TYPE_P(offset)) { case IS_STRING: - zend_symtable_update(Z_ARRVAL(result->u.constant), Z_STRVAL(offset->u.constant), Z_STRSIZE(offset->u.constant)+1, &element, sizeof(zval *), NULL); - zval_dtor(&offset->u.constant); - zend_symtable_update(Z_ARRVAL_P(result), Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, &expr, sizeof(zval *), NULL); ++ zend_symtable_update(Z_ARRVAL_P(result), Z_STRVAL_P(offset), Z_STRSIZE_P(offset)+1, &expr, sizeof(zval *), NULL); + zval_dtor(offset); break; case IS_NULL: - zend_symtable_update(Z_ARRVAL(result->u.constant), "", 1, &element, sizeof(zval *), NULL); + zend_symtable_update(Z_ARRVAL_P(result), "", 1, &expr, sizeof(zval *), NULL); break; - case IS_LONG: + case IS_INT: case IS_BOOL: - zend_hash_index_update(Z_ARRVAL(result->u.constant), Z_IVAL(offset->u.constant), &element, sizeof(zval *), NULL); - zend_hash_index_update(Z_ARRVAL_P(result), Z_LVAL_P(offset), &expr, sizeof(zval *), NULL); ++ zend_hash_index_update(Z_ARRVAL_P(result), Z_IVAL_P(offset), &expr, sizeof(zval *), NULL); break; case IS_DOUBLE: - zend_hash_index_update(Z_ARRVAL(result->u.constant), zend_dval_to_ival(Z_DVAL(offset->u.constant)), &element, sizeof(zval *), NULL); - zend_hash_index_update(Z_ARRVAL_P(result), zend_dval_to_lval(Z_DVAL_P(offset)), &expr, sizeof(zval *), NULL); ++ zend_hash_index_update(Z_ARRVAL_P(result), zend_dval_to_ival(Z_DVAL_P(offset)), &expr, sizeof(zval *), NULL); break; - case IS_CONSTANT_ARRAY: + case IS_ARRAY: zend_error(E_ERROR, "Illegal offset type"); break; } diff --cc Zend/zend_execute.h index 08af239,9bde312..0b81399 --- a/Zend/zend_execute.h +++ b/Zend/zend_execute.h @@@ -352,16 -352,18 +352,18 @@@ void execute_new_code(TSRMLS_D) ZEND_API const char *get_active_class_name(const char **space TSRMLS_DC); ZEND_API const char *get_active_function_name(TSRMLS_D); ZEND_API const char *zend_get_executed_filename(TSRMLS_D); -ZEND_API uint zend_get_executed_lineno(TSRMLS_D); +ZEND_API zend_size_t zend_get_executed_lineno(TSRMLS_D); ZEND_API zend_bool zend_is_executing(TSRMLS_D); -ZEND_API void zend_set_timeout(long seconds, int reset_signals); +ZEND_API void zend_set_timeout(zend_int_t seconds, int reset_signals); ZEND_API void zend_unset_timeout(TSRMLS_D); ZEND_API void zend_timeout(int dummy); -ZEND_API zend_class_entry *zend_fetch_class(const char *class_name, uint class_name_len, int fetch_type TSRMLS_DC); -ZEND_API zend_class_entry *zend_fetch_class_by_name(const char *class_name, uint class_name_len, const zend_literal *key, int fetch_type TSRMLS_DC); +ZEND_API zend_class_entry *zend_fetch_class(const char *class_name, zend_size_t class_name_len, int fetch_type TSRMLS_DC); +ZEND_API zend_class_entry *zend_fetch_class_by_name(const char *class_name, zend_size_t class_name_len, const zend_literal *key, int fetch_type TSRMLS_DC); void zend_verify_abstract_class(zend_class_entry *ce TSRMLS_DC); + ZEND_API void zend_fetch_dimension_by_zval(zval **result, zval *container, zval *dim TSRMLS_DC); + #ifdef ZEND_WIN32 void zend_init_timeout_thread(void); void zend_shutdown_timeout_thread(void); diff --cc Zend/zend_language_parser.y index d72f73e,56e702e..8887bac --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@@ -996,7 -994,9 +994,9 @@@ static_scalar_value | static_class_name_scalar { $$.u.ast = zend_ast_create_constant(&$1.u.constant); } | namespace_name { zend_do_fetch_constant(&$$, NULL, &$1, ZEND_CT, 1 TSRMLS_CC); $$.u.ast = zend_ast_create_constant(&$$.u.constant); } | T_NAMESPACE T_NS_SEPARATOR namespace_name { $$.op_type = IS_CONST; ZVAL_EMPTY_STRING(&$$.u.constant); zend_do_build_namespace_name(&$$, &$$, &$3 TSRMLS_CC); $3 = $$; zend_do_fetch_constant(&$$, NULL, &$3, ZEND_CT, 0 TSRMLS_CC); $$.u.ast = zend_ast_create_constant(&$$.u.constant); } - | T_NS_SEPARATOR namespace_name { char *tmp = estrndup(Z_STRVAL($2.u.constant), Z_STRLEN($2.u.constant)+1); memcpy(&(tmp[1]), Z_STRVAL($2.u.constant), Z_STRLEN($2.u.constant)+1); tmp[0] = '\\'; efree(Z_STRVAL($2.u.constant)); Z_STRVAL($2.u.constant) = tmp; ++Z_STRLEN($2.u.constant); zend_do_fetch_constant(&$$, NULL, &$2, ZEND_CT, 0 TSRMLS_CC); $$.u.ast = zend_ast_create_constant(&$$.u.constant); } + | T_NS_SEPARATOR namespace_name { char *tmp = estrndup(Z_STRVAL($2.u.constant), Z_STRSIZE($2.u.constant)+1); memcpy(&(tmp[1]), Z_STRVAL($2.u.constant), Z_STRSIZE($2.u.constant)+1); tmp[0] = '\\'; efree(Z_STRVAL($2.u.constant)); Z_STRVAL($2.u.constant) = tmp; ++Z_STRSIZE($2.u.constant); zend_do_fetch_constant(&$$, NULL, &$2, ZEND_CT, 0 TSRMLS_CC); $$.u.ast = zend_ast_create_constant(&$$.u.constant); } + | T_ARRAY '(' static_array_pair_list ')' { $$ = $3; } + | '[' static_array_pair_list ']' { $$ = $2; } | static_class_constant { $$.u.ast = zend_ast_create_constant(&$1.u.constant); } | T_CLASS_C { $$.u.ast = zend_ast_create_constant(&$1.u.constant); } | static_operation { $$ = $1; } diff --cc ext/json/json.c index 2794bf9,d4cb39f..4d434e0 --- a/ext/json/json.c +++ b/ext/json/json.c @@@ -228,9 -228,9 +228,9 @@@ static inline void json_pretty_print_in /* }}} */ -static void json_encode_array(smart_str *buf, zval **val, int options TSRMLS_DC) /* {{{ */ +static void json_encode_array(smart_str *buf, zval **val, php_int_t options TSRMLS_DC) /* {{{ */ { - int i, r; + int i, r, need_comma = 0; HashTable *myht; if (Z_TYPE_PP(val) == IS_ARRAY) { @@@ -262,11 -261,10 +261,10 @@@ { char *key; zval **data; - ulong index; - uint key_len; + php_uint_t index; + php_size_t key_len; HashPosition pos; HashTable *tmp_ht; - int need_comma = 0; zend_hash_internal_pointer_reset_ex(myht, &pos); for (;; zend_hash_move_forward_ex(myht, &pos)) { diff --cc ext/mysqli/mysqli.c index 9e1ba3a,b23d7e3..a475e78 --- a/ext/mysqli/mysqli.c +++ b/ext/mysqli/mysqli.c @@@ -709,18 -709,19 +709,19 @@@ PHP_MINIT_FUNCTION(mysqli #endif /* mysqli_real_connect flags */ - REGISTER_LONG_CONSTANT("MYSQLI_CLIENT_SSL", CLIENT_SSL, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("MYSQLI_CLIENT_COMPRESS",CLIENT_COMPRESS, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("MYSQLI_CLIENT_INTERACTIVE", CLIENT_INTERACTIVE, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("MYSQLI_CLIENT_IGNORE_SPACE", CLIENT_IGNORE_SPACE, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("MYSQLI_CLIENT_NO_SCHEMA", CLIENT_NO_SCHEMA, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("MYSQLI_CLIENT_FOUND_ROWS", CLIENT_FOUND_ROWS, CONST_CS | CONST_PERSISTENT); + REGISTER_INT_CONSTANT("MYSQLI_CLIENT_SSL", CLIENT_SSL, CONST_CS | CONST_PERSISTENT); + REGISTER_INT_CONSTANT("MYSQLI_CLIENT_COMPRESS",CLIENT_COMPRESS, CONST_CS | CONST_PERSISTENT); + REGISTER_INT_CONSTANT("MYSQLI_CLIENT_INTERACTIVE", CLIENT_INTERACTIVE, CONST_CS | CONST_PERSISTENT); + REGISTER_INT_CONSTANT("MYSQLI_CLIENT_IGNORE_SPACE", CLIENT_IGNORE_SPACE, CONST_CS | CONST_PERSISTENT); + REGISTER_INT_CONSTANT("MYSQLI_CLIENT_NO_SCHEMA", CLIENT_NO_SCHEMA, CONST_CS | CONST_PERSISTENT); + REGISTER_INT_CONSTANT("MYSQLI_CLIENT_FOUND_ROWS", CLIENT_FOUND_ROWS, CONST_CS | CONST_PERSISTENT); /* for mysqli_query */ - REGISTER_LONG_CONSTANT("MYSQLI_STORE_RESULT", MYSQLI_STORE_RESULT, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("MYSQLI_USE_RESULT", MYSQLI_USE_RESULT, CONST_CS | CONST_PERSISTENT); + REGISTER_INT_CONSTANT("MYSQLI_STORE_RESULT", MYSQLI_STORE_RESULT, CONST_CS | CONST_PERSISTENT); + REGISTER_INT_CONSTANT("MYSQLI_USE_RESULT", MYSQLI_USE_RESULT, CONST_CS | CONST_PERSISTENT); #if defined (MYSQLI_USE_MYSQLND) - REGISTER_LONG_CONSTANT("MYSQLI_ASYNC", MYSQLI_ASYNC, CONST_CS | CONST_PERSISTENT); - REGISTER_LONG_CONSTANT("MYSQLI_STORE_RESULT_COPY_DATA", MYSQLI_STORE_RESULT_COPY_DATA, CONST_CS | CONST_PERSISTENT); + REGISTER_INT_CONSTANT("MYSQLI_ASYNC", MYSQLI_ASYNC, CONST_CS | CONST_PERSISTENT); ++ REGISTER_INT_CONSTANT("MYSQLI_STORE_RESULT_COPY_DATA", MYSQLI_STORE_RESULT_COPY_DATA, CONST_CS | CONST_PERSISTENT); #endif /* for mysqli_fetch_assoc */ diff --cc ext/mysqlnd/mysqlnd.c index 65b3941,893a144..625d111 --- a/ext/mysqlnd/mysqlnd.c +++ b/ext/mysqlnd/mysqlnd.c @@@ -1107,11 -1107,12 +1107,12 @@@ MYSQLND_METHOD(mysqlnd_conn, connect)(M /* {{{ mysqlnd_connect */ PHPAPI MYSQLND * mysqlnd_connect(MYSQLND * conn_handle, const char * host, const char * user, - const char * passwd, unsigned int passwd_len, - const char * db, unsigned int db_len, - unsigned int port, + const char * passwd, php_size_t passwd_len, + const char * db, php_size_t db_len, + php_uint_t port, const char * socket_or_pipe, - php_uint_t mysql_flags - unsigned int mysql_flags, - unsigned int client_api_flags ++ php_uint_t mysql_flags, ++ php_uint_t client_api_flags TSRMLS_DC) { enum_func_status ret = FAIL; diff --cc ext/mysqlnd/mysqlnd.h index a3b56c4,f373ea5..042bd1d --- a/ext/mysqlnd/mysqlnd.h +++ b/ext/mysqlnd/mysqlnd.h @@@ -85,15 -85,16 +85,16 @@@ PHPAPI const MYSQLND_CHARSET * mysqlnd_ /* Connect */ - #define mysqlnd_init(persistent) _mysqlnd_init((persistent) TSRMLS_CC) - PHPAPI MYSQLND * _mysqlnd_init(zend_bool persistent TSRMLS_DC); + #define mysqlnd_init(client_flags, persistent) _mysqlnd_init((client_flags), (persistent) TSRMLS_CC) + PHPAPI MYSQLND * _mysqlnd_init(unsigned int client_flags, zend_bool persistent TSRMLS_DC); PHPAPI MYSQLND * mysqlnd_connect(MYSQLND * conn, const char * host, const char * user, - const char * passwd, unsigned int passwd_len, - const char * db, unsigned int db_len, - unsigned int port, + const char * passwd, php_size_t passwd_len, + const char * db, php_size_t db_len, + php_uint_t port, const char * socket_or_pipe, - php_uint_t mysql_flags - unsigned int mysql_flags, - unsigned int client_api_flags ++ php_uint_t mysql_flags, ++ php_uint_t client_api_flags TSRMLS_DC); #define mysqlnd_change_user(conn, user, passwd, db, silent) ((conn)->data)->m->change_user((conn)->data, (user), (passwd), (db), (silent), strlen((passwd)) TSRMLS_CC) @@@ -270,18 -271,19 +271,19 @@@ ZEND_BEGIN_MODULE_GLOBALS(mysqlnd char * trace_alloc_settings; /* The actual string */ MYSQLND_DEBUG * dbg; /* The DBG object for standard tracing */ MYSQLND_DEBUG * trace_alloc; /* The DBG object for allocation tracing */ - long net_cmd_buffer_size; - long net_read_buffer_size; - long log_mask; - long net_read_timeout; - long mempool_default_size; - long debug_emalloc_fail_threshold; - long debug_ecalloc_fail_threshold; - long debug_erealloc_fail_threshold; - long debug_malloc_fail_threshold; - long debug_calloc_fail_threshold; - long debug_realloc_fail_threshold; + php_int_t net_cmd_buffer_size; + php_int_t net_read_buffer_size; + php_int_t log_mask; + php_int_t net_read_timeout; + php_int_t mempool_default_size; + php_int_t debug_emalloc_fail_threshold; + php_int_t debug_ecalloc_fail_threshold; + php_int_t debug_erealloc_fail_threshold; + php_int_t debug_malloc_fail_threshold; + php_int_t debug_calloc_fail_threshold; + php_int_t debug_realloc_fail_threshold; char * sha256_server_public_key; + zend_bool fetch_data_copy; ZEND_END_MODULE_GLOBALS(mysqlnd) PHPAPI ZEND_EXTERN_MODULE_GLOBALS(mysqlnd) diff --cc ext/mysqlnd/mysqlnd_ps.c index 61583f5,bee8e1d..550f7f0 --- a/ext/mysqlnd/mysqlnd_ps.c +++ b/ext/mysqlnd/mysqlnd_ps.c @@@ -733,46 -736,48 +736,48 @@@ mysqlnd_stmt_fetch_row_buffered(MYSQLND { MYSQLND_STMT * s = (MYSQLND_STMT *) param; MYSQLND_STMT_DATA * stmt = s? s->data:NULL; - MYSQLND_RES_BUFFERED *set = result->stored_data; const MYSQLND_RES_METADATA * const meta = result->meta; - unsigned int field_count = meta->field_count; + php_uint_t field_count = meta->field_count; DBG_ENTER("mysqlnd_stmt_fetch_row_buffered"); *fetched_anything = FALSE; DBG_INF_FMT("stmt=%lu", stmt != NULL ? stmt->stmt_id : 0L); /* If we haven't read everything */ - if (set->data_cursor && - (set->data_cursor - set->data) < (set->row_count * field_count)) - { - /* The user could have skipped binding - don't crash*/ - if (stmt->result_bind) { - php_uint_t i; - zval **current_row = set->data_cursor; - - if (NULL == current_row[0]) { - uint64_t row_num = (set->data_cursor - set->data) / field_count; - enum_func_status rc = result->stored_data->m.row_decoder(set->row_buffers[row_num], - current_row, - meta->field_count, - meta->fields, - result->conn->options->int_and_float_native, - result->conn->stats TSRMLS_CC); - if (PASS != rc) { - DBG_RETURN(FAIL); - } - set->initialized_rows++; - if (stmt->update_max_length) { - for (i = 0; i < result->field_count; i++) { - /* - NULL fields are 0 length, 0 is not more than 0 - String of zero size, definitely can't be the next max_length. - Thus for NULL and zero-length we are quite efficient. - */ - if (Z_TYPE_P(current_row[i]) >= IS_STRING) { - php_uint_t len = Z_STRSIZE_P(current_row[i]); - if (meta->fields[i].max_length < len) { - meta->fields[i].max_length = len; + if (result->stored_data->type == MYSQLND_BUFFERED_TYPE_ZVAL) { + MYSQLND_RES_BUFFERED_ZVAL * set = (MYSQLND_RES_BUFFERED_ZVAL *) result->stored_data; + if (set->data_cursor && + (set->data_cursor - set->data) < (result->stored_data->row_count * field_count)) + { + /* The user could have skipped binding - don't crash*/ + if (stmt->result_bind) { - unsigned int i; ++ php_uint_t i; + zval **current_row = set->data_cursor; + + if (NULL == current_row[0]) { + uint64_t row_num = (set->data_cursor - set->data) / field_count; + enum_func_status rc = result->stored_data->m.row_decoder(result->stored_data->row_buffers[row_num], + current_row, + meta->field_count, + meta->fields, + result->conn->options->int_and_float_native, + result->conn->stats TSRMLS_CC); + if (PASS != rc) { + DBG_RETURN(FAIL); + } + result->stored_data->initialized_rows++; + if (stmt->update_max_length) { + for (i = 0; i < result->field_count; i++) { + /* + NULL fields are 0 length, 0 is not more than 0 + String of zero size, definitely can't be the next max_length. + Thus for NULL and zero-length we are quite efficient. + */ + if (Z_TYPE_P(current_row[i]) >= IS_STRING) { - unsigned long len = Z_STRLEN_P(current_row[i]); ++ php_size_t len = Z_STRSIZE_P(current_row[i]); + if (meta->fields[i].max_length < len) { + meta->fields[i].max_length = len; + } } } } diff --cc ext/mysqlnd/mysqlnd_result.c index 78f4010,0112a13..98cba21 --- a/ext/mysqlnd/mysqlnd_result.c +++ b/ext/mysqlnd/mysqlnd_result.c @@@ -32,29 -32,30 +32,30 @@@ #define MYSQLND_SILENT - - /* {{{ mysqlnd_result_buffered::initialize_result_set_rest */ + /* {{{ mysqlnd_result_buffered_zval::initialize_result_set_rest */ static enum_func_status - MYSQLND_METHOD(mysqlnd_result_buffered, initialize_result_set_rest)(MYSQLND_RES_BUFFERED * const result, MYSQLND_RES_METADATA * const meta, - MYSQLND_STATS * stats, zend_bool int_and_float_native TSRMLS_DC) + MYSQLND_METHOD(mysqlnd_result_buffered_zval, initialize_result_set_rest)(MYSQLND_RES_BUFFERED * const result, MYSQLND_RES_METADATA * const meta, + MYSQLND_STATS * stats, zend_bool int_and_float_native TSRMLS_DC) { - unsigned int i; + php_uint_t i; - zval **data_cursor = result->data; - zval **data_begin = result->data; - php_uint_t field_count = meta->field_count; - uint64_t row_count = result->row_count; enum_func_status ret = PASS; - DBG_ENTER("mysqlnd_result_buffered::initialize_result_set_rest"); + const unsigned int field_count = meta->field_count; + const uint64_t row_count = result->row_count; + enum_func_status rc; + + zval **data_begin = ((MYSQLND_RES_BUFFERED_ZVAL *) result)->data; + zval **data_cursor = data_begin; + + DBG_ENTER("mysqlnd_result_buffered_zval::initialize_result_set_rest"); if (!data_cursor || row_count == result->initialized_rows) { DBG_RETURN(ret); } - while ((data_cursor - data_begin) < (int)(row_count * field_count)) { + while ((data_cursor - data_begin) < (ptrdiff_t)(row_count * field_count)) { if (NULL == data_cursor[0]) { - enum_func_status rc = result->m.row_decoder( - result->row_buffers[(data_cursor - data_begin) / field_count], + rc = result->m.row_decoder(result->row_buffers[(data_cursor - data_begin) / field_count], data_cursor, - meta->field_count, + field_count, meta->fields, int_and_float_native, stats TSRMLS_CC); @@@ -84,6 -85,62 +85,62 @@@ /* }}} */ + /* {{{ mysqlnd_result_buffered_c::initialize_result_set_rest */ + static enum_func_status + MYSQLND_METHOD(mysqlnd_result_buffered_c, initialize_result_set_rest)(MYSQLND_RES_BUFFERED * const result, MYSQLND_RES_METADATA * const meta, + MYSQLND_STATS * stats, zend_bool int_and_float_native TSRMLS_DC) + { + unsigned int i; + enum_func_status ret = PASS; + const unsigned int field_count = meta->field_count; + const uint64_t row_count = result->row_count; + enum_func_status rc; + DBG_ENTER("mysqlnd_result_buffered_c::initialize_result_set_rest"); + + if (result->initialized_rows < row_count) { + zend_uchar * initialized = ((MYSQLND_RES_BUFFERED_C *) result)->initialized; + zval ** current_row = mnd_emalloc(field_count * sizeof(zval *)); + + if (!current_row) { + DBG_RETURN(FAIL); + } + + for (i = 0; i < result->row_count; i++) { + /* (i / 8) & the_bit_for_i*/ + if (initialized[i >> 3] & (1 << (i & 7))) { + continue; + } + + rc = result->m.row_decoder(result->row_buffers[i], current_row, field_count, meta->fields, int_and_float_native, stats TSRMLS_CC); + + if (rc != PASS) { + ret = FAIL; + break; + } + result->initialized_rows++; + initialized[i >> 3] |= (1 << (i & 7)); + for (i = 0; i < field_count; i++) { + /* + NULL fields are 0 length, 0 is not more than 0 + String of zero size, definitely can't be the next max_length. + Thus for NULL and zero-length we are quite efficient. + */ + if (Z_TYPE_P(current_row[i]) >= IS_STRING) { - unsigned long len = Z_STRLEN_P(current_row[i]); ++ unsigned long len = Z_STRSIZE_P(current_row[i]); + if (meta->fields[i].max_length < len) { + meta->fields[i].max_length = len; + } + } + zval_ptr_dtor(¤t_row[i]); + } + } + mnd_efree(current_row); + } + DBG_RETURN(ret); + } + /* }}} */ + + /* {{{ mysqlnd_rset_zval_ptr_dtor */ static void mysqlnd_rset_zval_ptr_dtor(zval **zv, enum_mysqlnd_res_type type, zend_bool * copy_ctor_called TSRMLS_DC) @@@ -205,25 -262,23 +262,23 @@@ MYSQLND_METHOD(mysqlnd_result_unbuffere /* }}} */ - /* {{{ mysqlnd_result_buffered::free_result */ + /* {{{ mysqlnd_result_buffered_zval::free_result */ static void - MYSQLND_METHOD(mysqlnd_result_buffered, free_result)(MYSQLND_RES_BUFFERED * const set TSRMLS_DC) + MYSQLND_METHOD(mysqlnd_result_buffered_zval, free_result)(MYSQLND_RES_BUFFERED_ZVAL * const set TSRMLS_DC) { - php_uint_t field_count = set->field_count; - int64_t row; + zval ** data = set->data; - DBG_ENTER("mysqlnd_res::free_buffered_data"); - DBG_INF_FMT("Freeing "MYSQLND_LLU_SPEC" row(s)", set->row_count); + DBG_ENTER("mysqlnd_result_buffered_zval::free_result"); - if (set->data) { + set->data = NULL; /* prevent double free if following loop is interrupted */ + if (data) { - unsigned int copy_on_write_performed = 0; - unsigned int copy_on_write_saved = 0; - unsigned int field_count = set->field_count; + php_uint_t copy_on_write_performed = 0; + php_uint_t copy_on_write_saved = 0; - zval **data = set->data; - set->data = NULL; /* prevent double free if following loop is interrupted */ - ++ php_uint_t field_count = set->field_count; + int64_t row; + for (row = set->row_count - 1; row >= 0; row--) { zval **current_row = data + row * field_count; - MYSQLND_MEMORY_POOL_CHUNK *current_buffer = set->row_buffers[row]; int64_t col; if (current_row != NULL) { @@@ -589,13 -678,10 +678,10 @@@ mysqlnd_query_read_result_set_header(MY of PHP, to be called as separate function. But let's have it for completeness. */ -static unsigned long * +static php_uint_t * - MYSQLND_METHOD(mysqlnd_result_buffered, fetch_lengths)(MYSQLND_RES_BUFFERED * const result TSRMLS_DC) + MYSQLND_METHOD(mysqlnd_result_buffered_zval, fetch_lengths)(MYSQLND_RES_BUFFERED * const result TSRMLS_DC) { - php_uint_t i; - zval **previous_row; - MYSQLND_RES_BUFFERED *set = result; - + const MYSQLND_RES_BUFFERED_ZVAL * set = (MYSQLND_RES_BUFFERED_ZVAL *) result; /* If: - unbuffered result @@@ -767,7 -874,7 +874,7 @@@ MYSQLND_METHOD(mysqlnd_result_unbuffere /* {{{ mysqlnd_result_unbuffered::fetch_row */ static enum_func_status - MYSQLND_METHOD(mysqlnd_result_unbuffered, fetch_row)(MYSQLND_RES * result, void * param, php_uint_t flags, zend_bool * fetched_anything TSRMLS_DC) -MYSQLND_METHOD(mysqlnd_result_unbuffered, fetch_row)(MYSQLND_RES * result, void * param, const unsigned int flags, zend_bool * fetched_anything TSRMLS_DC) ++MYSQLND_METHOD(mysqlnd_result_unbuffered, fetch_row)(MYSQLND_RES * result, void * param, const php_uint_t flags, zend_bool * fetched_anything TSRMLS_DC) { enum_func_status ret; zval *row = (zval *) param; @@@ -941,23 -1048,114 +1048,114 @@@ oom /* {{{ mysqlnd_result_buffered::fetch_row_c */ static enum_func_status -MYSQLND_METHOD(mysqlnd_result_buffered, fetch_row_c)(MYSQLND_RES * result, void * param, unsigned int flags, zend_bool * fetched_anything TSRMLS_DC) +MYSQLND_METHOD(mysqlnd_result_buffered, fetch_row_c)(MYSQLND_RES * result, void * param, php_uint_t flags, zend_bool * fetched_anything TSRMLS_DC) { MYSQLND_ROW_C * row = (MYSQLND_ROW_C *) param; - MYSQLND_RES_BUFFERED * set = result->stored_data; const MYSQLND_RES_METADATA * const meta = result->meta; - unsigned int field_count = meta->field_count; + php_uint_t field_count = meta->field_count; enum_func_status ret = FAIL; - DBG_ENTER("mysqlnd_result_buffered::fetch_row_c"); + if (result->stored_data->type == MYSQLND_BUFFERED_TYPE_ZVAL) { + MYSQLND_RES_BUFFERED_ZVAL * set = (MYSQLND_RES_BUFFERED_ZVAL *) result->stored_data; + + /* If we haven't read everything */ + if (set->data_cursor && + (set->data_cursor - set->data) < (result->stored_data->row_count * field_count)) + { + zval **current_row = set->data_cursor; + unsigned int i; + + if (NULL == current_row[0]) { + uint64_t row_num = (set->data_cursor - set->data) / field_count; + enum_func_status rc = set->m.row_decoder(set->row_buffers[row_num], + current_row, + field_count, + meta->fields, + result->conn->options->int_and_float_native, + result->conn->stats TSRMLS_CC); + if (rc != PASS) { + DBG_RETURN(FAIL); + } + set->initialized_rows++; + for (i = 0; i < field_count; i++) { + /* + NULL fields are 0 length, 0 is not more than 0 + String of zero size, definitely can't be the next max_length. + Thus for NULL and zero-length we are quite efficient. + */ + if (Z_TYPE_P(current_row[i]) >= IS_STRING) { - unsigned long len = Z_STRLEN_P(current_row[i]); ++ unsigned long len = Z_STRSIZE_P(current_row[i]); + if (meta->fields[i].max_length < len) { + meta->fields[i].max_length = len; + } + } + } + } + + /* BEGIN difference between normal normal fetch and _c */ + /* there is no conn handle in this function thus we can't set OOM in error_info */ + *row = mnd_malloc(field_count * sizeof(char *)); + if (*row) { + for (i = 0; i < field_count; i++) { + zval * data = current_row[i]; + - set->lengths[i] = (Z_TYPE_P(data) == IS_NULL)? 0:Z_STRLEN_P(data); ++ set->lengths[i] = (Z_TYPE_P(data) == IS_NULL)? 0:Z_STRSIZE_P(data); + + if (Z_TYPE_P(data) != IS_NULL) { + convert_to_string(data); + (*row)[i] = Z_STRVAL_P(data); + } else { + (*row)[i] = NULL; + } + } + set->data_cursor += field_count; + MYSQLND_INC_GLOBAL_STATISTIC(STAT_ROWS_FETCHED_FROM_CLIENT_NORMAL_BUF); + } else { + SET_OOM_ERROR(*result->conn->error_info); + } + /* END difference between normal normal fetch and _c */ + + *fetched_anything = *row? TRUE:FALSE; + ret = *row? PASS:FAIL; + } else { + set->data_cursor = NULL; + DBG_INF("EOF reached"); + *fetched_anything = FALSE; + ret = PASS; + } + } else if (result->stored_data->type == MYSQLND_BUFFERED_TYPE_C) { + /* + We don't support _C with pdo because it uses the data in a different way - just references it. + We will either leak or give nirvana pointers + */ + *fetched_anything = FALSE; + DBG_RETURN(FAIL); + } + DBG_INF_FMT("ret=PASS fetched=%u", *fetched_anything); + DBG_RETURN(ret); + } + /* }}} */ + + + /* {{{ mysqlnd_result_buffered_zval::fetch_row */ + static enum_func_status + MYSQLND_METHOD(mysqlnd_result_buffered_zval, fetch_row)(MYSQLND_RES * result, void * param, const unsigned int flags, zend_bool * fetched_anything TSRMLS_DC) + { + zval * row = (zval *) param; + const MYSQLND_RES_METADATA * const meta = result->meta; - unsigned int field_count = meta->field_count; ++ php_uint_t field_count = meta->field_count; + enum_func_status ret = FAIL; + MYSQLND_RES_BUFFERED_ZVAL * set = (MYSQLND_RES_BUFFERED_ZVAL *) result->stored_data; + + DBG_ENTER("mysqlnd_result_buffered_zval::fetch_row"); + /* If we haven't read everything */ if (set->data_cursor && (set->data_cursor - set->data) < (set->row_count * field_count)) { - zval **current_row = set->data_cursor; - MYSQLND_FIELD * field = meta->fields; - unsigned int i; + php_uint_t i; + zval **current_row = set->data_cursor; if (NULL == current_row[0]) { uint64_t row_num = (set->data_cursor - set->data) / field_count; @@@ -978,26 -1176,42 +1176,42 @@@ Thus for NULL and zero-length we are quite efficient. */ if (Z_TYPE_P(current_row[i]) >= IS_STRING) { - php_uint_t len = Z_STRSIZE_P(current_row[i]); - if (field->max_length < len) { - field->max_length = len; - unsigned long len = Z_STRLEN_P(current_row[i]); ++ php_size_t len = Z_STRSIZE_P(current_row[i]); + if (meta->fields[i].max_length < len) { + meta->fields[i].max_length = len; } } } } - /* BEGIN difference between normal normal fetch and _c */ - /* there is no conn handle in this function thus we can't set OOM in error_info */ - *row = mnd_malloc(field_count * sizeof(char *)); - if (ret) { - for (i = 0; i < field_count; i++) { - zval * data = current_row[i]; + for (i = 0; i < field_count; i++) { + zval * data = current_row[i]; - if (Z_TYPE_P(data) != IS_NULL) { - convert_to_string(data); - (*row)[i] = Z_STRVAL_P(data); - set->lengths[i] = (Z_TYPE_P(data) == IS_NULL)? 0:Z_STRLEN_P(data); ++ set->lengths[i] = (Z_TYPE_P(data) == IS_NULL)? 0:Z_STRSIZE_P(data); + + if (flags & MYSQLND_FETCH_NUM) { + Z_ADDREF_P(data); + zend_hash_next_index_insert(Z_ARRVAL_P(row), &data, sizeof(zval *), NULL); + } + if (flags & MYSQLND_FETCH_ASSOC) { + /* zend_hash_quick_update needs length + trailing zero */ + /* QQ: Error handling ? */ + /* + zend_hash_quick_update does not check, as add_assoc_zval_ex do, whether + the index is a numeric and convert it to it. This however means constant + hashing of the column name, which is not needed as it can be precomputed. + */ + Z_ADDREF_P(data); + if (meta->zend_hash_keys[i].is_numeric == FALSE) { + zend_hash_quick_update(Z_ARRVAL_P(row), + meta->fields[i].name, + meta->fields[i].name_length + 1, + meta->zend_hash_keys[i].key, + (void *) &data, sizeof(zval *), NULL); } else { - (*row)[i] = NULL; + zend_hash_index_update(Z_ARRVAL_P(row), + meta->zend_hash_keys[i].key, + (void *) &data, sizeof(zval *), NULL); } } } @@@ -1019,38 -1231,45 +1231,45 @@@ /* }}} */ - /* {{{ mysqlnd_result_buffered::fetch_row */ + /* {{{ mysqlnd_result_buffered_c::fetch_row */ static enum_func_status - MYSQLND_METHOD(mysqlnd_result_buffered, fetch_row)(MYSQLND_RES * result, void * param, php_uint_t flags, zend_bool * fetched_anything TSRMLS_DC) -MYSQLND_METHOD(mysqlnd_result_buffered_c, fetch_row)(MYSQLND_RES * result, void * param, const unsigned int flags, zend_bool * fetched_anything TSRMLS_DC) ++MYSQLND_METHOD(mysqlnd_result_buffered_c, fetch_row)(MYSQLND_RES * result, void * param, const php_uint_t flags, zend_bool * fetched_anything TSRMLS_DC) { zval * row = (zval *) param; - MYSQLND_RES_BUFFERED * set = result->stored_data; const MYSQLND_RES_METADATA * const meta = result->meta; - unsigned int field_count = meta->field_count; + php_uint_t field_count = meta->field_count; enum_func_status ret = FAIL; - DBG_ENTER("mysqlnd_result_buffered::fetch_row"); + MYSQLND_RES_BUFFERED_C * set = (MYSQLND_RES_BUFFERED_C *) result->stored_data; + + DBG_ENTER("mysqlnd_result_buffered_c::fetch_row"); /* If we haven't read everything */ - if (set->data_cursor && - (set->data_cursor - set->data) < (set->row_count * field_count)) - { - zval **current_row = set->data_cursor; - MYSQLND_FIELD * field = meta->fields; + if (set->current_row < set->row_count) { + zval **current_row; + enum_func_status rc; - unsigned int i; + php_uint_t i; - if (NULL == current_row[0]) { - uint64_t row_num = (set->data_cursor - set->data) / field_count; - enum_func_status rc = set->m.row_decoder(set->row_buffers[row_num], - current_row, - field_count, - meta->fields, - result->conn->options->int_and_float_native, - result->conn->stats TSRMLS_CC); - if (rc != PASS) { - DBG_RETURN(FAIL); - } + current_row = mnd_emalloc(field_count * sizeof(zval *)); + if (!current_row) { + SET_OOM_ERROR(*result->conn->error_info); + DBG_RETURN(FAIL); + } + + rc = result->stored_data->m.row_decoder(result->stored_data->row_buffers[set->current_row], + current_row, + field_count, + meta->fields, + result->conn->options->int_and_float_native, + result->conn->stats TSRMLS_CC); + if (rc != PASS) { + DBG_RETURN(FAIL); + } + if (!(set->initialized[set->current_row >> 3] & (1 << (set->current_row & 7)))) { + set->initialized[set->current_row >> 3] |= (1 << (set->current_row & 7)); /* mark initialized */ + set->initialized_rows++; + for (i = 0; i < field_count; i++) { /* NULL fields are 0 length, 0 is not more than 0 @@@ -1058,17 -1277,19 +1277,19 @@@ Thus for NULL and zero-length we are quite efficient. */ if (Z_TYPE_P(current_row[i]) >= IS_STRING) { - php_uint_t len = Z_STRSIZE_P(current_row[i]); - if (field->max_length < len) { - field->max_length = len; - unsigned long len = Z_STRLEN_P(current_row[i]); ++ php_size_t len = Z_STRSIZE_P(current_row[i]); + if (meta->fields[i].max_length < len) { + meta->fields[i].max_length = len; } } } } - for (i = 0; i < field_count; i++, field++) { + for (i = 0; i < field_count; i++) { zval * data = current_row[i]; - set->lengths[i] = (Z_TYPE_P(data) == IS_NULL)? 0:Z_STRLEN_P(data); ++ set->lengths[i] = (Z_TYPE_P(data) == IS_NULL)? 0:Z_STRSIZE_P(data); + if (flags & MYSQLND_FETCH_NUM) { Z_ADDREF_P(data); zend_hash_next_index_insert(Z_ARRVAL_P(row), &data, sizeof(zval *), NULL); @@@ -1113,7 -1345,7 +1345,7 @@@ /* {{{ mysqlnd_res::fetch_row */ static enum_func_status - MYSQLND_METHOD(mysqlnd_res, fetch_row)(MYSQLND_RES * result, void * param, php_uint_t flags, zend_bool *fetched_anything TSRMLS_DC) -MYSQLND_METHOD(mysqlnd_res, fetch_row)(MYSQLND_RES * result, void * param, const unsigned int flags, zend_bool *fetched_anything TSRMLS_DC) ++MYSQLND_METHOD(mysqlnd_res, fetch_row)(MYSQLND_RES * result, void * param, const php_uint_t flags, zend_bool *fetched_anything TSRMLS_DC) { const mysqlnd_fetch_row_func f = result->stored_data? result->stored_data->m.fetch_row:(result->unbuf? result->unbuf->m.fetch_row:NULL); if (f) { @@@ -1539,7 -1807,7 +1807,7 @@@ MYSQLND_METHOD(mysqlnd_res, field_tell) /* {{{ mysqlnd_res::fetch_into */ static void - MYSQLND_METHOD(mysqlnd_res, fetch_into)(MYSQLND_RES * result, php_uint_t flags, -MYSQLND_METHOD(mysqlnd_res, fetch_into)(MYSQLND_RES * result, const unsigned int flags, ++MYSQLND_METHOD(mysqlnd_res, fetch_into)(MYSQLND_RES * result, const php_uint_t flags, zval *return_value, enum_mysqlnd_extension extension TSRMLS_DC ZEND_FILE_LINE_DC) { @@@ -1600,10 -1868,10 +1868,10 @@@ MYSQLND_METHOD(mysqlnd_res, fetch_row_c /* {{{ mysqlnd_res::fetch_all */ static void - MYSQLND_METHOD(mysqlnd_res, fetch_all)(MYSQLND_RES * result, php_uint_t flags, zval *return_value TSRMLS_DC ZEND_FILE_LINE_DC) -MYSQLND_METHOD(mysqlnd_res, fetch_all)(MYSQLND_RES * result, const unsigned int flags, zval *return_value TSRMLS_DC ZEND_FILE_LINE_DC) ++MYSQLND_METHOD(mysqlnd_res, fetch_all)(MYSQLND_RES * result, const php_uint_t flags, zval *return_value TSRMLS_DC ZEND_FILE_LINE_DC) { zval *row; - ulong i = 0; + php_uint_t i = 0; MYSQLND_RES_BUFFERED *set = result->stored_data; DBG_ENTER("mysqlnd_res::fetch_all"); @@@ -1786,14 -2054,14 +2054,14 @@@ mysqlnd_result_unbuffered_init(php_uint /* }}} */ - /* {{{ mysqlnd_result_buffered_init */ - PHPAPI MYSQLND_RES_BUFFERED * - mysqlnd_result_buffered_init(php_uint_t field_count, zend_bool ps, zend_bool persistent TSRMLS_DC) + /* {{{ mysqlnd_result_buffered_zval_init */ + PHPAPI MYSQLND_RES_BUFFERED_ZVAL * -mysqlnd_result_buffered_zval_init(unsigned int field_count, zend_bool ps, zend_bool persistent TSRMLS_DC) ++mysqlnd_result_buffered_zval_init(php_uint_t field_count, zend_bool ps, zend_bool persistent TSRMLS_DC) { - size_t alloc_size = sizeof(MYSQLND_RES_BUFFERED) + mysqlnd_plugin_count() * sizeof(void *); - MYSQLND_RES_BUFFERED * ret = mnd_pecalloc(1, alloc_size, persistent); + size_t alloc_size = sizeof(MYSQLND_RES_BUFFERED_ZVAL) + mysqlnd_plugin_count() * sizeof(void *); + MYSQLND_RES_BUFFERED_ZVAL * ret = mnd_pecalloc(1, alloc_size, persistent); - DBG_ENTER("mysqlnd_result_buffered_init"); + DBG_ENTER("mysqlnd_result_buffered_zval_init"); if (!ret) { DBG_RETURN(NULL); @@@ -1812,6 -2080,50 +2080,50 @@@ ret->field_count= field_count; ret->ps = ps; ret->m = *mysqlnd_result_buffered_get_methods(); + ret->type = MYSQLND_BUFFERED_TYPE_ZVAL; + + if (ps) { + ret->m.fetch_lengths = NULL; /* makes no sense */ + ret->m.row_decoder = php_mysqlnd_rowp_read_binary_protocol; + } else { + ret->m.row_decoder = php_mysqlnd_rowp_read_text_protocol_zval; + } + ret->m.fetch_row = MYSQLND_METHOD(mysqlnd_result_buffered_zval, fetch_row); + ret->m.fetch_lengths = MYSQLND_METHOD(mysqlnd_result_buffered_zval, fetch_lengths); + ret->m.data_seek = MYSQLND_METHOD(mysqlnd_result_buffered_zval, data_seek); + ret->m.initialize_result_set_rest = MYSQLND_METHOD(mysqlnd_result_buffered_zval, initialize_result_set_rest); + DBG_RETURN(ret); + } + /* }}} */ + + + /* {{{ mysqlnd_result_buffered_c_init */ + PHPAPI MYSQLND_RES_BUFFERED_C * -mysqlnd_result_buffered_c_init(unsigned int field_count, zend_bool ps, zend_bool persistent TSRMLS_DC) ++mysqlnd_result_buffered_c_init(php_uint_t field_count, zend_bool ps, zend_bool persistent TSRMLS_DC) + { + size_t alloc_size = sizeof(MYSQLND_RES_BUFFERED_C) + mysqlnd_plugin_count() * sizeof(void *); + MYSQLND_RES_BUFFERED_C * ret = mnd_pecalloc(1, alloc_size, persistent); + + DBG_ENTER("mysqlnd_result_buffered_c_init"); + + if (!ret) { + DBG_RETURN(NULL); + } - if (!(ret->lengths = mnd_pecalloc(field_count, sizeof(unsigned long), persistent))) { ++ if (!(ret->lengths = mnd_pecalloc(field_count, sizeof(php_uint_t), persistent))) { + mnd_pefree(ret, persistent); + DBG_RETURN(NULL); + } + if (!(ret->result_set_memory_pool = mysqlnd_mempool_create(MYSQLND_G(mempool_default_size) TSRMLS_CC))) { + mnd_efree(ret->lengths); + mnd_pefree(ret, persistent); + DBG_RETURN(NULL); + } + + ret->persistent = persistent; + ret->field_count= field_count; + ret->ps = ps; + ret->m = *mysqlnd_result_buffered_get_methods(); + ret->type = MYSQLND_BUFFERED_TYPE_C; if (ps) { ret->m.fetch_lengths = NULL; /* makes no sense */ diff --cc ext/mysqlnd/mysqlnd_result.h index 09e0f81,f7e22a1..9c536e5 --- a/ext/mysqlnd/mysqlnd_result.h +++ b/ext/mysqlnd/mysqlnd_result.h @@@ -23,9 -23,10 +23,10 @@@ #ifndef MYSQLND_RESULT_H #define MYSQLND_RESULT_H -PHPAPI MYSQLND_RES * mysqlnd_result_init(unsigned int field_count, zend_bool persistent TSRMLS_DC); -PHPAPI MYSQLND_RES_UNBUFFERED * mysqlnd_result_unbuffered_init(unsigned int field_count, zend_bool ps, zend_bool persistent TSRMLS_DC); -PHPAPI MYSQLND_RES_BUFFERED_ZVAL * mysqlnd_result_buffered_zval_init(unsigned int field_count, zend_bool ps, zend_bool persistent TSRMLS_DC); -PHPAPI MYSQLND_RES_BUFFERED_C * mysqlnd_result_buffered_c_init(unsigned int field_count, zend_bool ps, zend_bool persistent TSRMLS_DC); +PHPAPI MYSQLND_RES * mysqlnd_result_init(php_uint_t field_count, zend_bool persistent TSRMLS_DC); +PHPAPI MYSQLND_RES_UNBUFFERED * mysqlnd_result_unbuffered_init(php_uint_t field_count, zend_bool ps, zend_bool persistent TSRMLS_DC); - PHPAPI MYSQLND_RES_BUFFERED * mysqlnd_result_buffered_init(php_uint_t field_count, zend_bool ps, zend_bool persistent TSRMLS_DC); ++PHPAPI MYSQLND_RES_BUFFERED_ZVAL * mysqlnd_result_buffered_zval_init(php_uint_t field_count, zend_bool ps, zend_bool persistent TSRMLS_DC); ++PHPAPI MYSQLND_RES_BUFFERED_C * mysqlnd_result_buffered_c_init(php_uint_t field_count, zend_bool ps, zend_bool persistent TSRMLS_DC); enum_func_status mysqlnd_query_read_result_set_header(MYSQLND_CONN_DATA * conn, MYSQLND_STMT * stmt TSRMLS_DC); diff --cc ext/mysqlnd/mysqlnd_structs.h index 3b653e5,66920e4..a21e71d --- a/ext/mysqlnd/mysqlnd_structs.h +++ b/ext/mysqlnd/mysqlnd_structs.h @@@ -244,7 -246,7 +246,7 @@@ typedef struct st_mysqlnd_debug MYSQLND typedef MYSQLND_RES* (*mysqlnd_stmt_use_or_store_func)(MYSQLND_STMT * const TSRMLS_DC); typedef enum_func_status (*mysqlnd_fetch_row_func)(MYSQLND_RES *result, void * param, - php_uint_t flags, - const unsigned int flags, ++ const php_uint_t flags, zend_bool * fetched_anything TSRMLS_DC); @@@ -614,13 -624,13 +624,13 @@@ typedef enum_func_status (*func_mysqlnd typedef MYSQLND_RES * (*func_mysqlnd_res__use_result)(MYSQLND_RES * const result, zend_bool ps_protocol TSRMLS_DC); -typedef MYSQLND_RES * (*func_mysqlnd_res__store_result)(MYSQLND_RES * result, MYSQLND_CONN_DATA * const conn, const unsigned int flags TSRMLS_DC); -typedef void (*func_mysqlnd_res__fetch_into)(MYSQLND_RES *result, const unsigned int flags, zval *return_value, enum_mysqlnd_extension ext TSRMLS_DC ZEND_FILE_LINE_DC); +typedef MYSQLND_RES * (*func_mysqlnd_res__store_result)(MYSQLND_RES * result, MYSQLND_CONN_DATA * const conn, const php_uint_t flags TSRMLS_DC); - typedef void (*func_mysqlnd_res__fetch_into)(MYSQLND_RES *result, php_uint_t flags, zval *return_value, enum_mysqlnd_extension ext TSRMLS_DC ZEND_FILE_LINE_DC); ++typedef void (*func_mysqlnd_res__fetch_into)(MYSQLND_RES *result, const php_uint_t flags, zval *return_value, enum_mysqlnd_extension ext TSRMLS_DC ZEND_FILE_LINE_DC); typedef MYSQLND_ROW_C (*func_mysqlnd_res__fetch_row_c)(MYSQLND_RES *result TSRMLS_DC); - typedef void (*func_mysqlnd_res__fetch_all)(MYSQLND_RES *result, php_uint_t flags, zval *return_value TSRMLS_DC ZEND_FILE_LINE_DC); -typedef void (*func_mysqlnd_res__fetch_all)(MYSQLND_RES *result, const unsigned int flags, zval *return_value TSRMLS_DC ZEND_FILE_LINE_DC); -typedef void (*func_mysqlnd_res__fetch_field_data)(MYSQLND_RES *result, unsigned int offset, zval *return_value TSRMLS_DC); ++typedef void (*func_mysqlnd_res__fetch_all)(MYSQLND_RES *result, const php_uint_t flags, zval *return_value TSRMLS_DC ZEND_FILE_LINE_DC); +typedef void (*func_mysqlnd_res__fetch_field_data)(MYSQLND_RES *result, php_uint_t offset, zval *return_value TSRMLS_DC); typedef uint64_t (*func_mysqlnd_res__num_rows)(const MYSQLND_RES * const result TSRMLS_DC); -typedef unsigned int (*func_mysqlnd_res__num_fields)(const MYSQLND_RES * const result TSRMLS_DC); +typedef php_uint_t (*func_mysqlnd_res__num_fields)(const MYSQLND_RES * const result TSRMLS_DC); typedef enum_func_status (*func_mysqlnd_res__skip_result)(MYSQLND_RES * const result TSRMLS_DC); typedef enum_func_status (*func_mysqlnd_res__seek_data)(MYSQLND_RES * const result, const uint64_t row TSRMLS_DC); typedef MYSQLND_FIELD_OFFSET (*func_mysqlnd_res__seek_field)(MYSQLND_RES * const result, const MYSQLND_FIELD_OFFSET field_offset TSRMLS_DC); @@@ -630,8 -640,8 +640,8 @@@ typedef const MYSQLND_FIELD *(*func_mys typedef const MYSQLND_FIELD *(*func_mysqlnd_res__fetch_fields)(MYSQLND_RES * const result TSRMLS_DC); typedef enum_func_status (*func_mysqlnd_res__read_result_metadata)(MYSQLND_RES * result, MYSQLND_CONN_DATA * conn TSRMLS_DC); -typedef unsigned long * (*func_mysqlnd_res__fetch_lengths)(MYSQLND_RES * const result TSRMLS_DC); +typedef php_uint_t * (*func_mysqlnd_res__fetch_lengths)(MYSQLND_RES * const result TSRMLS_DC); - typedef enum_func_status (*func_mysqlnd_res__store_result_fetch_data)(MYSQLND_CONN_DATA * const conn, MYSQLND_RES * result, MYSQLND_RES_METADATA *meta, zend_bool binary_protocol TSRMLS_DC); + typedef enum_func_status (*func_mysqlnd_res__store_result_fetch_data)(MYSQLND_CONN_DATA * const conn, MYSQLND_RES * result, MYSQLND_RES_METADATA * meta, MYSQLND_MEMORY_POOL_CHUNK *** row_buffers, zend_bool binary_protocol TSRMLS_DC); typedef void (*func_mysqlnd_res__free_result_buffers)(MYSQLND_RES * result TSRMLS_DC); /* private */ typedef enum_func_status (*func_mysqlnd_res__free_result)(MYSQLND_RES * result, zend_bool implicit TSRMLS_DC); @@@ -942,14 -952,11 +952,11 @@@ struct st_mysqlnd_connection_dat The result set objects can determine by inspecting 'quit_sent' whether the connection is still valid. */ - unsigned int refcount; + php_uint_t refcount; /* Temporal storage for mysql_query */ - unsigned int field_count; + php_uint_t field_count; - /* persistent connection */ - zend_bool persistent; - /* options */ MYSQLND_OPTIONS * options; MYSQLND_OPTIONS options_impl; @@@ -991,31 -1003,51 +1003,50 @@@ struct st_mysqlnd_result_metadat }; - struct st_mysqlnd_buffered_result - { - zval **data; - zval **data_cursor; - MYSQLND_MEMORY_POOL_CHUNK **row_buffers; - uint64_t row_count; - uint64_t initialized_rows; + #define def_mysqlnd_buffered_result_parent \ + MYSQLND_MEMORY_POOL_CHUNK **row_buffers; \ + uint64_t row_count; \ + uint64_t initialized_rows; \ + \ + /* Column lengths of current row - both buffered and unbuffered. For buffered results it duplicates the data found in **data */ \ + unsigned long *lengths; \ + \ + MYSQLND_MEMORY_POOL *result_set_memory_pool; \ + \ + unsigned int references; \ + \ + MYSQLND_ERROR_INFO error_info; \ + \ + unsigned int field_count; \ + zend_bool ps; \ + zend_bool persistent; \ + struct st_mysqlnd_result_buffered_methods m; \ + enum mysqlnd_buffered_type type; \ + void * unused1; \ + void * unused2; \ + void * unused3 - /* - Column lengths of current row - both buffered and unbuffered. - For buffered results it duplicates the data found in **data - */ - php_uint_t *lengths; + + struct st_mysqlnd_buffered_result_parent + { + def_mysqlnd_buffered_result_parent; + }; - MYSQLND_MEMORY_POOL *result_set_memory_pool; - + struct st_mysqlnd_buffered_result_zval + { + def_mysqlnd_buffered_result_parent; - php_uint_t references; + zval **data; + zval **data_cursor; + }; - MYSQLND_ERROR_INFO error_info; - php_uint_t field_count; - zend_bool ps; - zend_bool persistent; + struct st_mysqlnd_buffered_result_c + { + def_mysqlnd_buffered_result_parent; - struct st_mysqlnd_result_buffered_methods m; + zend_uchar *initialized; /* every row is a single bit */ + uint64_t current_row; }; diff --cc ext/mysqlnd/mysqlnd_wireprotocol.c index fe821e9,ecce71d..375fa09 --- a/ext/mysqlnd/mysqlnd_wireprotocol.c +++ b/ext/mysqlnd/mysqlnd_wireprotocol.c @@@ -1572,14 -1572,14 +1572,14 @@@ php_mysqlnd_rowp_read_binary_protocol(M } /* }}} */ - /* {{{ php_mysqlnd_rowp_read_text_protocol */ enum_func_status - php_mysqlnd_rowp_read_text_protocol(MYSQLND_MEMORY_POOL_CHUNK * row_buffer, zval ** fields, + php_mysqlnd_rowp_read_text_protocol_aux(MYSQLND_MEMORY_POOL_CHUNK * row_buffer, zval ** fields, - unsigned int field_count, const MYSQLND_FIELD * fields_metadata, + php_uint_t field_count, const MYSQLND_FIELD * fields_metadata, - zend_bool as_int_or_float, MYSQLND_STATS * stats TSRMLS_DC) + zend_bool as_int_or_float, zend_bool copy_data, MYSQLND_STATS * stats TSRMLS_DC) { + - unsigned int i; + php_uint_t i; zend_bool last_field_was_string = FALSE; zval **current_field, **end_field, **start_field; zend_uchar * p = row_buffer->ptr; @@@ -1606,9 -1606,9 +1606,9 @@@ /* Don't reverse the order. It is significant!*/ zend_uchar *this_field_len_pos = p; /* php_mysqlnd_net_field_length() call should be after *this_field_len_pos = p; */ - unsigned long len = php_mysqlnd_net_field_length(&p); + php_uint_t len = php_mysqlnd_net_field_length(&p); - if (current_field > start_field && last_field_was_string) { + if (copy_data == FALSE && current_field > start_field && last_field_was_string) { /* Normal queries: We have to put \0 now to the end of the previous field, if it was @@@ -1731,18 -1731,18 +1731,18 @@@ later in this function there will be an advancement. */ p -= len; - if (Z_TYPE_PP(current_field) == IS_LONG) { - bit_area += 1 + sprintf((char *)start, "%ld", Z_LVAL_PP(current_field)); + if (Z_TYPE_PP(current_field) == IS_INT) { + bit_area += 1 + sprintf((char *)start, ZEND_INT_FMT, Z_IVAL_PP(current_field)); - ZVAL_STRINGL(*current_field, (char *) start, bit_area - start - 1, 0); + ZVAL_STRINGL(*current_field, (char *) start, bit_area - start - 1, copy_data); } else if (Z_TYPE_PP(current_field) == IS_STRING){ - memcpy(bit_area, Z_STRVAL_PP(current_field), Z_STRLEN_PP(current_field)); - bit_area += Z_STRLEN_PP(current_field); + memcpy(bit_area, Z_STRVAL_PP(current_field), Z_STRSIZE_PP(current_field)); + bit_area += Z_STRSIZE_PP(current_field); *bit_area++ = '\0'; zval_dtor(*current_field); - ZVAL_STRINGL(*current_field, (char *) start, bit_area - start - 1, 0); + ZVAL_STRINGL(*current_field, (char *) start, bit_area - start - 1, copy_data); } } else { - ZVAL_STRINGL(*current_field, (char *)p, len, 0); + ZVAL_STRINGL(*current_field, (char *)p, len, copy_data); } p += len; last_field_was_string = TRUE; diff --cc ext/mysqlnd/mysqlnd_wireprotocol.h index 43aff57,7e8b962..f658b25 --- a/ext/mysqlnd/mysqlnd_wireprotocol.h +++ b/ext/mysqlnd/mysqlnd_wireprotocol.h @@@ -312,8 -312,12 +312,12 @@@ enum_func_status php_mysqlnd_rowp_read_ zend_bool as_int_or_float, MYSQLND_STATS * stats TSRMLS_DC); - enum_func_status php_mysqlnd_rowp_read_text_protocol(MYSQLND_MEMORY_POOL_CHUNK * row_buffer, zval ** fields, + enum_func_status php_mysqlnd_rowp_read_text_protocol_zval(MYSQLND_MEMORY_POOL_CHUNK * row_buffer, zval ** fields, - unsigned int field_count, const MYSQLND_FIELD * fields_metadata, ++ php_uint_t field_count, const MYSQLND_FIELD * fields_metadata, + zend_bool as_int_or_float, MYSQLND_STATS * stats TSRMLS_DC); + + enum_func_status php_mysqlnd_rowp_read_text_protocol_c(MYSQLND_MEMORY_POOL_CHUNK * row_buffer, zval ** fields, - unsigned int field_count, const MYSQLND_FIELD * fields_metadata, + php_uint_t field_count, const MYSQLND_FIELD * fields_metadata, zend_bool as_int_or_float, MYSQLND_STATS * stats TSRMLS_DC); diff --cc ext/opcache/zend_accelerator_util_funcs.c index 8de2426,ae33e76..d17bc99 --- a/ext/opcache/zend_accelerator_util_funcs.c +++ b/ext/opcache/zend_accelerator_util_funcs.c @@@ -237,11 -237,13 +237,13 @@@ static zend_ast *zend_ast_clone(zend_as if ((Z_TYPE_P(ast->u.val) & IS_CONSTANT_TYPE_MASK) >= IS_ARRAY) { switch ((Z_TYPE_P(ast->u.val) & IS_CONSTANT_TYPE_MASK)) { case IS_STRING: - case IS_CONSTANT: + case IS_CONSTANT: - Z_STRVAL_P(node->u.val) = (char *) interned_estrndup(Z_STRVAL_P(ast->u.val), Z_STRLEN_P(ast->u.val)); + Z_STRVAL_P(node->u.val) = (char *) interned_estrndup(Z_STRVAL_P(ast->u.val), Z_STRSIZE_P(ast->u.val)); break; case IS_ARRAY: - case IS_CONSTANT_ARRAY: + #if ZEND_EXTENSION_API_NO <= PHP_5_5_API_NO + case IS_CONSTANT_ARRAY: + #endif if (ast->u.val->value.ht && ast->u.val->value.ht != &EG(symbol_table)) { ALLOC_HASHTABLE(node->u.val->value.ht); zend_hash_clone_zval(node->u.val->value.ht, ast->u.val->value.ht, 0); @@@ -295,11 -297,13 +297,13 @@@ static inline zval* zend_clone_zval(zva switch ((Z_TYPE_P(ret) & ~IS_CONSTANT_INDEX)) { #endif case IS_STRING: - case IS_CONSTANT: + case IS_CONSTANT: - Z_STRVAL_P(ret) = (char *) interned_estrndup(Z_STRVAL_P(ret), Z_STRLEN_P(ret)); + Z_STRVAL_P(ret) = (char *) interned_estrndup(Z_STRVAL_P(ret), Z_STRSIZE_P(ret)); break; case IS_ARRAY: - case IS_CONSTANT_ARRAY: + #if ZEND_EXTENSION_API_NO <= PHP_5_5_API_NO + case IS_CONSTANT_ARRAY: + #endif if (ret->value.ht && ret->value.ht != &EG(symbol_table)) { ALLOC_HASHTABLE(ret->value.ht); zend_hash_clone_zval(ret->value.ht, src->value.ht, 0); @@@ -417,11 -421,13 +421,13 @@@ static void zend_hash_clone_zval(HashTa switch ((Z_TYPE_P((zval*)p->pDataPtr) & ~IS_CONSTANT_INDEX)) { #endif case IS_STRING: - case IS_CONSTANT: + case IS_CONSTANT: - Z_STRVAL_P(ppz) = (char *) interned_estrndup(Z_STRVAL_P((zval*)p->pDataPtr), Z_STRLEN_P((zval*)p->pDataPtr)); + Z_STRVAL_P(ppz) = (char *) interned_estrndup(Z_STRVAL_P((zval*)p->pDataPtr), Z_STRSIZE_P((zval*)p->pDataPtr)); break; case IS_ARRAY: - case IS_CONSTANT_ARRAY: + #if ZEND_EXTENSION_API_NO <= PHP_5_5_API_NO + case IS_CONSTANT_ARRAY: + #endif if (((zval*)p->pDataPtr)->value.ht && ((zval*)p->pDataPtr)->value.ht != &EG(symbol_table)) { ALLOC_HASHTABLE(ppz->value.ht); zend_hash_clone_zval(ppz->value.ht, ((zval*)p->pDataPtr)->value.ht, 0); diff --cc ext/opcache/zend_persist_calc.c index 8d42b1d,a01d834..95da751 --- a/ext/opcache/zend_persist_calc.c +++ b/ext/opcache/zend_persist_calc.c @@@ -126,10 -126,12 +126,12 @@@ static uint zend_persist_zval_calc(zva #endif case IS_STRING: case IS_CONSTANT: - ADD_INTERNED_STRING(Z_STRVAL_P(z), Z_STRLEN_P(z) + 1); + ADD_INTERNED_STRING(Z_STRVAL_P(z), Z_STRSIZE_P(z) + 1); break; case IS_ARRAY: + #if ZEND_EXTENSION_API_NO <= PHP_5_5_API_NO case IS_CONSTANT_ARRAY: + #endif ADD_DUP_SIZE(z->value.ht, sizeof(HashTable)); ADD_SIZE(zend_hash_persist_calc(z->value.ht, (int (*)(void* TSRMLS_DC)) zend_persist_zval_ptr_calc, sizeof(zval**) TSRMLS_CC)); break; diff --cc ext/phar/phar_object.c index 17d51e9,407edda..77ba903 --- a/ext/phar/phar_object.c +++ b/ext/phar/phar_object.c @@@ -1939,13 -1934,15 +1939,15 @@@ PHP_METHOD(Phar, buildFromIterator */ PHP_METHOD(Phar, count) { + /* mode can be ignored, maximum depth is 1 */ + long mode; PHAR_ARCHIVE_OBJECT(); - if (zend_parse_parameters_none() == FAILURE) { - return; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &mode) == FAILURE) { + RETURN_FALSE; } - RETURN_LONG(zend_hash_num_elements(&phar_obj->arc.archive->manifest)); + RETURN_INT(zend_hash_num_elements(&phar_obj->arc.archive->manifest)); } /* }}} */ diff --cc ext/reflection/php_reflection.c index 3110145,703e141..ac6f1e9 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@@ -733,9 -733,9 +733,9 @@@ static void _parameter_string(string *s *zv = *precv->op2.zv; zval_copy_ctor(zv); INIT_PZVAL(zv); - zval_update_constant_ex(&zv, (void*)1, fptr->common.scope TSRMLS_CC); + zval_update_constant_ex(&zv, 1, fptr->common.scope TSRMLS_CC); if (Z_TYPE_P(zv) == IS_BOOL) { - if (Z_LVAL_P(zv)) { + if (Z_IVAL_P(zv)) { string_write(str, "true", sizeof("true")-1); } else { string_write(str, "false", sizeof("false")-1); diff --cc ext/spl/spl_observer.c index 5f1f740,91830ab..f7951b9 --- a/ext/spl/spl_observer.c +++ b/ext/spl/spl_observer.c @@@ -623,12 -622,28 +624,28 @@@ SPL_METHOD(SplObjectStorage, contains SPL_METHOD(SplObjectStorage, count) { spl_SplObjectStorage *intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC); - - if (zend_parse_parameters_none() == FAILURE) { - long mode = COUNT_NORMAL; ++ php_int_t mode = COUNT_NORMAL; + - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &mode) == FAILURE) { ++ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|i", &mode) == FAILURE) { return; } - + + if (mode == COUNT_RECURSIVE) { - long ret = zend_hash_num_elements(&intern->storage); ++ php_int_t ret = zend_hash_num_elements(&intern->storage); + HashPosition position; + zval *element; + + for (zend_hash_internal_pointer_reset_ex(&intern->storage, &position); + zend_hash_get_current_data_ex(&intern->storage, (void**) &element, &position) == SUCCESS; + zend_hash_move_forward_ex(&intern->storage, &position)) { + ret += php_count_recursive(element, mode TSRMLS_CC); + } + - RETURN_LONG(ret); ++ RETURN_INT(ret); + return; + } + - RETURN_LONG(zend_hash_num_elements(&intern->storage)); + RETURN_INT(zend_hash_num_elements(&intern->storage)); } /* }}} */ /* {{{ proto void SplObjectStorage::rewind() diff --cc ext/standard/array.c index 646d122,4f98331..357b905 --- a/ext/standard/array.c +++ b/ext/standard/array.c @@@ -274,9 -271,9 +271,9 @@@ PHP_FUNCTION(ksort } /* }}} */ - static php_int_t php_count_recursive(zval *array, php_int_t mode TSRMLS_DC) /* {{{ */ -PHPAPI int php_count_recursive(zval *array, long mode TSRMLS_DC) /* {{{ */ ++PHPAPI php_int_t php_count_recursive(zval *array, php_int_t mode TSRMLS_DC) /* {{{ */ { - long cnt = 0; + php_int_t cnt = 0; zval **element; if (Z_TYPE_P(array) == IS_ARRAY) { @@@ -336,12 -333,17 +333,17 @@@ PHP_FUNCTION(count #ifdef HAVE_SPL /* if not and the object implements Countable we call its count() method */ if (Z_OBJ_HT_P(array)->get_class_entry && instanceof_function(Z_OBJCE_P(array), spl_ce_Countable TSRMLS_CC)) { - zend_call_method_with_0_params(&array, NULL, NULL, "count", &retval); + zval *mode_zv; + MAKE_STD_ZVAL(mode_zv); - ZVAL_LONG(mode_zv, mode); ++ ZVAL_INT(mode_zv, mode); + zend_call_method_with_1_params(&array, NULL, NULL, "count", &retval, mode_zv); if (retval) { - convert_to_long_ex(&retval); - RETVAL_LONG(Z_LVAL_P(retval)); + convert_to_int_ex(&retval); + RETVAL_INT(Z_IVAL_P(retval)); zval_ptr_dtor(&retval); } + zval_dtor(mode_zv); + efree(mode_zv); return; } #endif