From: Dmitry Stogov Date: Mon, 4 Aug 2014 09:56:27 +0000 (+0400) Subject: Merge branch 'master' into phpng X-Git-Tag: POST_PHPNG_MERGE~40 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7301994c28d548c5a4eda6a3a4ae0fab6af04636;p=php Merge branch 'master' into phpng * master: (46 commits) PHP_INT_MIN and _MAX tests NEWS and UPGRADING Added PHP_INT_MIN Fix wrong lenght size Bug #51096 - Remove unnecessary ? for first/last day of Moved streams related functions to xp_ssl.c Remove duplicate NEWS Update NEWS Update NEWS Update NEWS BFN BFN Fixed bug #67715 (php-milter does not build and crashes randomly). We need to turn off any strict mode here for this warning to show up Disable restrictions regarding arrays in constants at run-time. For the discussion around it, see the thread on the mailing list: http://www.mail-archive.com/internals@lists.php.net/msg68245.html Revert "Fix bug #67064 in a BC safe way" Updated NEWS for #67693 Updated NEWS for #67693 Fixed bug #67693 - incorrect push to the empty array add missing entry to NEWS ... Conflicts: Zend/tests/errmsg_040.phpt Zend/tests/ns_059.phpt Zend/zend_language_parser.y Zend/zend_vm_def.h ext/openssl/openssl.c ext/reflection/php_reflection.c ext/session/session.c ext/spl/spl_directory.c ext/spl/spl_iterators.c ext/sqlite3/sqlite3.c ext/standard/array.c --- 7301994c28d548c5a4eda6a3a4ae0fab6af04636 diff --cc Zend/tests/errmsg_040.phpt index f3d0afcf0a,cda8d4c76a..d5d2bf38d3 --- a/Zend/tests/errmsg_040.phpt +++ b/Zend/tests/errmsg_040.phpt @@@ -6,7 -6,9 +6,7 @@@ errmsg: arrays are not allowed in clas class test { const TEST = array(1,2,3); } -- + var_dump(test::TEST); - echo "Done\n"; ?> --EXPECTF-- diff --cc Zend/tests/ns_059.phpt index ea66037b43,701e448812..301a6fc830 --- a/Zend/tests/ns_059.phpt +++ b/Zend/tests/ns_059.phpt @@@ -3,6 -3,9 +3,7 @@@ --FILE-- --EXPECTF-- - Fatal error: Arrays are not allowed as constants in %sns_059.php on line 2 - + array(0) { + } diff --cc Zend/zend_ast.c index 824c0d5c3e,54448ac286..180e55404c --- a/Zend/zend_ast.c +++ b/Zend/zend_ast.c @@@ -364,9 -335,9 +362,9 @@@ ZEND_API void zend_ast_evaluate(zval *r zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC); zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC); { -- zval *tmp; ++ zval tmp; zend_fetch_dimension_by_zval(&tmp, &op1, &op2 TSRMLS_CC); -- ZVAL_ZVAL(result, tmp, 1, 1); ++ ZVAL_ZVAL(result, &tmp, 1, 1); } zval_dtor(&op1); zval_dtor(&op2); diff --cc Zend/zend_compile.c index dee8bb85c0,7c979d56b7..f099802a62 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@@ -5844,14 -5442,12 +5844,8 @@@ void zend_do_declare_property(znode *va } /* }}} */ -void zend_do_declare_class_constant(znode *var_name, const znode *value TSRMLS_DC) /* {{{ */ +void zend_do_declare_class_constant(znode *var_name, znode *value TSRMLS_DC) /* {{{ */ { - if ((Z_TYPE(value->u.constant) == IS_ARRAY) || - (Z_TYPE(value->u.constant) == IS_CONSTANT_AST && - Z_ASTVAL(value->u.constant)->kind == ZEND_INIT_ARRAY)) { - zend_error_noreturn(E_COMPILE_ERROR, "Arrays are not allowed in class constants"); - return; - } - zval *property; - const char *cname = NULL; - zend_ulong hash; - if ((CG(active_class_entry)->ce_flags & ZEND_ACC_TRAIT) == ZEND_ACC_TRAIT) { zend_error_noreturn(E_COMPILE_ERROR, "Traits cannot have constants"); return; @@@ -7772,14 -7291,8 +7766,8 @@@ void zend_do_use_const(znode *ns_name, void zend_do_declare_constant(znode *name, znode *value TSRMLS_DC) /* {{{ */ { zend_op *opline; - zval **ns_name; + zval *ns_name; - if ((Z_TYPE(value->u.constant) == IS_ARRAY) || - (Z_TYPE(value->u.constant) == IS_CONSTANT_AST && - Z_ASTVAL(value->u.constant)->kind == ZEND_INIT_ARRAY)) { - zend_error_noreturn(E_COMPILE_ERROR, "Arrays are not allowed as constants"); - } - if (zend_get_ct_const(&name->u.constant, 0 TSRMLS_CC)) { zend_error_noreturn(E_COMPILE_ERROR, "Cannot redeclare constant '%s'", Z_STRVAL(name->u.constant)); } diff --cc Zend/zend_execute.c index 282781a9ab,6ada04e1cb..48dbc7a497 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@@ -1343,24 -1372,20 +1343,29 @@@ static zend_always_inline void zend_fet } } -ZEND_API void zend_fetch_dimension_by_zval(zval **result, zval *container, zval *dim TSRMLS_DC) { - temp_variable tmp; - zend_fetch_dimension_address_read(&tmp, container, dim, IS_TMP_VAR, BP_VAR_R TSRMLS_CC); - *result = tmp.var.ptr; +static zend_never_inline void zend_fetch_dimension_address_read_R(zval *result, zval *container, zval *dim, int dim_type TSRMLS_DC) +{ + zend_fetch_dimension_address_read(result, container, dim, dim_type, BP_VAR_R TSRMLS_CC); } -static void zend_fetch_property_address(temp_variable *result, zval **container_ptr, zval *prop_ptr, const zend_literal *key, int type TSRMLS_DC) +static zend_never_inline void zend_fetch_dimension_address_read_IS(zval *result, zval *container, zval *dim, int dim_type TSRMLS_DC) { - zval *container = *container_ptr; + zend_fetch_dimension_address_read(result, container, dim, dim_type, BP_VAR_IS TSRMLS_CC); +} + ++ZEND_API void zend_fetch_dimension_by_zval(zval *result, zval *container, zval *dim TSRMLS_DC) ++{ ++ zend_fetch_dimension_address_read_R(result, container, dim, IS_TMP_VAR TSRMLS_CC); ++} + +static void zend_fetch_property_address(zval *result, zval *container_ptr, zval *prop_ptr, void **cache_slot, int type, int is_ref TSRMLS_DC) +{ + zval *container = container_ptr; + + ZVAL_DEREF(container); if (Z_TYPE_P(container) != IS_OBJECT) { if (container == &EG(error_zval)) { - result->var.ptr_ptr = &EG(error_zval_ptr); - PZVAL_LOCK(EG(error_zval_ptr)); + ZVAL_INDIRECT(result, &EG(error_zval)); return; } diff --cc Zend/zend_execute.h index 812d4141b4,d151c3413d..3ebf1c95f1 --- a/Zend/zend_execute.h +++ b/Zend/zend_execute.h @@@ -285,10 -356,12 +285,12 @@@ ZEND_API zend_bool zend_is_executing(TS ZEND_API void zend_set_timeout(long 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(zend_string *class_name, int fetch_type TSRMLS_DC); +ZEND_API zend_class_entry *zend_fetch_class_by_name(zend_string *class_name, const zval *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); ++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 43e20cd9ce,7502723564..38b1bcc2b4 --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@@ -1037,23 -1041,25 +1041,25 @@@ static_operation | '(' static_scalar_value ')' { $$ = $2; } ; - - scalar: - T_STRING_VARNAME { $$ = $1; } - | class_name_scalar { $$ = $1; } - | class_constant { $$ = $1; } + general_constant: + class_constant { $$ = $1; } | namespace_name { zend_do_fetch_constant(&$$, NULL, &$1, ZEND_RT, 1 TSRMLS_CC); } | 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_RT, 0 TSRMLS_CC); } - | 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_RT, 0 TSRMLS_CC); } + | T_NS_SEPARATOR namespace_name { zval tmp; ZVAL_NEW_STR(&tmp, STR_ALLOC(Z_STRLEN($2.u.constant)+1, 0)); Z_STRVAL(tmp)[0] = '\\'; memcpy(Z_STRVAL(tmp) + 1, Z_STRVAL($2.u.constant), Z_STRLEN($2.u.constant)+1); if (Z_DELREF($2.u.constant) == 0) {efree(Z_STR($2.u.constant));} Z_STR($2.u.constant) = Z_STR(tmp); zend_do_fetch_constant(&$$, NULL, &$2, ZEND_RT, 0 TSRMLS_CC); } - | common_scalar { $$ = $1; } - | '"' encaps_list '"' { $$ = $2; } - | T_START_HEREDOC encaps_list T_END_HEREDOC { $$ = $2; } - | T_CLASS_C { if (Z_TYPE($1.u.constant) == IS_CONSTANT) {zend_do_fetch_constant(&$$, NULL, &$1, ZEND_RT, 1 TSRMLS_CC);} else {$$ = $1;} } ; + scalar: + T_STRING_VARNAME { $$ = $1; } + | general_constant { $$ = $1; } + | class_name_scalar { $$ = $1; } + | common_scalar { $$ = $1; } + | '"' encaps_list '"' { $$ = $2; } + | T_START_HEREDOC encaps_list T_END_HEREDOC { $$ = $2; } + | T_CLASS_C { if (Z_TYPE($1.u.constant) == IS_CONSTANT) {zend_do_fetch_constant(&$$, NULL, &$1, ZEND_RT, 1 TSRMLS_CC);} else {$$ = $1;} } + ; static_array_pair_list: - /* empty */ { $$.op_type = IS_CONST; INIT_PZVAL(&$$.u.constant); array_init(&$$.u.constant); $$.u.ast = zend_ast_create_constant(&$$.u.constant); } + /* empty */ { $$.op_type = IS_CONST; array_init(&$$.u.constant); $$.u.ast = zend_ast_create_constant(&$$.u.constant); } | non_empty_static_array_pair_list possible_comma { zend_ast_dynamic_shrink(&$1.u.ast); $$ = $1; } ; diff --cc ext/openssl/openssl.c index cd8a156e20,26cb7b01c3..cf89f8d17f --- a/ext/openssl/openssl.c +++ b/ext/openssl/openssl.c @@@ -838,14 -841,14 +838,14 @@@ static int add_oid_section(struct php_x req->config_filename, req->var, req->req_config TSRMLS_CC) == FAILURE) return FAILURE #define SET_OPTIONAL_STRING_ARG(key, varname, defval) \ - if (optional_args && (item = zend_hash_str_find(Z_ARRVAL_P(optional_args), key, sizeof(key)-1)) != NULL) \ - if (optional_args && zend_hash_find(Z_ARRVAL_P(optional_args), key, sizeof(key), (void**)&item) == SUCCESS && Z_TYPE_PP(item) == IS_STRING) \ - varname = Z_STRVAL_PP(item); \ ++ if (optional_args && (item = zend_hash_str_find(Z_ARRVAL_P(optional_args), key, sizeof(key)-1)) != NULL && Z_TYPE_P(item) == IS_STRING) \ + varname = Z_STRVAL_P(item); \ else \ varname = defval #define SET_OPTIONAL_LONG_ARG(key, varname, defval) \ - if (optional_args && (item = zend_hash_str_find(Z_ARRVAL_P(optional_args), key, sizeof(key)-1)) != NULL) \ - if (optional_args && zend_hash_find(Z_ARRVAL_P(optional_args), key, sizeof(key), (void**)&item) == SUCCESS && Z_TYPE_PP(item) == IS_LONG) \ - varname = Z_LVAL_PP(item); \ ++ if (optional_args && (item = zend_hash_str_find(Z_ARRVAL_P(optional_args), key, sizeof(key)-1)) != NULL && Z_TYPE_P(item) == IS_LONG) \ + varname = Z_LVAL_P(item); \ else \ varname = defval @@@ -904,8 -907,9 +904,9 @@@ static int php_openssl_parse_config(str } } - if (req->priv_key_encrypt && optional_args && (item = zend_hash_str_find(Z_ARRVAL_P(optional_args), "encrypt_key_cipher", sizeof("encrypt_key_cipher")-1)) != NULL) { - if (req->priv_key_encrypt && optional_args && zend_hash_find(Z_ARRVAL_P(optional_args), "encrypt_key_cipher", sizeof("encrypt_key_cipher"), (void**)&item) == SUCCESS - && Z_TYPE_PP(item) == IS_LONG) { - long cipher_algo = Z_LVAL_PP(item); ++ if (req->priv_key_encrypt && optional_args && (item = zend_hash_str_find(Z_ARRVAL_P(optional_args), "encrypt_key_cipher", sizeof("encrypt_key_cipher")-1)) != NULL ++ && Z_TYPE_P(item) == IS_LONG) { + long cipher_algo = Z_LVAL_P(item); const EVP_CIPHER* cipher = php_openssl_get_evp_cipher_from_algo(cipher_algo); if (cipher == NULL) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown cipher algorithm for private key."); @@@ -2435,8 -2401,8 +2390,8 @@@ PHP_FUNCTION(openssl_pkcs12_export_to_f } /* parse extra config from args array, promote this to an extra function */ - if (args && (item = zend_hash_str_find(Z_ARRVAL_P(args), "friendly_name", sizeof("friendly_name")-1)) != NULL) - if (args && zend_hash_find(Z_ARRVAL_P(args), "friendly_name", sizeof("friendly_name"), (void**)&item) == SUCCESS && Z_TYPE_PP(item) == IS_STRING) - friendly_name = Z_STRVAL_PP(item); ++ if (args && (item = zend_hash_str_find(Z_ARRVAL_P(args), "friendly_name", sizeof("friendly_name")-1)) != NULL && Z_TYPE_P(item) == IS_STRING) + friendly_name = Z_STRVAL_P(item); /* certpbe (default RC2-40) keypbe (default 3DES) friendly_caname @@@ -2513,10 -2479,10 +2468,10 @@@ PHP_FUNCTION(openssl_pkcs12_export } /* parse extra config from args array, promote this to an extra function */ - if (args && (item = zend_hash_str_find(Z_ARRVAL_P(args), "friendly_name", sizeof("friendly_name")-1)) != NULL) - if (args && zend_hash_find(Z_ARRVAL_P(args), "friendly_name", sizeof("friendly_name"), (void**)&item) == SUCCESS && Z_TYPE_PP(item) == IS_STRING) - friendly_name = Z_STRVAL_PP(item); ++ if (args && (item = zend_hash_str_find(Z_ARRVAL_P(args), "friendly_name", sizeof("friendly_name")-1)) != NULL && Z_TYPE_P(item) == IS_STRING) + friendly_name = Z_STRVAL_P(item); - if (args && zend_hash_find(Z_ARRVAL_P(args), "extracerts", sizeof("extracerts"), (void**)&item) == SUCCESS) + if (args && (item = zend_hash_str_find(Z_ARRVAL_P(args), "extracerts", sizeof("extracerts")-1)) != NULL) ca = php_array_to_X509_sk(item TSRMLS_CC); /* end parse extra config */ diff --cc ext/openssl/xp_ssl.c index bf72fed434,7ecc20b709..7c7ba235d9 --- a/ext/openssl/xp_ssl.c +++ b/ext/openssl/xp_ssl.c @@@ -263,6 -267,61 +263,52 @@@ static int verify_callback(int preverif } /* }}} */ + static int php_x509_fingerprint_cmp(X509 *peer, const char *method, const char *expected TSRMLS_DC) + { + char *fingerprint; + int fingerprint_len; + int result = -1; + + if (php_openssl_x509_fingerprint(peer, method, 0, &fingerprint, &fingerprint_len TSRMLS_CC) == SUCCESS) { + result = strcmp(expected, fingerprint); + efree(fingerprint); + } + + return result; + } + + static zend_bool php_x509_fingerprint_match(X509 *peer, zval *val TSRMLS_DC) + { + if (Z_TYPE_P(val) == IS_STRING) { + const char *method = NULL; + + switch (Z_STRLEN_P(val)) { + case 32: + method = "md5"; + break; + + case 40: + method = "sha1"; + break; + } + + return method && php_x509_fingerprint_cmp(peer, method, Z_STRVAL_P(val) TSRMLS_CC) == 0; + } else if (Z_TYPE_P(val) == IS_ARRAY) { - HashPosition pos; - zval **current; - char *key; - uint key_len; - ulong key_index; - - for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(val), &pos); - zend_hash_get_current_data_ex(Z_ARRVAL_P(val), (void **)¤t, &pos) == SUCCESS; - zend_hash_move_forward_ex(Z_ARRVAL_P(val), &pos) - ) { - int key_type = zend_hash_get_current_key_ex(Z_ARRVAL_P(val), &key, &key_len, &key_index, 0, &pos); ++ zval *current; ++ zend_string *key; + - if (key_type == HASH_KEY_IS_STRING - && Z_TYPE_PP(current) == IS_STRING - && php_x509_fingerprint_cmp(peer, key, Z_STRVAL_PP(current) TSRMLS_CC) != 0 ++ ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(val), key, current) { ++ if (key && Z_TYPE_P(current) == IS_STRING ++ && php_x509_fingerprint_cmp(peer, key->val, Z_STRVAL_P(current) TSRMLS_CC) != 0 + ) { + return 0; + } - } ++ } ZEND_HASH_FOREACH_END(); + return 1; + } + return 0; + } + static zend_bool matches_wildcard_name(const char *subjectname, const char *certname) /* {{{ */ { char *wildcard = NULL; diff --cc ext/readline/readline_cli.c index 84d27ca046,9c27acb193..0ca9daf8ff --- a/ext/readline/readline_cli.c +++ b/ext/readline/readline_cli.c @@@ -587,8 -588,9 +590,9 @@@ static int readline_shell_run(TSRMLS_D char *line; size_t size = 4096, pos = 0, len; char *code = emalloc(size); - char *prompt = cli_get_prompt("php", '>' TSRMLS_CC); + zend_string *prompt = cli_get_prompt("php", '>' TSRMLS_CC); char *history_file; + int history_lines_to_write = 0; if (PG(auto_prepend_file) && PG(auto_prepend_file)[0]) { zend_file_handle *prepend_file_p; @@@ -681,10 -695,9 +695,9 @@@ php_last_char = '\0'; } - write_history(history_file); free(history_file); efree(code); - efree(prompt); + STR_RELEASE(prompt); return EG(exit_status); } /* }}} */ diff --cc ext/reflection/php_reflection.c index 508ddceacd,8e5fcadef4..fd7569bcb8 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@@ -4260,8 -4308,8 +4260,8 @@@ ZEND_METHOD(reflection_class, newInstan METHOD_NOTSTATIC(reflection_class_ptr); GET_REFLECTION_OBJECT_PTR(ce); - if (ce->create_object != NULL) { - zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, "Class %s is an internal class that cannot be instantiated without invoking its constructor", ce->name->val); + if (ce->create_object != NULL && ce->ce_flags & ZEND_ACC_FINAL_CLASS) { - zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, "Class %s is an internal class marked as final that cannot be instantiated without invoking its constructor", ce->name); ++ zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, "Class %s is an internal class marked as final that cannot be instantiated without invoking its constructor", ce->name->val); } object_init_ex(return_value, ce); diff --cc ext/session/session.c index ff04462ca4,5b82ae7ffe..46ffa566c8 --- a/ext/session/session.c +++ b/ext/session/session.c @@@ -296,11 -300,12 +296,12 @@@ PHPAPI zend_string *php_session_create_ gettimeofday(&tv, NULL); - if (zend_hash_find(&EG(symbol_table), "_SERVER", sizeof("_SERVER"), (void **) &array) == SUCCESS && - Z_TYPE_PP(array) == IS_ARRAY && - zend_hash_find(Z_ARRVAL_PP(array), "REMOTE_ADDR", sizeof("REMOTE_ADDR"), (void **) &token) == SUCCESS && - Z_TYPE_PP(token) == IS_STRING + if ((array = zend_hash_str_find(&EG(symbol_table).ht, "_SERVER", sizeof("_SERVER") - 1)) && + Z_TYPE_P(array) == IS_ARRAY && - (token = zend_hash_str_find(Z_ARRVAL_P(array), "REMOTE_ADDR", sizeof("REMOTE_ADDR") - 1)) ++ (token = zend_hash_str_find(Z_ARRVAL_P(array), "REMOTE_ADDR", sizeof("REMOTE_ADDR") - 1)) && ++ Z_TYPE_P(token) == IS_STRING ) { - remote_addr = Z_STRVAL_PP(token); + remote_addr = Z_STRVAL_P(token); } /* maximum 15+19+19+10 bytes */ diff --cc ext/soap/soap.c index 4e5a2b35ea,0453dc28e0..ec2c2f0c17 --- a/ext/soap/soap.c +++ b/ext/soap/soap.c @@@ -145,11 -147,13 +145,13 @@@ static void soap_error_handler(int erro #define FETCH_THIS_SERVICE(ss) \ { \ - zval **tmp; \ - if (zend_hash_find(Z_OBJPROP_P(this_ptr),"service", sizeof("service"), (void **)&tmp) != FAILURE) { \ + zval *tmp; \ + if ((tmp = zend_hash_str_find(Z_OBJPROP_P(getThis()),"service", sizeof("service")-1)) != NULL) { \ ss = (soapServicePtr)zend_fetch_resource(tmp TSRMLS_CC, -1, "service", NULL, 1, le_service); \ } else { \ - ss = NULL; \ + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can not fetch service object"); \ + SOAP_SERVER_END_CODE(); \ + return; \ } \ } diff --cc ext/spl/spl_directory.c index 9405dafa0d,c2f67ac395..f9fe83e26d --- a/ext/spl/spl_directory.c +++ b/ext/spl/spl_directory.c @@@ -2073,20 -2102,23 +2073,22 @@@ static int spl_filesystem_file_call(spl int result; int num_args = pass_num_args + (arg2 ? 2 : 1); - zval ***params = (zval***)safe_emalloc(num_args, sizeof(zval**), 0); + zval *params = (zval*)safe_emalloc(num_args, sizeof(zval), 0); - params[0] = &zresource_ptr; + params[0] = *zresource_ptr; if (arg2) { - params[1] = &arg2; + params[1] = *arg2; } - zend_get_parameters_array_ex(pass_num_args, params+(arg2 ? 2 : 1)); - - ZVAL_STRING(&z_fname, func_ptr->common.function_name, 0); + zend_get_parameters_array_ex(pass_num_args, params + (arg2 ? 2 : 1)); ++ ZVAL_UNDEF(&retval); ++ fci.size = sizeof(fci); fci.function_table = EG(function_table); - fci.object_ptr = NULL; - fci.function_name = &z_fname; - fci.retval_ptr_ptr = &retval; + fci.object = NULL; + fci.retval = &retval; fci.param_count = num_args; fci.params = params; fci.no_separation = 1; @@@ -2382,8 -2420,11 +2393,11 @@@ SPL_METHOD(SplFileObject, valid } if (SPL_HAS_FLAG(intern->flags, SPL_FILE_OBJECT_READ_AHEAD)) { - RETURN_BOOL(intern->u.file.current_line || intern->u.file.current_zval); + RETURN_BOOL(intern->u.file.current_line || !Z_ISUNDEF(intern->u.file.current_zval)); } else { + if(!intern->u.file.stream) { + RETURN_FALSE; + } RETVAL_BOOL(!php_stream_eof(intern->u.file.stream)); } } /* }}} */ @@@ -2414,13 -2460,18 +2433,18 @@@ SPL_METHOD(SplFileObject, current return; } + if(!intern->u.file.stream) { + zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Object not initialized"); + return; + } + - if (!intern->u.file.current_line && !intern->u.file.current_zval) { + if (!intern->u.file.current_line && Z_ISUNDEF(intern->u.file.current_zval)) { spl_filesystem_file_read_line(getThis(), intern, 1 TSRMLS_CC); } - if (intern->u.file.current_line && (!SPL_HAS_FLAG(intern->flags, SPL_FILE_OBJECT_READ_CSV) || !intern->u.file.current_zval)) { - RETURN_STRINGL(intern->u.file.current_line, intern->u.file.current_line_len, 1); - } else if (intern->u.file.current_zval) { - RETURN_ZVAL(intern->u.file.current_zval, 1, 0); + if (intern->u.file.current_line && (!SPL_HAS_FLAG(intern->flags, SPL_FILE_OBJECT_READ_CSV) || Z_ISUNDEF(intern->u.file.current_zval))) { + RETURN_STRINGL(intern->u.file.current_line, intern->u.file.current_line_len); + } else if (!Z_ISUNDEF(intern->u.file.current_zval)) { + RETURN_ZVAL(&intern->u.file.current_zval, 1, 0); } RETURN_FALSE; } /* }}} */ @@@ -2695,8 -2752,13 +2725,13 @@@ FileFunction(flock Flush the file */ SPL_METHOD(SplFileObject, fflush) { - spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + spl_filesystem_object *intern = Z_SPLFILESYSTEM_P(getThis()); + if(!intern->u.file.stream) { + zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Object not initialized"); + return; + } + RETURN_BOOL(!php_stream_flush(intern->u.file.stream)); } /* }}} */ @@@ -2704,8 -2766,15 +2739,15 @@@ Return current file position */ SPL_METHOD(SplFileObject, ftell) { - spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + spl_filesystem_object *intern = Z_SPLFILESYSTEM_P(getThis()); - long ret = php_stream_tell(intern->u.file.stream); + long ret; + + if(!intern->u.file.stream) { + zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Object not initialized"); + return; + } + + ret = php_stream_tell(intern->u.file.stream); if (ret == -1) { RETURN_FALSE; @@@ -2758,13 -2837,19 +2810,18 @@@ SPL_METHOD(SplFileObject, fgetc Get a line from file pointer and strip HTML tags */ SPL_METHOD(SplFileObject, fgetss) { - spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - zval *arg2 = NULL; - MAKE_STD_ZVAL(arg2); + spl_filesystem_object *intern = Z_SPLFILESYSTEM_P(getThis()); + zval arg2; + if(!intern->u.file.stream) { + zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Object not initialized"); + return; + } + if (intern->u.file.max_line_len > 0) { - ZVAL_LONG(arg2, intern->u.file.max_line_len); + ZVAL_LONG(&arg2, intern->u.file.max_line_len); } else { - ZVAL_LONG(arg2, 1024); + ZVAL_LONG(&arg2, 1024); } spl_filesystem_file_free_line(intern TSRMLS_CC); @@@ -2777,8 -2864,13 +2834,13 @@@ Output all remaining data from a file pointer */ SPL_METHOD(SplFileObject, fpassthru) { - spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + spl_filesystem_object *intern = Z_SPLFILESYSTEM_P(getThis()); + if(!intern->u.file.stream) { + zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Object not initialized"); + return; + } + RETURN_LONG(php_stream_passthru(intern->u.file.stream)); } /* }}} */ @@@ -2786,8 -2878,13 +2848,13 @@@ Implements a mostly ANSI compatible fscanf() */ SPL_METHOD(SplFileObject, fscanf) { - spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + spl_filesystem_object *intern = Z_SPLFILESYSTEM_P(getThis()); + if(!intern->u.file.stream) { + zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Object not initialized"); + return; + } + spl_filesystem_file_free_line(intern TSRMLS_CC); intern->u.file.current_line_num++; @@@ -2867,9 -2980,9 +2949,9 @@@ SPL_METHOD(SplFileObject, ftruncate Seek to specified line */ SPL_METHOD(SplFileObject, seek) { - spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + spl_filesystem_object *intern = Z_SPLFILESYSTEM_P(getThis()); long line_pos; - + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &line_pos) == FAILURE) { return; } diff --cc ext/spl/spl_iterators.c index ac9b9bef83,08841a710a..29c1c17e8a --- a/ext/spl/spl_iterators.c +++ b/ext/spl/spl_iterators.c @@@ -127,24 -128,30 +127,47 @@@ typedef struct _spl_recursive_it_iterat static zend_object_handlers spl_handlers_rec_it_it; static zend_object_handlers spl_handlers_dual_it; -#define SPL_FETCH_AND_CHECK_DUAL_IT(var, objzval) \ +static inline spl_recursive_it_object *spl_recursive_it_from_obj(zend_object *obj) /* {{{ */ { + return (spl_recursive_it_object*)((char*)(obj) - XtOffsetOf(spl_recursive_it_object, std)); +} +/* }}} */ + +#define Z_SPLRECURSIVE_IT_P(zv) spl_recursive_it_from_obj(Z_OBJ_P((zv))) + +#define SPL_FETCH_AND_CHECK_DUAL_IT(var, objzval) \ + do { \ + spl_dual_it_object *it = Z_SPLDUAL_IT_P(objzval); \ + if (it->dit_type == DIT_Unknown) { \ + zend_throw_exception_ex(spl_ce_LogicException, 0 TSRMLS_CC, \ + "The object is in an invalid state as the parent constructor was not called"); \ + return; \ + } \ + (var) = it; \ + } while (0) + ++#define SPL_FETCH_SUB_ELEMENT(var, object, element) \ + do { \ - spl_dual_it_object *it = zend_object_store_get_object((objzval) TSRMLS_CC); \ - if (it->dit_type == DIT_Unknown) { \ ++ if(!(object)->iterators) { \ + zend_throw_exception_ex(spl_ce_LogicException, 0 TSRMLS_CC, \ + "The object is in an invalid state as the parent constructor was not called"); \ + return; \ + } \ - (var) = it; \ ++ (var) = (object)->iterators[(object)->level].element; \ + } while (0) + -#define SPL_FETCH_SUB_ELEMENT(var, object, element) \ ++#define SPL_FETCH_SUB_ELEMENT_ADDR(var, object, element) \ + do { \ + if(!(object)->iterators) { \ + zend_throw_exception_ex(spl_ce_LogicException, 0 TSRMLS_CC, \ + "The object is in an invalid state as the parent constructor was not called"); \ + return; \ + } \ - (var) = (object)->iterators[(object)->level].element; \ ++ (var) = &(object)->iterators[(object)->level].element; \ + } while (0) + + #define SPL_FETCH_SUB_ITERATOR(var, object) SPL_FETCH_SUB_ELEMENT(var, object, iterator) + + static void spl_recursive_it_dtor(zend_object_iterator *_iter TSRMLS_DC) { spl_recursive_it_iterator *iter = (spl_recursive_it_iterator*)_iter; @@@ -373,11 -391,9 +401,9 @@@ next_step static void spl_recursive_it_rewind_ex(spl_recursive_it_object *object, zval *zthis TSRMLS_DC) { - zend_object_iterator *sub_iter; + zend_object_iterator *sub_iter; - if (!object->iterators) { - php_error_docref(NULL TSRMLS_CC, E_ERROR, "The %s instance wasn't initialized properly", Z_OBJCE_P(zthis)->name->val); - } + SPL_FETCH_SUB_ITERATOR(sub_iter, object); while (object->level) { sub_iter = object->iterators[object->level].iterator; @@@ -597,8 -612,8 +623,8 @@@ SPL_METHOD(RecursiveIteratorIterator, r Check whether the current position is valid */ SPL_METHOD(RecursiveIteratorIterator, valid) { - spl_recursive_it_object *object = (spl_recursive_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + spl_recursive_it_object *object = Z_SPLRECURSIVE_IT_P(getThis()); - + if (zend_parse_parameters_none() == FAILURE) { return; } @@@ -610,9 -625,9 +636,9 @@@ Access the current key */ SPL_METHOD(RecursiveIteratorIterator, key) { - spl_recursive_it_object *object = (spl_recursive_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + spl_recursive_it_object *object = Z_SPLRECURSIVE_IT_P(getThis()); - zend_object_iterator *iterator = object->iterators[object->level].iterator; - + zend_object_iterator *iterator; + if (zend_parse_parameters_none() == FAILURE) { return; } @@@ -628,17 -645,19 +656,19 @@@ Access the current element value */ SPL_METHOD(RecursiveIteratorIterator, current) { - spl_recursive_it_object *object = (spl_recursive_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + spl_recursive_it_object *object = Z_SPLRECURSIVE_IT_P(getThis()); - zend_object_iterator *iterator = object->iterators[object->level].iterator; + zend_object_iterator *iterator; - zval **data; + zval *data; if (zend_parse_parameters_none() == FAILURE) { return; } + SPL_FETCH_SUB_ITERATOR(iterator, object); + - iterator->funcs->get_current_data(iterator, &data TSRMLS_CC); - if (data && *data) { - RETURN_ZVAL(*data, 1, 0); + data = iterator->funcs->get_current_data(iterator TSRMLS_CC); + if (data) { + RETURN_ZVAL(data, 1, 0); } } /* }}} */ @@@ -681,21 -701,30 +711,30 @@@ SPL_METHOD(RecursiveIteratorIterator, g if (level < 0 || level > object->level) { RETURN_NULL(); } + + if(!object->iterators) { + zend_throw_exception_ex(spl_ce_LogicException, 0 TSRMLS_CC, + "The object is in an invalid state as the parent constructor was not called"); + return; + } + - RETURN_ZVAL(object->iterators[level].zobject, 1, 0); + RETURN_ZVAL(&object->iterators[level].zobject, 1, 0); } /* }}} */ /* {{{ proto RecursiveIterator RecursiveIteratorIterator::getInnerIterator() The current active sub iterator */ SPL_METHOD(RecursiveIteratorIterator, getInnerIterator) { - spl_recursive_it_object *object = (spl_recursive_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + spl_recursive_it_object *object = Z_SPLRECURSIVE_IT_P(getThis()); - long level = object->level; + zval *zobject; if (zend_parse_parameters_none() == FAILURE) { return; } - - RETURN_ZVAL(&object->iterators[level].zobject, 1, 0); + - SPL_FETCH_SUB_ELEMENT(zobject, object, zobject); ++ SPL_FETCH_SUB_ELEMENT_ADDR(zobject, object, zobject); + + RETURN_ZVAL(zobject, 1, 0); } /* }}} */ /* {{{ proto RecursiveIterator RecursiveIteratorIterator::beginIteration() @@@ -722,20 -751,28 +761,26 @@@ SPL_METHOD(RecursiveIteratorIterator, e Called for each element to test whether it has children */ SPL_METHOD(RecursiveIteratorIterator, callHasChildren) { - spl_recursive_it_object *object = (spl_recursive_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + spl_recursive_it_object *object = Z_SPLRECURSIVE_IT_P(getThis()); - zend_class_entry *ce = object->iterators[object->level].ce; + zend_class_entry *ce; - zval *retval, *zobject; + zval *zobject; if (zend_parse_parameters_none() == FAILURE) { return; } + if (!object->iterators) { + RETURN_NULL(); + } + + SPL_FETCH_SUB_ELEMENT(ce, object, ce); + - zobject = object->iterators[object->level].zobject; - if (!zobject) { + zobject = &object->iterators[object->level].zobject; + if (Z_TYPE_P(zobject) == IS_UNDEF) { RETURN_FALSE; } else { - zend_call_method_with_0_params(&zobject, ce, NULL, "haschildren", &retval); - if (retval) { - RETURN_ZVAL(retval, 0, 1); - } else { + zend_call_method_with_0_params(zobject, ce, NULL, "haschildren", return_value); + if (Z_TYPE_P(return_value) == IS_UNDEF) { RETURN_FALSE; } } @@@ -745,22 -782,24 +790,24 @@@ Return children of current element */ SPL_METHOD(RecursiveIteratorIterator, callGetChildren) { - spl_recursive_it_object *object = (spl_recursive_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + spl_recursive_it_object *object = Z_SPLRECURSIVE_IT_P(getThis()); - zend_class_entry *ce = object->iterators[object->level].ce; + zend_class_entry *ce; - zval *retval, *zobject; + zval *zobject; if (zend_parse_parameters_none() == FAILURE) { return; } + SPL_FETCH_SUB_ELEMENT(ce, object, ce); + - zobject = object->iterators[object->level].zobject; - if (!zobject) { + zobject = &object->iterators[object->level].zobject; + if (Z_TYPE_P(zobject) == IS_UNDEF) { return; } else { - zend_call_method_with_0_params(&zobject, ce, NULL, "getchildren", &retval); - if (retval) { - RETURN_ZVAL(retval, 0, 1); - } + zend_call_method_with_0_params(zobject, ce, NULL, "getchildren", return_value); + if (Z_TYPE_P(return_value) == IS_UNDEF) { + RETURN_NULL(); + } } } /* }}} */ @@@ -1127,13 -1187,20 +1192,20 @@@ SPL_METHOD(RecursiveTreeIterator, curre return; } + if(!object->iterators) { + zend_throw_exception_ex(spl_ce_LogicException, 0 TSRMLS_CC, + "The object is in an invalid state as the parent constructor was not called"); + return; + } + if (object->flags & RTIT_BYPASS_CURRENT) { - zend_object_iterator *iterator; - zval **data; + zend_object_iterator *iterator = object->iterators[object->level].iterator; + zval *data; + SPL_FETCH_SUB_ITERATOR(iterator, object); - iterator->funcs->get_current_data(iterator, &data TSRMLS_CC); - if (data && *data) { - RETURN_ZVAL(*data, 1, 0); + data = iterator->funcs->get_current_data(iterator TSRMLS_CC); + if (data) { + RETURN_ZVAL(data, 1, 0); } else { RETURN_NULL(); } @@@ -1172,11 -1240,11 +1244,11 @@@ Returns the current key prefixed and postfixed */ SPL_METHOD(RecursiveTreeIterator, key) { - spl_recursive_it_object *object = (spl_recursive_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + spl_recursive_it_object *object = Z_SPLRECURSIVE_IT_P(getThis()); - zend_object_iterator *iterator = object->iterators[object->level].iterator; + zend_object_iterator *iterator; zval prefix, key, postfix, key_copy; - char *str, *ptr; - size_t str_len; + char *ptr; + zend_string *str; if (zend_parse_parameters_none() == FAILURE) { return; @@@ -1884,13 -1965,15 +1958,14 @@@ SPL_METHOD(RecursiveCallbackFilterItera return; } - intern = Z_SPLDUAL_IT_P(getThis()); ++//??? intern = Z_SPLDUAL_IT_P(getThis()); + SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis()); zend_call_method_with_0_params(&intern->inner.zobject, intern->inner.ce, NULL, "getchildren", &retval); - if (!EG(exception) && retval) { - spl_instantiate_arg_ex2(Z_OBJCE_P(getThis()), &return_value, 0, retval, intern->u.cbfilter->fci.function_name TSRMLS_CC); - } - if (retval) { - zval_ptr_dtor(&retval); + if (!EG(exception) && Z_TYPE(retval) != IS_UNDEF) { + spl_instantiate_arg_ex2(Z_OBJCE_P(getThis()), return_value, &retval, &intern->u.cbfilter->fci.function_name TSRMLS_CC); } + zval_ptr_dtor(&retval); } /* }}} */ /* {{{ proto void ParentIterator::__construct(RecursiveIterator it) Create a ParentIterator from a RecursiveIterator */ diff --cc ext/sqlite3/sqlite3.c index c31ef3e1c1,33c855facf..1d3c612f6a --- a/ext/sqlite3/sqlite3.c +++ b/ext/sqlite3/sqlite3.c @@@ -1390,12 -1444,14 +1408,14 @@@ PHP_METHOD(sqlite3stmt, bindParam } } + SQLITE3_CHECK_INITIALIZED_STMT(stmt_obj->stmt, SQLite3Stmt); + - Z_ADDREF_P(param.parameter); + ZVAL_COPY(¶m.parameter, parameter); if (!register_bound_parameter_to_sqlite(¶m, stmt_obj TSRMLS_CC)) { - if (param.parameter) { + if (!Z_ISUNDEF(param.parameter)) { zval_ptr_dtor(&(param.parameter)); - param.parameter = NULL; + ZVAL_UNDEF(¶m.parameter); } RETURN_FALSE; } @@@ -1422,12 -1477,14 +1442,14 @@@ PHP_METHOD(sqlite3stmt, bindValue } } + SQLITE3_CHECK_INITIALIZED_STMT(stmt_obj->stmt, SQLite3Stmt); + - Z_ADDREF_P(param.parameter); + ZVAL_COPY(¶m.parameter, parameter); if (!register_bound_parameter_to_sqlite(¶m, stmt_obj TSRMLS_CC)) { - if (param.parameter) { + if (!Z_ISUNDEF(param.parameter)) { zval_ptr_dtor(&(param.parameter)); - param.parameter = NULL; + ZVAL_UNDEF(¶m.parameter); } RETURN_FALSE; } diff --cc ext/standard/array.c index 731c374582,19895f1f58..a177ee7e0f --- a/ext/standard/array.c +++ b/ext/standard/array.c @@@ -332,14 -333,12 +332,11 @@@ 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)) { - zval mode_zv; - ZVAL_LONG(&mode_zv, mode); - zend_call_method_with_1_params(array, NULL, NULL, "count", &retval, &mode_zv); - zend_call_method_with_0_params(&array, NULL, NULL, "count", &retval); - if (retval) { - convert_to_long_ex(&retval); - RETVAL_LONG(Z_LVAL_P(retval)); ++ zend_call_method_with_0_params(array, NULL, NULL, "count", &retval); + if (Z_TYPE(retval) != IS_UNDEF) { + RETVAL_LONG(zval_get_long(&retval)); zval_ptr_dtor(&retval); } - zval_ptr_dtor(&mode_zv); return; } #endif @@@ -2060,32 -1888,8 +2057,32 @@@ static void _phpi_pop(INTERNAL_FUNCTION /* If we did a shift... re-index like it did before */ if (!off_the_end) { - zend_hash_reindex(Z_ARRVAL_P(stack), 1); - } else if (!key_len && Z_ARRVAL_P(stack)->nNextFreeElement > 0 && index >= Z_ARRVAL_P(stack)->nNextFreeElement - 1) { + unsigned int k = 0; + int should_rehash = 0; + uint idx; + Bucket *p; + + for (idx = 0; idx < Z_ARRVAL_P(stack)->nNumUsed; idx++) { + p = Z_ARRVAL_P(stack)->arData + idx; + if (Z_TYPE(p->val) == IS_UNDEF) continue; + if (p->key == NULL) { + if (p->h != k) { + p->h = k++; + should_rehash = 1; + } else { + k++; + } + } + } + Z_ARRVAL_P(stack)->nNextFreeElement = k; + if (should_rehash) { + if (Z_ARRVAL_P(stack)->u.flags & HASH_FLAG_PACKED) { + zend_hash_packed_to_hash(Z_ARRVAL_P(stack)); + } else { + zend_hash_rehash(Z_ARRVAL_P(stack)); + } + } - } else if (!key && index >= Z_ARRVAL_P(stack)->nNextFreeElement - 1) { ++ } else if (!key && Z_ARRVAL_P(stack)->nNextFreeElement > 0 && index >= Z_ARRVAL_P(stack)->nNextFreeElement - 1) { Z_ARRVAL_P(stack)->nNextFreeElement = Z_ARRVAL_P(stack)->nNextFreeElement - 1; } diff --cc tests/classes/constants_error_002.phpt index be27971b87,610a42da9b..63aa22109c --- a/tests/classes/constants_error_002.phpt +++ b/tests/classes/constants_error_002.phpt @@@ -2,11 -2,11 +2,11 @@@ Error case: class constant as an array --FILE-- + ===DONE=== --EXPECTF-- - - Fatal error: Arrays are not allowed in class constants in %s on line 4 + ===DONE===