From: Dmitry Stogov Date: Fri, 25 Apr 2014 20:32:51 +0000 (+0400) Subject: Merge mainstream 'master' branch into refactoring X-Git-Tag: POST_PHPNG_MERGE~412^2~46 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f9927a6c97208c60d922f9a4e98feb8079c57d1f;p=php Merge mainstream 'master' branch into refactoring During merge I had to revert: Nikita's patch for php_splice() (it probably needs to be applyed again) Bob Weinand's patches related to constant expression handling (we need to review them carefully) I also reverted all our attempts to support sapi/phpdbg (we didn't test it anyway) Conflicts: 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_exceptions.c Zend/zend_execute.c Zend/zend_execute.h Zend/zend_execute_API.c Zend/zend_hash.c Zend/zend_highlight.c Zend/zend_language_parser.y Zend/zend_language_scanner.c Zend/zend_language_scanner_defs.h Zend/zend_variables.c Zend/zend_vm_def.h Zend/zend_vm_execute.h ext/date/php_date.c ext/dom/documenttype.c ext/hash/hash.c ext/iconv/iconv.c ext/mbstring/tests/zend_multibyte-10.phpt ext/mbstring/tests/zend_multibyte-11.phpt ext/mbstring/tests/zend_multibyte-12.phpt ext/mysql/php_mysql.c ext/mysqli/mysqli.c ext/mysqlnd/mysqlnd_reverse_api.c ext/mysqlnd/php_mysqlnd.c ext/opcache/ZendAccelerator.c ext/opcache/zend_accelerator_util_funcs.c ext/opcache/zend_persist.c ext/opcache/zend_persist_calc.c ext/pcre/php_pcre.c ext/pdo/pdo_dbh.c ext/pdo/pdo_stmt.c ext/pdo_pgsql/pgsql_driver.c ext/pgsql/pgsql.c ext/reflection/php_reflection.c ext/session/session.c ext/spl/spl_array.c ext/spl/spl_observer.c ext/standard/array.c ext/standard/basic_functions.c ext/standard/html.c ext/standard/mail.c ext/standard/php_array.h ext/standard/proc_open.c ext/standard/streamsfuncs.c ext/standard/user_filters.c ext/standard/var_unserializer.c ext/standard/var_unserializer.re main/php_variables.c sapi/phpdbg/phpdbg.c sapi/phpdbg/phpdbg_bp.c sapi/phpdbg/phpdbg_frame.c sapi/phpdbg/phpdbg_help.c sapi/phpdbg/phpdbg_list.c sapi/phpdbg/phpdbg_print.c sapi/phpdbg/phpdbg_prompt.c --- f9927a6c97208c60d922f9a4e98feb8079c57d1f diff --cc Zend/zend_API.c index 9212527963,2d845d357e..60ef092bb1 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@@ -1151,10 -1093,10 +1151,10 @@@ ZEND_API void zend_update_class_constan int i; *scope = class_type; - zend_hash_apply_with_argument(&class_type->constants_table, (apply_func_arg_t) zval_update_constant, (void*)1 TSRMLS_CC); + zend_hash_apply_with_argument(&class_type->constants_table, (apply_func_arg_t) zval_update_constant, (void *)1 TSRMLS_CC); for (i = 0; i < class_type->default_properties_count; i++) { - if (class_type->default_properties_table[i]) { + if (Z_TYPE(class_type->default_properties_table[i]) != IS_UNDEF) { zval_update_class_constant(&class_type->default_properties_table[i], 0, i TSRMLS_CC); } } @@@ -2084,7 -2017,10 +2084,10 @@@ ZEND_API void zend_check_magic_method_i } else if (name_len == sizeof(ZEND_TOSTRING_FUNC_NAME) - 1 && !memcmp(lcname, ZEND_TOSTRING_FUNC_NAME, sizeof(ZEND_TOSTRING_FUNC_NAME)-1) && fptr->common.num_args != 0 ) { - zend_error(error_type, "Method %s::%s() cannot take arguments", ce->name, ZEND_TOSTRING_FUNC_NAME); + zend_error(error_type, "Method %s::%s() cannot take arguments", ce->name->val, ZEND_TOSTRING_FUNC_NAME); + } else if (name_len == sizeof(ZEND_DEBUGINFO_FUNC_NAME) - 1 && + !memcmp(lcname, ZEND_DEBUGINFO_FUNC_NAME, sizeof(ZEND_DEBUGINFO_FUNC_NAME)-1) && fptr->common.num_args != 0) { - zend_error(error_type, "Method %s::%s() cannot take arguments", ce->name, ZEND_DEBUGINFO_FUNC_NAME); ++ zend_error(error_type, "Method %s::%s() cannot take arguments", ce->name->val, ZEND_DEBUGINFO_FUNC_NAME); } } /* }}} */ @@@ -2098,8 -2034,8 +2101,8 @@@ ZEND_API int zend_register_functions(ze int count=0, unload=0; HashTable *target_function_table = function_table; int error_type; - zend_function *ctor = NULL, *dtor = NULL, *clone = NULL, *__get = NULL, *__set = NULL, *__unset = NULL, *__isset = NULL, *__call = NULL, *__callstatic = NULL, *__tostring = NULL; + zend_function *ctor = NULL, *dtor = NULL, *clone = NULL, *__get = NULL, *__set = NULL, *__unset = NULL, *__isset = NULL, *__call = NULL, *__callstatic = NULL, *__tostring = NULL, *__debugInfo = NULL; - const char *lowercase_name; + zend_string *lowercase_name; int fname_len; const char *lc_class_name = NULL; int class_name_len = 0; @@@ -2225,31 -2158,33 +2228,33 @@@ * If it's an old-style constructor, store it only if we don't have * a constructor already. */ - if ((fname_len == class_name_len) && !ctor && !memcmp(lowercase_name, lc_class_name, class_name_len+1)) { + if ((fname_len == class_name_len) && !ctor && !memcmp(lowercase_name->val, lc_class_name, class_name_len+1)) { ctor = reg_function; - } else if ((fname_len == sizeof(ZEND_CONSTRUCTOR_FUNC_NAME)-1) && !memcmp(lowercase_name, ZEND_CONSTRUCTOR_FUNC_NAME, sizeof(ZEND_CONSTRUCTOR_FUNC_NAME) - 1)) { + } else if ((fname_len == sizeof(ZEND_CONSTRUCTOR_FUNC_NAME)-1) && !memcmp(lowercase_name->val, ZEND_CONSTRUCTOR_FUNC_NAME, sizeof(ZEND_CONSTRUCTOR_FUNC_NAME) - 1)) { ctor = reg_function; - } else if ((fname_len == sizeof(ZEND_DESTRUCTOR_FUNC_NAME)-1) && !memcmp(lowercase_name, ZEND_DESTRUCTOR_FUNC_NAME, sizeof(ZEND_DESTRUCTOR_FUNC_NAME) - 1)) { + } else if ((fname_len == sizeof(ZEND_DESTRUCTOR_FUNC_NAME)-1) && !memcmp(lowercase_name->val, ZEND_DESTRUCTOR_FUNC_NAME, sizeof(ZEND_DESTRUCTOR_FUNC_NAME) - 1)) { dtor = reg_function; if (internal_function->num_args) { - zend_error(error_type, "Destructor %s::%s() cannot take arguments", scope->name, ptr->fname); + zend_error(error_type, "Destructor %s::%s() cannot take arguments", scope->name->val, ptr->fname); } - } else if ((fname_len == sizeof(ZEND_CLONE_FUNC_NAME)-1) && !memcmp(lowercase_name, ZEND_CLONE_FUNC_NAME, sizeof(ZEND_CLONE_FUNC_NAME) - 1)) { + } else if ((fname_len == sizeof(ZEND_CLONE_FUNC_NAME)-1) && !memcmp(lowercase_name->val, ZEND_CLONE_FUNC_NAME, sizeof(ZEND_CLONE_FUNC_NAME) - 1)) { clone = reg_function; - } else if ((fname_len == sizeof(ZEND_CALL_FUNC_NAME)-1) && !memcmp(lowercase_name, ZEND_CALL_FUNC_NAME, sizeof(ZEND_CALL_FUNC_NAME) - 1)) { + } else if ((fname_len == sizeof(ZEND_CALL_FUNC_NAME)-1) && !memcmp(lowercase_name->val, ZEND_CALL_FUNC_NAME, sizeof(ZEND_CALL_FUNC_NAME) - 1)) { __call = reg_function; - } else if ((fname_len == sizeof(ZEND_CALLSTATIC_FUNC_NAME)-1) && !memcmp(lowercase_name, ZEND_CALLSTATIC_FUNC_NAME, sizeof(ZEND_CALLSTATIC_FUNC_NAME) - 1)) { + } else if ((fname_len == sizeof(ZEND_CALLSTATIC_FUNC_NAME)-1) && !memcmp(lowercase_name->val, ZEND_CALLSTATIC_FUNC_NAME, sizeof(ZEND_CALLSTATIC_FUNC_NAME) - 1)) { __callstatic = reg_function; - } else if ((fname_len == sizeof(ZEND_TOSTRING_FUNC_NAME)-1) && !memcmp(lowercase_name, ZEND_TOSTRING_FUNC_NAME, sizeof(ZEND_TOSTRING_FUNC_NAME) - 1)) { + } else if ((fname_len == sizeof(ZEND_TOSTRING_FUNC_NAME)-1) && !memcmp(lowercase_name->val, ZEND_TOSTRING_FUNC_NAME, sizeof(ZEND_TOSTRING_FUNC_NAME) - 1)) { __tostring = reg_function; - } else if ((fname_len == sizeof(ZEND_GET_FUNC_NAME)-1) && !memcmp(lowercase_name, ZEND_GET_FUNC_NAME, sizeof(ZEND_GET_FUNC_NAME) - 1)) { + } else if ((fname_len == sizeof(ZEND_GET_FUNC_NAME)-1) && !memcmp(lowercase_name->val, ZEND_GET_FUNC_NAME, sizeof(ZEND_GET_FUNC_NAME) - 1)) { __get = reg_function; - } else if ((fname_len == sizeof(ZEND_SET_FUNC_NAME)-1) && !memcmp(lowercase_name, ZEND_SET_FUNC_NAME, sizeof(ZEND_SET_FUNC_NAME) - 1)) { + } else if ((fname_len == sizeof(ZEND_SET_FUNC_NAME)-1) && !memcmp(lowercase_name->val, ZEND_SET_FUNC_NAME, sizeof(ZEND_SET_FUNC_NAME) - 1)) { __set = reg_function; - } else if ((fname_len == sizeof(ZEND_UNSET_FUNC_NAME)-1) && !memcmp(lowercase_name, ZEND_UNSET_FUNC_NAME, sizeof(ZEND_UNSET_FUNC_NAME) - 1)) { + } else if ((fname_len == sizeof(ZEND_UNSET_FUNC_NAME)-1) && !memcmp(lowercase_name->val, ZEND_UNSET_FUNC_NAME, sizeof(ZEND_UNSET_FUNC_NAME) - 1)) { __unset = reg_function; - } else if ((fname_len == sizeof(ZEND_ISSET_FUNC_NAME)-1) && !memcmp(lowercase_name, ZEND_ISSET_FUNC_NAME, sizeof(ZEND_ISSET_FUNC_NAME) - 1)) { + } else if ((fname_len == sizeof(ZEND_ISSET_FUNC_NAME)-1) && !memcmp(lowercase_name->val, ZEND_ISSET_FUNC_NAME, sizeof(ZEND_ISSET_FUNC_NAME) - 1)) { __isset = reg_function; - } else if ((fname_len == sizeof(ZEND_DEBUGINFO_FUNC_NAME)-1) && !memcmp(lowercase_name, ZEND_DEBUGINFO_FUNC_NAME, sizeof(ZEND_DEBUGINFO_FUNC_NAME) - 1)) { ++ } else if ((fname_len == sizeof(ZEND_DEBUGINFO_FUNC_NAME)-1) && !memcmp(lowercase_name->val, ZEND_DEBUGINFO_FUNC_NAME, sizeof(ZEND_DEBUGINFO_FUNC_NAME) - 1)) { + __debugInfo = reg_function; } else { reg_function = NULL; } @@@ -2352,6 -2287,11 +2358,11 @@@ } __isset->common.fn_flags &= ~ZEND_ACC_ALLOW_STATIC; } + if (__debugInfo) { + if (__debugInfo->common.fn_flags & ZEND_ACC_STATIC) { - zend_error(error_type, "Method %s::%s() cannot be static", scope->name, __debugInfo->common.function_name); ++ zend_error(error_type, "Method %s::%s() cannot be static", scope->name->val, __debugInfo->common.function_name->val); + } + } efree((char*)lc_class_name); } return SUCCESS; diff --cc Zend/zend_ast.c index 5babcffe48,e486aa326c..07d38dc6bf --- a/Zend/zend_ast.c +++ b/Zend/zend_ast.c @@@ -222,9 -251,10 +229,9 @@@ ZEND_API void zend_ast_evaluate(zval *r zval_dtor(&op2); break; case ZEND_CONST: - *result = *ast->u.val; - zval_copy_ctor(result); - if (IS_CONSTANT_TYPE(Z_TYPE_P(result))) { - zval_update_constant_ex(&result, 1, scope TSRMLS_CC); + ZVAL_DUP(result, &ast->u.val); + if (Z_OPT_CONSTANT_P(result)) { - zval_update_constant_ex(result, (void *) 1, scope TSRMLS_CC); ++ zval_update_constant_ex(result, 1, scope TSRMLS_CC); } break; case ZEND_BOOL_AND: @@@ -285,29 -344,20 +292,20 @@@ ZEND_API zend_ast *zend_ast_copy(zend_a if (ast == NULL) { return NULL; } else if (ast->kind == ZEND_CONST) { - zend_ast *copy = zend_ast_create_constant(ast->u.val); - zval_copy_ctor(copy->u.val); + zend_ast *copy = zend_ast_create_constant(&ast->u.val); + zval_copy_ctor(©->u.val); return copy; - } else { - switch (ast->children) { - case 1: - return zend_ast_create_unary( - ast->kind, - zend_ast_copy((&ast->u.child)[0])); - case 2: - return zend_ast_create_binary( - ast->kind, - zend_ast_copy((&ast->u.child)[0]), - zend_ast_copy((&ast->u.child)[1])); - case 3: - return zend_ast_create_ternary( - ast->kind, - zend_ast_copy((&ast->u.child)[0]), - zend_ast_copy((&ast->u.child)[1]), - zend_ast_copy((&ast->u.child)[2])); + } else if (ast->children) { + zend_ast *new = emalloc(sizeof(zend_ast) + sizeof(zend_ast*) * (ast->children - 1)); + int i; + new->kind = ast->kind; + new->children = ast->children; + for (i = 0; i < ast->children; i++) { + (&new->u.child)[i] = zend_ast_copy((&ast->u.child)[i]); } + return new; } - return zend_ast_create_dynamic(ast->kind); + return NULL; } ZEND_API void zend_ast_destroy(zend_ast *ast) diff --cc Zend/zend_compile.c index 625957f74a,beb53402ba..8df612e18b --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@@ -97,11 -102,18 +97,18 @@@ ZEND_API zend_compiler_globals compiler ZEND_API zend_executor_globals executor_globals; #endif + static void zend_push_function_call_entry(zend_function *fbc TSRMLS_DC) /* {{{ */ + { + zend_function_call_entry fcall = { fbc }; + zend_stack_push(&CG(function_call_stack), &fcall, sizeof(zend_function_call_entry)); + } + /* }}} */ + static void zend_duplicate_property_info(zend_property_info *property_info) /* {{{ */ { - property_info->name = str_estrndup(property_info->name, property_info->name_length); + STR_ADDREF(property_info->name); if (property_info->doc_comment) { - property_info->doc_comment = estrndup(property_info->doc_comment, property_info->doc_comment_len); + STR_ADDREF(property_info->doc_comment); } } /* }}} */ @@@ -1611,6 -1629,11 +1618,11 @@@ void zend_do_begin_function_declaration if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) { zend_error(E_WARNING, "The magic method __invoke() must have public visibility and cannot be static"); } + - } else if ((name_len == sizeof(ZEND_DEBUGINFO_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_DEBUGINFO_FUNC_NAME, sizeof(ZEND_DEBUGINFO_FUNC_NAME)-1))) { ++ } else if ((name->len == sizeof(ZEND_DEBUGINFO_FUNC_NAME)-1) && (!memcmp(lcname->val, ZEND_DEBUGINFO_FUNC_NAME, sizeof(ZEND_DEBUGINFO_FUNC_NAME)-1))) { + if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) { + zend_error(E_WARNING, "The magic method __debugInfo() must have public visibility and cannot be static"); + } } } else { char *class_lcname; @@@ -1671,6 -1694,11 +1683,11 @@@ if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) { zend_error(E_WARNING, "The magic method __invoke() must have public visibility and cannot be static"); } - } else if ((name_len == sizeof(ZEND_DEBUGINFO_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_DEBUGINFO_FUNC_NAME, sizeof(ZEND_DEBUGINFO_FUNC_NAME)-1))) { ++ } else if ((name->len == sizeof(ZEND_DEBUGINFO_FUNC_NAME)-1) && (!memcmp(lcname->val, ZEND_DEBUGINFO_FUNC_NAME, sizeof(ZEND_DEBUGINFO_FUNC_NAME)-1))) { + if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) { + zend_error(E_WARNING, "The magic method __debugInfo() must have public visibility and cannot be static"); + } + CG(active_class_entry)->__debugInfo = (zend_function *) CG(active_op_array); } else if (!(fn_flags & ZEND_ACC_STATIC)) { CG(active_op_array)->fn_flags |= ZEND_ACC_ALLOW_STATIC; } @@@ -1978,10 -1993,10 +1995,10 @@@ int zend_do_begin_function_call(znode * efree(lcname); return 1; /* Dynamic */ } - efree(Z_STRVAL(function_name->u.constant)); - Z_STRVAL(function_name->u.constant) = lcname; + STR_RELEASE(Z_STR(function_name->u.constant)); + Z_STR(function_name->u.constant) = lcname; - zend_stack_push(&CG(function_call_stack), (void *) &function, sizeof(zend_function *)); + zend_push_function_call_entry(function TSRMLS_CC); if (CG(context).nested_calls + 1 > CG(active_op_array)->nested_calls) { CG(active_op_array)->nested_calls = CG(context).nested_calls + 1; } @@@ -2716,7 -2729,7 +2737,7 @@@ void zend_do_unpack_params(znode *param * computed at compile time, thus we need access to EX(call). In order to have it we * retroactively emit a ZEND_INIT_FCALL_BY_NAME opcode. */ zval func_name; - ZVAL_STR(&func_name, STR_COPY((*function_ptr_ptr)->common.function_name)); - ZVAL_STRING(&func_name, fcall->fbc->common.function_name, 1); ++ ZVAL_STR(&func_name, STR_COPY(fcall->fbc->common.function_name)); opline = get_next_op(CG(active_op_array) TSRMLS_CC); opline->opcode = ZEND_INIT_FCALL_BY_NAME; @@@ -3466,12 -3455,15 +3490,12 @@@ static char * zend_get_function_declara } } if (precv && precv->opcode == ZEND_RECV_INIT && precv->op2_type != IS_UNUSED) { - zval *zv, zv_copy; - int use_copy; - ALLOC_ZVAL(zv); - *zv = *precv->op2.zv; - zval_copy_ctor(zv); - INIT_PZVAL(zv); + zval zv; + + ZVAL_DUP(&zv, precv->op2.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_TYPE(zv) == IS_BOOL) { + if (Z_LVAL(zv)) { memcpy(offset, "true", 4); offset += 4; } else { @@@ -3981,38 -3953,40 +4005,40 @@@ static zend_bool zend_traits_method_com } /* }}} */ -static void zend_add_magic_methods(zend_class_entry* ce, const char* mname, uint mname_len, zend_function* fe TSRMLS_DC) /* {{{ */ +static void zend_add_magic_methods(zend_class_entry* ce, zend_string* mname, zend_function* fe TSRMLS_DC) /* {{{ */ { - if (!strncmp(mname, ZEND_CLONE_FUNC_NAME, mname_len)) { + if (!strncmp(mname->val, ZEND_CLONE_FUNC_NAME, mname->len)) { ce->clone = fe; fe->common.fn_flags |= ZEND_ACC_CLONE; - } else if (!strncmp(mname, ZEND_CONSTRUCTOR_FUNC_NAME, mname_len)) { + } else if (!strncmp(mname->val, ZEND_CONSTRUCTOR_FUNC_NAME, mname->len)) { if (ce->constructor) { - zend_error_noreturn(E_COMPILE_ERROR, "%s has colliding constructor definitions coming from traits", ce->name); + zend_error_noreturn(E_COMPILE_ERROR, "%s has colliding constructor definitions coming from traits", ce->name->val); } ce->constructor = fe; fe->common.fn_flags |= ZEND_ACC_CTOR; - } else if (!strncmp(mname, ZEND_DESTRUCTOR_FUNC_NAME, mname_len)) { + } else if (!strncmp(mname->val, ZEND_DESTRUCTOR_FUNC_NAME, mname->len)) { ce->destructor = fe; fe->common.fn_flags |= ZEND_ACC_DTOR; - } else if (!strncmp(mname, ZEND_GET_FUNC_NAME, mname_len)) { + } else if (!strncmp(mname->val, ZEND_GET_FUNC_NAME, mname->len)) { ce->__get = fe; - } else if (!strncmp(mname, ZEND_SET_FUNC_NAME, mname_len)) { + } else if (!strncmp(mname->val, ZEND_SET_FUNC_NAME, mname->len)) { ce->__set = fe; - } else if (!strncmp(mname, ZEND_CALL_FUNC_NAME, mname_len)) { + } else if (!strncmp(mname->val, ZEND_CALL_FUNC_NAME, mname->len)) { ce->__call = fe; - } else if (!strncmp(mname, ZEND_UNSET_FUNC_NAME, mname_len)) { + } else if (!strncmp(mname->val, ZEND_UNSET_FUNC_NAME, mname->len)) { ce->__unset = fe; - } else if (!strncmp(mname, ZEND_ISSET_FUNC_NAME, mname_len)) { + } else if (!strncmp(mname->val, ZEND_ISSET_FUNC_NAME, mname->len)) { ce->__isset = fe; - } else if (!strncmp(mname, ZEND_CALLSTATIC_FUNC_NAME, mname_len)) { + } else if (!strncmp(mname->val, ZEND_CALLSTATIC_FUNC_NAME, mname->len)) { ce->__callstatic = fe; - } else if (!strncmp(mname, ZEND_TOSTRING_FUNC_NAME, mname_len)) { + } else if (!strncmp(mname->val, ZEND_TOSTRING_FUNC_NAME, mname->len)) { ce->__tostring = fe; - } else if (!strncmp(mname, ZEND_DEBUGINFO_FUNC_NAME, mname_len)) { ++ } else if (!strncmp(mname->val, ZEND_DEBUGINFO_FUNC_NAME, mname->len)) { + ce->__debugInfo = fe; - } else if (ce->name_length + 1 == mname_len) { - char *lowercase_name = emalloc(ce->name_length + 1); - zend_str_tolower_copy(lowercase_name, ce->name, ce->name_length); - lowercase_name = (char*)zend_new_interned_string(lowercase_name, ce->name_length + 1, 1 TSRMLS_CC); - if (!memcmp(mname, lowercase_name, mname_len)) { + } else if (ce->name->len == mname->len) { + zend_string *lowercase_name = STR_ALLOC(ce->name->len, 0); + zend_str_tolower_copy(lowercase_name->val, ce->name->val, ce->name->len); + lowercase_name = zend_new_interned_string(lowercase_name TSRMLS_CC); + if (!memcmp(mname->val, lowercase_name->val, mname->len)) { if (ce->constructor) { - zend_error_noreturn(E_COMPILE_ERROR, "%s has colliding constructor definitions coming from traits", ce->name); + zend_error_noreturn(E_COMPILE_ERROR, "%s has colliding constructor definitions coming from traits", ce->name->val); } ce->constructor = fe; fe->common.fn_flags |= ZEND_ACC_CTOR; diff --cc Zend/zend_compile.h index 24f06c426f,99d3704b76..4288a3b705 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@@ -340,9 -360,14 +340,14 @@@ union _zend_function typedef struct _zend_function_state { zend_function *function; - void **arguments; + zval *arguments; } zend_function_state; + typedef struct _zend_function_call_entry { + zend_function *fbc; + zend_uint arg_num; + zend_bool uses_argument_unpacking; + } zend_function_call_entry; typedef struct _zend_switch_entry { znode cond; @@@ -506,9 -523,9 +511,9 @@@ void zend_do_begin_dynamic_function_cal void zend_do_fetch_class(znode *result, znode *class_name TSRMLS_DC); void zend_do_build_full_name(znode *result, znode *prefix, znode *name, int is_class_member TSRMLS_DC); int zend_do_begin_class_member_function_call(znode *class_name, znode *method_name TSRMLS_DC); - void zend_do_end_function_call(znode *function_name, znode *result, const znode *argument_list, int is_method, int is_dynamic_fcall TSRMLS_DC); + void zend_do_end_function_call(znode *function_name, znode *result, int is_method, int is_dynamic_fcall TSRMLS_DC); void zend_do_return(znode *expr, int do_end_vparse TSRMLS_DC); -void zend_do_yield(znode *result, znode *value, const znode *key, zend_bool is_variable TSRMLS_DC); +void zend_do_yield(znode *result, znode *value, znode *key, zend_bool is_variable TSRMLS_DC); void zend_do_handle_exception(TSRMLS_D); void zend_do_begin_lambda_function_declaration(znode *result, znode *function_token, int return_reference, int is_static TSRMLS_DC); diff --cc Zend/zend_constants.c index fd98a92c4e,0f44f58a77..a25fe2bdb5 --- a/Zend/zend_constants.c +++ b/Zend/zend_constants.c @@@ -379,26 -358,23 +379,26 @@@ ZEND_API zval *zend_get_constant_ex(zen } else { zend_error(E_ERROR, "Cannot access static:: when no class scope is active"); } - efree(lcname); } else { - efree(lcname); - ce = zend_fetch_class(class_name, class_name_len, flags TSRMLS_CC); + ce = zend_fetch_class(class_name, flags TSRMLS_CC); } - if (retval && ce) { - if (zend_hash_find(&ce->constants_table, constant_name, const_name_len+1, (void **) &ret_constant) != SUCCESS) { - retval = 0; + free_alloca(lcname, use_heap); + if (ce) { + ret_constant = zend_hash_find(&ce->constants_table, constant_name); + if (ret_constant == NULL) { if ((flags & ZEND_FETCH_CLASS_SILENT) == 0) { - zend_error(E_ERROR, "Undefined class constant '%s::%s'", class_name, constant_name); + zend_error(E_ERROR, "Undefined class constant '%s::%s'", class_name->val, constant_name->val); } + } else if (Z_ISREF_P(ret_constant)) { + ret_constant = Z_REFVAL_P(ret_constant); } - } else if (!ce) { - retval = 0; } - efree(class_name); - goto finish; + STR_FREE(class_name); + STR_FREE(constant_name); + if (ret_constant && Z_CONSTANT_P(ret_constant)) { - zval_update_constant_ex(ret_constant, (void*)1, ce TSRMLS_CC); ++ zval_update_constant_ex(ret_constant, 1, ce TSRMLS_CC); + } + return ret_constant; } /* non-class constant */ diff --cc Zend/zend_exceptions.c index 4272adedbd,e4570269e3..137d9c97f8 --- a/Zend/zend_exceptions.c +++ b/Zend/zend_exceptions.c @@@ -335,42 -335,48 +335,49 @@@ ZEND_METHOD(error_exception, getSeverit /* }}} */ /* {{{ gettraceasstring() macros */ -#define TRACE_APPEND_CHR(chr) \ - *str = (char*)erealloc(*str, *len + 1 + 1); \ - (*str)[(*len)++] = chr +#define TRACE_APPEND_CHR(chr) \ + str = STR_REALLOC(str, str->len + 1, 0); \ + str->val[str->len - 1] = chr -#define TRACE_APPEND_STRL(val, vallen) \ - { \ - int l = vallen; \ - *str = (char*)erealloc(*str, *len + l + 1); \ - memcpy((*str) + *len, val, l); \ - *len += l; \ +#define TRACE_APPEND_STRL(v, l) \ + { \ + str = STR_REALLOC(str, str->len + (l), 0); \ + memcpy(str->val + str->len - (l), (v), (l)); \ } -#define TRACE_APPEND_STR(val) \ - TRACE_APPEND_STRL(val, sizeof(val)-1) +#define TRACE_APPEND_STR(v) \ + TRACE_APPEND_STRL((v), sizeof((v))-1) -#define TRACE_APPEND_KEY(key) \ - if (zend_hash_find(ht, key, sizeof(key), (void**)&tmp) == SUCCESS) { \ - if (Z_TYPE_PP(tmp) != IS_STRING) { \ - zend_error(E_WARNING, "Value for %s is no string", key); \ - TRACE_APPEND_STR("[unknown]"); \ - } else { \ - TRACE_APPEND_STRL(Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp)); \ - } \ - } +#define TRACE_APPEND_KEY(key) do { \ + tmp = zend_hash_str_find(ht, key, sizeof(key)-1); \ + if (tmp) { \ + if (Z_TYPE_P(tmp) != IS_STRING) { \ + zend_error(E_WARNING, "Value for %s is no string", key); \ + TRACE_APPEND_STR("[unknown]"); \ + } else { \ + TRACE_APPEND_STRL(Z_STRVAL_P(tmp), Z_STRLEN_P(tmp)); \ + } \ + } \ + } while (0) + -#define TRACE_ARG_APPEND(vallen) \ - *str = (char*)erealloc(*str, *len + 1 + vallen); \ - memmove((*str) + *len - l_added + 1 + vallen, (*str) + *len - l_added + 1, l_added); ++#define TRACE_ARG_APPEND(vallen) do { \ ++ int len = str->len; \ ++ str = STR_REALLOC(str, len + vallen, 0); \ ++ memmove(str->val + len - l_added + 1 + vallen, str->val + len - l_added + 1, l_added); \ ++ } while (0) + /* }}} */ -static int _build_trace_args(zval **arg TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */ +static int _build_trace_args(zval *arg TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */ { - char **str; - int *len; + zend_string *str, **str_ptr; - str = va_arg(args, char**); - len = va_arg(args, int*); + str_ptr = va_arg(args, zend_string**); + str = *str_ptr; /* the trivial way would be to do: - * conver_to_string_ex(arg); + * convert_to_string_ex(arg); * append it and kill the now tmp arg. * but that could cause some E_NOTICE and also damn long lines. */ @@@ -394,8 -399,58 +401,57 @@@ l_added += 3 + 1; } while (--l_added) { - if (str->val[str->len - l_added] < 32) { - str->val[str->len - l_added] = '?'; - unsigned char chr = (*str)[*len - l_added]; ++ unsigned char chr = str->val[str->len - l_added]; + if (chr < 32 || chr == '\\' || chr > 126) { - (*str)[*len - l_added] = '\\'; ++ str->val[str->len - l_added] = '\\'; + + switch (chr) { + case '\n': + TRACE_ARG_APPEND(1); - (*str)[++(*len) - l_added] = 'n'; ++ str->val[str->len - l_added] = 'n'; + break; + case '\r': + TRACE_ARG_APPEND(1); - (*str)[++(*len) - l_added] = 'r'; ++ str->val[str->len - l_added] = 'r'; + break; + case '\t': + TRACE_ARG_APPEND(1); - (*str)[++(*len) - l_added] = 't'; ++ str->val[str->len - l_added] = 't'; + break; + case '\f': + TRACE_ARG_APPEND(1); - (*str)[++(*len) - l_added] = 'f'; ++ str->val[str->len - l_added] = 'f'; + break; + case '\v': + TRACE_ARG_APPEND(1); - (*str)[++(*len) - l_added] = 'v'; ++ str->val[str->len - l_added] = 'v'; + break; + #ifndef PHP_WIN32 + case '\e': + #else + case VK_ESCAPE: + #endif + TRACE_ARG_APPEND(1); - (*str)[++(*len) - l_added] = 'e'; ++ str->val[str->len - l_added] = 'e'; + break; + case '\\': + TRACE_ARG_APPEND(1); - (*str)[++(*len) - l_added] = '\\'; ++ str->val[str->len - l_added] = '\\'; + break; + default: + TRACE_ARG_APPEND(3); - (*str)[*len - l_added + 1] = 'x'; ++ str->val[str->len - l_added - 2] = 'x'; + if ((chr >> 4) < 10) { - (*str)[*len - l_added + 2] = (chr >> 4) + '0'; ++ str->val[str->len - l_added - 1] = (chr >> 4) + '0'; + } else { - (*str)[*len - l_added + 2] = (chr >> 4) + 'A' - 10; ++ str->val[str->len - l_added - 1] = (chr >> 4) + 'A' - 10; + } + if (chr % 16 < 10) { - (*str)[*len - l_added + 3] = chr % 16 + '0'; ++ str->val[str->len - l_added] = chr % 16 + '0'; + } else { - (*str)[*len - l_added + 3] = chr % 16 + 'A' - 10; ++ str->val[str->len - l_added] = chr % 16 + 'A' - 10; + } - *len += 3; + } } } break; diff --cc Zend/zend_execute.h index d632a97840,d151c3413d..98e2678f53 --- a/Zend/zend_execute.h +++ b/Zend/zend_execute.h @@@ -134,10 -156,10 +134,10 @@@ again return result; } - ZEND_API int zval_update_constant(zval *pp, void *arg TSRMLS_DC); - ZEND_API int zval_update_constant_inline_change(zval *pp, void *arg TSRMLS_DC); - ZEND_API int zval_update_constant_no_inline_change(zval *pp, void *arg TSRMLS_DC); - ZEND_API int zval_update_constant_ex(zval *pp, void *arg, zend_class_entry *scope TSRMLS_DC); -ZEND_API int zval_update_constant(zval **pp, zend_bool inline_change TSRMLS_DC); -ZEND_API int zval_update_constant_inline_change(zval **pp, zend_class_entry *scope TSRMLS_DC); -ZEND_API int zval_update_constant_no_inline_change(zval **pp, zend_class_entry *scope TSRMLS_DC); -ZEND_API int zval_update_constant_ex(zval **pp, zend_bool inline_change, zend_class_entry *scope TSRMLS_DC); ++ZEND_API int zval_update_constant(zval *pp, zend_bool inline_change TSRMLS_DC); ++ZEND_API int zval_update_constant_inline_change(zval *pp, zend_class_entry *scope TSRMLS_DC); ++ZEND_API int zval_update_constant_no_inline_change(zval *pp, zend_class_entry *scope TSRMLS_DC); ++ZEND_API int zval_update_constant_ex(zval *pp, zend_bool inline_change, zend_class_entry *scope TSRMLS_DC); /* dedicated Zend executor functions - do not use! */ #define ZEND_VM_STACK_PAGE_SIZE ((16 * 1024) - 16) diff --cc Zend/zend_execute_API.c index 621ad66586,7cfd85d52a..03f763ea21 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@@ -501,15 -451,15 +501,14 @@@ ZEND_API int zend_is_true(zval *op TSRM #include "../TSRM/tsrm_strtok_r.h" - #define IS_VISITED_CONSTANT 0x080 + #define IS_VISITED_CONSTANT 0x80 #define IS_CONSTANT_VISITED(p) (Z_TYPE_P(p) & IS_VISITED_CONSTANT) #define Z_REAL_TYPE_P(p) (Z_TYPE_P(p) & ~IS_VISITED_CONSTANT) -#define MARK_CONSTANT_VISITED(p) Z_TYPE_P(p) |= IS_VISITED_CONSTANT +#define MARK_CONSTANT_VISITED(p) Z_TYPE_INFO_P(p) |= IS_VISITED_CONSTANT - ZEND_API int zval_update_constant_ex(zval *p, void *arg, zend_class_entry *scope TSRMLS_DC) /* {{{ */ -ZEND_API int zval_update_constant_ex(zval **pp, zend_bool inline_change, zend_class_entry *scope TSRMLS_DC) /* {{{ */ ++ZEND_API int zval_update_constant_ex(zval *p, zend_bool inline_change, zend_class_entry *scope TSRMLS_DC) /* {{{ */ { - zend_bool inline_change = (zend_bool) (zend_uintptr_t) arg; - zval *p = *pp; - zval const_value; + zval *const_value, tmp; char *colon; if (IS_CONSTANT_VISITED(p)) { @@@ -583,159 -538,42 +582,159 @@@ } } else { if (inline_change) { - str_efree(Z_STRVAL_P(p)); + STR_RELEASE(Z_STR_P(p)); } - *p = const_value; +//???! + ZVAL_COPY_VALUE(p, const_value); + if (Z_OPT_CONSTANT_P(p)) { - zval_update_constant_ex(p, (void*)1, NULL TSRMLS_CC); ++ zval_update_constant_ex(p, 1, NULL TSRMLS_CC); + } + zval_opt_copy_ctor(p); + } + + if (Z_REFCOUNTED_P(p)) Z_SET_REFCOUNT_P(p, refcount); + } else if (Z_TYPE_P(p) == IS_CONSTANT_ARRAY) { + zval *element, new_val; + zend_string *str_index; + ulong num_index; + int ret; + + SEPARATE_ZVAL_IF_NOT_REF(p); + + Z_TYPE_INFO_P(p) = IS_ARRAY_EX; + if (!inline_change) { + HashTable *ht = Z_ARRVAL_P(p); + ZVAL_NEW_ARR(p); + zend_hash_init(Z_ARRVAL_P(p), zend_hash_num_elements(ht), NULL, ZVAL_PTR_DTOR, 0); + zend_hash_copy(Z_ARRVAL_P(p), ht, ZVAL_COPY_CTOR); } - Z_SET_REFCOUNT_P(p, refcount); - Z_SET_ISREF_TO_P(p, is_ref); + /* First go over the array and see if there are any constant indices */ + zend_hash_internal_pointer_reset(Z_ARRVAL_P(p)); + while ((element = zend_hash_get_current_data(Z_ARRVAL_P(p))) != NULL) { + if (zend_hash_get_current_key(Z_ARRVAL_P(p), &str_index, &num_index, 0) != HASH_KEY_IS_STRING) { + zend_hash_move_forward(Z_ARRVAL_P(p)); + continue; + } + if (!(GC_FLAGS(str_index) & (IS_STR_CONSTANT | IS_STR_AST))) { + zend_hash_move_forward(Z_ARRVAL_P(p)); + continue; + } + + if (GC_FLAGS(str_index) & IS_STR_AST) { + zend_ast_ref *ast = *(zend_ast_ref **)str_index->val; + + zend_ast_evaluate(&tmp, ast->ast, scope TSRMLS_CC); + zend_ast_destroy(ast->ast); + efree(ast); + const_value = &tmp; + } else if (!(const_value = zend_get_constant_ex(str_index, scope, GC_FLAGS(str_index) & ~(IS_STR_PERSISTENT | IS_STR_INTERNED |IS_STR_PERMANENT) TSRMLS_CC))) { + char *actual, *str; + const char *save = str_index->val; + int len; + + str = str_index->val; + len = str_index->len; + if ((colon = (char*)zend_memrchr(str, ':', len))) { + zend_error(E_ERROR, "Undefined class constant '%s'", str); + len -= ((colon - str) + 1); + str = colon; + } else { + if (GC_FLAGS(str_index) & IS_STR_CONSTANT_UNQUALIFIED) { + if ((actual = (char *)zend_memrchr(str, '\\', len))) { + actual++; + len -= (actual - str); + str = actual; + } + } + if (str[0] == '\\') { + ++str; + --len; + } + if (save[0] == '\\') { + ++save; + } + if (!(GC_FLAGS(str_index) & IS_STR_CONSTANT_UNQUALIFIED)) { + zend_error(E_ERROR, "Undefined constant '%s'", save); + } + zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'", str, str); + } + if (str == str_index->val && len == str_index->len) { + ZVAL_STR(&tmp, STR_COPY(str_index)); + } else { + ZVAL_STRINGL(&tmp, str, len); + } + const_value = &tmp; + } else { +//???! + ZVAL_COPY_VALUE(&tmp, const_value); + if (Z_OPT_CONSTANT(tmp)) { - zval_update_constant_ex(&tmp, (void*)1, NULL TSRMLS_CC); ++ zval_update_constant_ex(&tmp, 1, NULL TSRMLS_CC); + } + zval_opt_copy_ctor(&tmp); + const_value = &tmp; + } + + if (Z_REFCOUNTED_P(element) && Z_REFCOUNT_P(element) > 1) { + ZVAL_DUP(&new_val, element); + zval_ptr_dtor(element); + ZVAL_COPY_VALUE(element, &new_val); + } + + switch (Z_TYPE_P(const_value)) { + case IS_STRING: + ret = zend_symtable_update_current_key_ex(Z_ARRVAL_P(p), Z_STR_P(const_value), HASH_UPDATE_KEY_IF_BEFORE); + break; + case IS_BOOL: + case IS_LONG: + ret = zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_LONG, NULL, Z_LVAL_P(const_value), HASH_UPDATE_KEY_IF_BEFORE); + break; + case IS_DOUBLE: + ret = zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_LONG, NULL, zend_dval_to_lval(Z_DVAL_P(const_value)), HASH_UPDATE_KEY_IF_BEFORE); + break; + case IS_NULL: + ret = zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_STRING, STR_EMPTY_ALLOC(), 0, HASH_UPDATE_KEY_IF_BEFORE); + break; + default: + ret = SUCCESS; + break; + } + if (ret == SUCCESS) { + zend_hash_move_forward(Z_ARRVAL_P(p)); + } + zval_dtor(const_value); + } + zend_hash_apply_with_argument(Z_ARRVAL_P(p), (apply_func_arg_t) zval_update_constant_inline_change, (void *) scope TSRMLS_CC); + zend_hash_internal_pointer_reset(Z_ARRVAL_P(p)); } else if (Z_TYPE_P(p) == IS_CONSTANT_AST) { - SEPARATE_ZVAL_IF_NOT_REF(pp); - p = *pp; + SEPARATE_ZVAL_IF_NOT_REF(p); - zend_ast_evaluate(&const_value, Z_AST_P(p), scope TSRMLS_CC); + zend_ast_evaluate(&tmp, Z_ASTVAL_P(p), scope TSRMLS_CC); if (inline_change) { - zend_ast_destroy(Z_AST_P(p)); + zend_ast_destroy(Z_ASTVAL_P(p)); + efree(Z_AST_P(p)); } - ZVAL_COPY_VALUE(p, &const_value); + ZVAL_COPY_VALUE(p, &tmp); } return 0; } /* }}} */ - ZEND_API int zval_update_constant_inline_change(zval *pp, void *scope TSRMLS_DC) /* {{{ */ -ZEND_API int zval_update_constant_inline_change(zval **pp, zend_class_entry *scope TSRMLS_DC) /* {{{ */ ++ZEND_API int zval_update_constant_inline_change(zval *pp, zend_class_entry *scope TSRMLS_DC) /* {{{ */ { - return zval_update_constant_ex(pp, (void*)1, scope TSRMLS_CC); + return zval_update_constant_ex(pp, 1, scope TSRMLS_CC); } /* }}} */ - ZEND_API int zval_update_constant_no_inline_change(zval *pp, void *scope TSRMLS_DC) /* {{{ */ -ZEND_API int zval_update_constant_no_inline_change(zval **pp, zend_class_entry *scope TSRMLS_DC) /* {{{ */ ++ZEND_API int zval_update_constant_no_inline_change(zval *pp, zend_class_entry *scope TSRMLS_DC) /* {{{ */ { - return zval_update_constant_ex(pp, (void*)0, scope TSRMLS_CC); + return zval_update_constant_ex(pp, 0, scope TSRMLS_CC); } /* }}} */ - ZEND_API int zval_update_constant(zval *pp, void *arg TSRMLS_DC) /* {{{ */ -ZEND_API int zval_update_constant(zval **pp, zend_bool inline_change TSRMLS_DC) /* {{{ */ ++ZEND_API int zval_update_constant(zval *pp, zend_bool inline_change TSRMLS_DC) /* {{{ */ { - return zval_update_constant_ex(pp, arg, NULL TSRMLS_CC); + return zval_update_constant_ex(pp, inline_change, NULL TSRMLS_CC); } /* }}} */ diff --cc Zend/zend_ini_parser.y index 29a2cb0aff,3823efd413..eaf451a3a1 --- a/Zend/zend_ini_parser.y +++ b/Zend/zend_ini_parser.y @@@ -116,21 -122,14 +116,21 @@@ static void zend_ini_get_constant(zval /* If name contains ':' it is not a constant. Bug #26893. */ if (!memchr(Z_STRVAL_P(name), ':', Z_STRLEN_P(name)) - && zend_get_constant(Z_STRVAL_P(name), Z_STRLEN_P(name), &z_constant TSRMLS_CC)) { - /* z_constant is emalloc()'d */ - convert_to_string(&z_constant); - Z_STRVAL_P(result) = zend_strndup(Z_STRVAL(z_constant), Z_STRLEN(z_constant)); - Z_STRLEN_P(result) = Z_STRLEN(z_constant); - Z_TYPE_P(result) = Z_TYPE(z_constant); - zval_dtor(&z_constant); - free(Z_STRVAL_P(name)); + && (c = zend_get_constant(Z_STR_P(name) TSRMLS_CC)) != 0) { + if (Z_TYPE_P(c) != IS_STRING) { + ZVAL_COPY_VALUE(&tmp, c); + if (Z_OPT_CONSTANT(tmp)) { - zval_update_constant_ex(&tmp, (void*)1, NULL TSRMLS_CC); ++ zval_update_constant_ex(&tmp, 1, NULL TSRMLS_CC); + } + zval_opt_copy_ctor(&tmp); + convert_to_string(&tmp); + c = &tmp; + } + ZVAL_PSTRINGL(result, Z_STRVAL_P(c), Z_STRLEN_P(c)); + if (c == &tmp) { + zval_dtor(&tmp); + } + STR_FREE(Z_STR_P(name)); } else { *result = *name; } diff --cc Zend/zend_language_parser.y index 073242b97e,56e702e8f9..ace4f6c284 --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@@ -997,9 -1003,11 +1003,10 @@@ static_scalar_value ; static_operation: - static_scalar_value '[' static_scalar_value ']' { $$.u.ast = zend_ast_create_binary(ZEND_FETCH_DIM_R, $1.u.ast, $3.u.ast); } - | static_scalar_value '+' static_scalar_value { $$.u.ast = zend_ast_create_binary(ZEND_ADD, $1.u.ast, $3.u.ast); } + static_scalar_value '+' static_scalar_value { $$.u.ast = zend_ast_create_binary(ZEND_ADD, $1.u.ast, $3.u.ast); } | static_scalar_value '-' static_scalar_value { $$.u.ast = zend_ast_create_binary(ZEND_SUB, $1.u.ast, $3.u.ast); } | static_scalar_value '*' static_scalar_value { $$.u.ast = zend_ast_create_binary(ZEND_MUL, $1.u.ast, $3.u.ast); } + | static_scalar_value T_POW static_scalar_value { $$.u.ast = zend_ast_create_binary(ZEND_POW, $1.u.ast, $3.u.ast); } | static_scalar_value '/' static_scalar_value { $$.u.ast = zend_ast_create_binary(ZEND_DIV, $1.u.ast, $3.u.ast); } | static_scalar_value '%' static_scalar_value { $$.u.ast = zend_ast_create_binary(ZEND_MOD, $1.u.ast, $3.u.ast); } | '!' static_scalar_value { $$.u.ast = zend_ast_create_unary(ZEND_BOOL_NOT, $2.u.ast); } diff --cc Zend/zend_language_scanner.c index cd7119f43d,ae41cde77f..be8be6c782 --- a/Zend/zend_language_scanner.c +++ b/Zend/zend_language_scanner.c @@@ -1,7854 -1,7857 +1,7876 @@@ -/* Generated by re2c 0.13.5 */ -#line 1 "Zend/zend_language_scanner.l" -/* - +----------------------------------------------------------------------+ - | Zend Engine | - +----------------------------------------------------------------------+ - | Copyright (c) 1998-2014 Zend Technologies Ltd. (http://www.zend.com) | - +----------------------------------------------------------------------+ - | This source file is subject to version 2.00 of the Zend license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.zend.com/license/2_00.txt. | - | If you did not receive a copy of the Zend license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@zend.com so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Marcus Boerger | - | Nuno Lopes | - | Scott MacVicar | - | Flex version authors: | - | Andi Gutmans | - | Zeev Suraski | - +----------------------------------------------------------------------+ -*/ - -/* $Id$ */ - -#if 0 -# define YYDEBUG(s, c) printf("state: %d char: %c\n", s, c) -#else -# define YYDEBUG(s, c) -#endif - -#include "zend_language_scanner_defs.h" - -#include -#include "zend.h" -#ifdef PHP_WIN32 -# include -#endif -#include "zend_alloc.h" -#include -#include "zend_compile.h" -#include "zend_language_scanner.h" -#include "zend_highlight.h" -#include "zend_constants.h" -#include "zend_variables.h" -#include "zend_operators.h" -#include "zend_API.h" -#include "zend_strtod.h" -#include "zend_exceptions.h" -#include "zend_virtual_cwd.h" -#include "tsrm_config_common.h" - -#define YYCTYPE unsigned char -#define YYFILL(n) { if ((YYCURSOR + n) >= (YYLIMIT + ZEND_MMAP_AHEAD)) { return 0; } } -#define YYCURSOR SCNG(yy_cursor) -#define YYLIMIT SCNG(yy_limit) -#define YYMARKER SCNG(yy_marker) - -#define YYGETCONDITION() SCNG(yy_state) -#define YYSETCONDITION(s) SCNG(yy_state) = s - -#define STATE(name) yyc##name - -/* emulate flex constructs */ -#define BEGIN(state) YYSETCONDITION(STATE(state)) -#define YYSTATE YYGETCONDITION() -#define yytext ((char*)SCNG(yy_text)) -#define yyleng SCNG(yy_leng) -#define yyless(x) do { YYCURSOR = (unsigned char*)yytext + x; \ - yyleng = (unsigned int)x; } while(0) -#define yymore() goto yymore_restart - -/* perform sanity check. If this message is triggered you should - increase the ZEND_MMAP_AHEAD value in the zend_streams.h file */ -#define YYMAXFILL 16 -#if ZEND_MMAP_AHEAD < YYMAXFILL -# error ZEND_MMAP_AHEAD should be greater than or equal to YYMAXFILL -#endif - -#ifdef HAVE_STDARG_H -# include -#endif - -#ifdef HAVE_UNISTD_H -# include -#endif - -/* Globals Macros */ -#define SCNG LANG_SCNG -#ifdef ZTS -ZEND_API ts_rsrc_id language_scanner_globals_id; -#else -ZEND_API zend_php_scanner_globals language_scanner_globals; -#endif - -#define HANDLE_NEWLINES(s, l) \ -do { \ - char *p = (s), *boundary = p+(l); \ - \ - while (p= 'a' && (c) <= 'z') || ((c) >= 'A' && (c) <= 'Z') || (c) == '_' || (c) >= 0x7F) - -#define ZEND_IS_OCT(c) ((c)>='0' && (c)<='7') -#define ZEND_IS_HEX(c) (((c)>='0' && (c)<='9') || ((c)>='a' && (c)<='f') || ((c)>='A' && (c)<='F')) - -BEGIN_EXTERN_C() - -static size_t encoding_filter_script_to_internal(unsigned char **to, size_t *to_length, const unsigned char *from, size_t from_length TSRMLS_DC) -{ - const zend_encoding *internal_encoding = zend_multibyte_get_internal_encoding(TSRMLS_C); - assert(internal_encoding && zend_multibyte_check_lexer_compatibility(internal_encoding)); - return zend_multibyte_encoding_converter(to, to_length, from, from_length, internal_encoding, LANG_SCNG(script_encoding) TSRMLS_CC); -} - -static size_t encoding_filter_script_to_intermediate(unsigned char **to, size_t *to_length, const unsigned char *from, size_t from_length TSRMLS_DC) -{ - return zend_multibyte_encoding_converter(to, to_length, from, from_length, zend_multibyte_encoding_utf8, LANG_SCNG(script_encoding) TSRMLS_CC); -} - -static size_t encoding_filter_intermediate_to_script(unsigned char **to, size_t *to_length, const unsigned char *from, size_t from_length TSRMLS_DC) -{ - return zend_multibyte_encoding_converter(to, to_length, from, from_length, -LANG_SCNG(script_encoding), zend_multibyte_encoding_utf8 TSRMLS_CC); -} - -static size_t encoding_filter_intermediate_to_internal(unsigned char **to, size_t *to_length, const unsigned char *from, size_t from_length TSRMLS_DC) -{ - const zend_encoding *internal_encoding = zend_multibyte_get_internal_encoding(TSRMLS_C); - assert(internal_encoding && zend_multibyte_check_lexer_compatibility(internal_encoding)); - return zend_multibyte_encoding_converter(to, to_length, from, from_length, -internal_encoding, zend_multibyte_encoding_utf8 TSRMLS_CC); -} - - -static void _yy_push_state(int new_state TSRMLS_DC) -{ - zend_stack_push(&SCNG(state_stack), (void *) &YYGETCONDITION(), sizeof(int)); - YYSETCONDITION(new_state); -} - -#define yy_push_state(state_and_tsrm) _yy_push_state(yyc##state_and_tsrm) - -static void yy_pop_state(TSRMLS_D) -{ - int *stack_state; - zend_stack_top(&SCNG(state_stack), (void **) &stack_state); - YYSETCONDITION(*stack_state); - zend_stack_del_top(&SCNG(state_stack)); -} - -static void yy_scan_buffer(char *str, unsigned int len TSRMLS_DC) -{ - YYCURSOR = (YYCTYPE*)str; - YYLIMIT = YYCURSOR + len; - if (!SCNG(yy_start)) { - SCNG(yy_start) = YYCURSOR; - } -} - -void startup_scanner(TSRMLS_D) -{ - CG(parse_error) = 0; - CG(doc_comment) = NULL; - CG(doc_comment_len) = 0; - zend_stack_init(&SCNG(state_stack)); - zend_ptr_stack_init(&SCNG(heredoc_label_stack)); -} - -static void heredoc_label_dtor(zend_heredoc_label *heredoc_label) { - efree(heredoc_label->label); -} - -void shutdown_scanner(TSRMLS_D) -{ - CG(parse_error) = 0; - RESET_DOC_COMMENT(); - zend_stack_destroy(&SCNG(state_stack)); - zend_ptr_stack_clean(&SCNG(heredoc_label_stack), (void (*)(void *)) &heredoc_label_dtor, 1); - zend_ptr_stack_destroy(&SCNG(heredoc_label_stack)); -} - -ZEND_API void zend_save_lexical_state(zend_lex_state *lex_state TSRMLS_DC) -{ - lex_state->yy_leng = SCNG(yy_leng); - lex_state->yy_start = SCNG(yy_start); - lex_state->yy_text = SCNG(yy_text); - lex_state->yy_cursor = SCNG(yy_cursor); - lex_state->yy_marker = SCNG(yy_marker); - lex_state->yy_limit = SCNG(yy_limit); - - lex_state->state_stack = SCNG(state_stack); - zend_stack_init(&SCNG(state_stack)); - - lex_state->heredoc_label_stack = SCNG(heredoc_label_stack); - zend_ptr_stack_init(&SCNG(heredoc_label_stack)); - - lex_state->in = SCNG(yy_in); - lex_state->yy_state = YYSTATE; - lex_state->filename = zend_get_compiled_filename(TSRMLS_C); - lex_state->lineno = CG(zend_lineno); - - lex_state->script_org = SCNG(script_org); - lex_state->script_org_size = SCNG(script_org_size); - lex_state->script_filtered = SCNG(script_filtered); - lex_state->script_filtered_size = SCNG(script_filtered_size); - lex_state->input_filter = SCNG(input_filter); - lex_state->output_filter = SCNG(output_filter); - lex_state->script_encoding = SCNG(script_encoding); -} - -ZEND_API void zend_restore_lexical_state(zend_lex_state *lex_state TSRMLS_DC) -{ - SCNG(yy_leng) = lex_state->yy_leng; - SCNG(yy_start) = lex_state->yy_start; - SCNG(yy_text) = lex_state->yy_text; - SCNG(yy_cursor) = lex_state->yy_cursor; - SCNG(yy_marker) = lex_state->yy_marker; - SCNG(yy_limit) = lex_state->yy_limit; - - zend_stack_destroy(&SCNG(state_stack)); - SCNG(state_stack) = lex_state->state_stack; - - zend_ptr_stack_clean(&SCNG(heredoc_label_stack), (void (*)(void *)) &heredoc_label_dtor, 1); - zend_ptr_stack_destroy(&SCNG(heredoc_label_stack)); - SCNG(heredoc_label_stack) = lex_state->heredoc_label_stack; - - SCNG(yy_in) = lex_state->in; - YYSETCONDITION(lex_state->yy_state); - CG(zend_lineno) = lex_state->lineno; - zend_restore_compiled_filename(lex_state->filename TSRMLS_CC); - - if (SCNG(script_filtered)) { - efree(SCNG(script_filtered)); - SCNG(script_filtered) = NULL; - } - SCNG(script_org) = lex_state->script_org; - SCNG(script_org_size) = lex_state->script_org_size; - SCNG(script_filtered) = lex_state->script_filtered; - SCNG(script_filtered_size) = lex_state->script_filtered_size; - SCNG(input_filter) = lex_state->input_filter; - SCNG(output_filter) = lex_state->output_filter; - SCNG(script_encoding) = lex_state->script_encoding; - - RESET_DOC_COMMENT(); -} - -ZEND_API void zend_destroy_file_handle(zend_file_handle *file_handle TSRMLS_DC) -{ - zend_llist_del_element(&CG(open_files), file_handle, (int (*)(void *, void *)) zend_compare_file_handles); - /* zend_file_handle_dtor() operates on the copy, so we have to NULLify the original here */ - file_handle->opened_path = NULL; - if (file_handle->free_filename) { - file_handle->filename = NULL; - } -} - -#define BOM_UTF32_BE "\x00\x00\xfe\xff" -#define BOM_UTF32_LE "\xff\xfe\x00\x00" -#define BOM_UTF16_BE "\xfe\xff" -#define BOM_UTF16_LE "\xff\xfe" -#define BOM_UTF8 "\xef\xbb\xbf" - -static const zend_encoding *zend_multibyte_detect_utf_encoding(const unsigned char *script, size_t script_size TSRMLS_DC) -{ - const unsigned char *p; - int wchar_size = 2; - int le = 0; - - /* utf-16 or utf-32? */ - p = script; - while ((p-script) < script_size) { - p = memchr(p, 0, script_size-(p-script)-2); - if (!p) { - break; - } - if (*(p+1) == '\0' && *(p+2) == '\0') { - wchar_size = 4; - break; - } - - /* searching for UTF-32 specific byte orders, so this will do */ - p += 4; - } - - /* BE or LE? */ - p = script; - while ((p-script) < script_size) { - if (*p == '\0' && *(p+wchar_size-1) != '\0') { - /* BE */ - le = 0; - break; - } else if (*p != '\0' && *(p+wchar_size-1) == '\0') { - /* LE* */ - le = 1; - break; - } - p += wchar_size; - } - - if (wchar_size == 2) { - return le ? zend_multibyte_encoding_utf16le : zend_multibyte_encoding_utf16be; - } else { - return le ? zend_multibyte_encoding_utf32le : zend_multibyte_encoding_utf32be; - } - - return NULL; -} - -static const zend_encoding* zend_multibyte_detect_unicode(TSRMLS_D) -{ - const zend_encoding *script_encoding = NULL; - int bom_size; - unsigned char *pos1, *pos2; - - if (LANG_SCNG(script_org_size) < sizeof(BOM_UTF32_LE)-1) { - return NULL; - } - - /* check out BOM */ - if (!memcmp(LANG_SCNG(script_org), BOM_UTF32_BE, sizeof(BOM_UTF32_BE)-1)) { - script_encoding = zend_multibyte_encoding_utf32be; - bom_size = sizeof(BOM_UTF32_BE)-1; - } else if (!memcmp(LANG_SCNG(script_org), BOM_UTF32_LE, sizeof(BOM_UTF32_LE)-1)) { - script_encoding = zend_multibyte_encoding_utf32le; - bom_size = sizeof(BOM_UTF32_LE)-1; - } else if (!memcmp(LANG_SCNG(script_org), BOM_UTF16_BE, sizeof(BOM_UTF16_BE)-1)) { - script_encoding = zend_multibyte_encoding_utf16be; - bom_size = sizeof(BOM_UTF16_BE)-1; - } else if (!memcmp(LANG_SCNG(script_org), BOM_UTF16_LE, sizeof(BOM_UTF16_LE)-1)) { - script_encoding = zend_multibyte_encoding_utf16le; - bom_size = sizeof(BOM_UTF16_LE)-1; - } else if (!memcmp(LANG_SCNG(script_org), BOM_UTF8, sizeof(BOM_UTF8)-1)) { - script_encoding = zend_multibyte_encoding_utf8; - bom_size = sizeof(BOM_UTF8)-1; - } - - if (script_encoding) { - /* remove BOM */ - LANG_SCNG(script_org) += bom_size; - LANG_SCNG(script_org_size) -= bom_size; - - return script_encoding; - } - - /* script contains NULL bytes -> auto-detection */ - if ((pos1 = memchr(LANG_SCNG(script_org), 0, LANG_SCNG(script_org_size)))) { - /* check if the NULL byte is after the __HALT_COMPILER(); */ - pos2 = LANG_SCNG(script_org); - - while (pos1 - pos2 >= sizeof("__HALT_COMPILER();")-1) { - pos2 = memchr(pos2, '_', pos1 - pos2); - if (!pos2) break; - pos2++; - if (strncasecmp((char*)pos2, "_HALT_COMPILER", sizeof("_HALT_COMPILER")-1) == 0) { - pos2 += sizeof("_HALT_COMPILER")-1; - while (*pos2 == ' ' || - *pos2 == '\t' || - *pos2 == '\r' || - *pos2 == '\n') { - pos2++; - } - if (*pos2 == '(') { - pos2++; - while (*pos2 == ' ' || - *pos2 == '\t' || - *pos2 == '\r' || - *pos2 == '\n') { - pos2++; - } - if (*pos2 == ')') { - pos2++; - while (*pos2 == ' ' || - *pos2 == '\t' || - *pos2 == '\r' || - *pos2 == '\n') { - pos2++; - } - if (*pos2 == ';') { - return NULL; - } - } - } - } - } - /* make best effort if BOM is missing */ - return zend_multibyte_detect_utf_encoding(LANG_SCNG(script_org), LANG_SCNG(script_org_size) TSRMLS_CC); - } - - return NULL; -} - -static const zend_encoding* zend_multibyte_find_script_encoding(TSRMLS_D) -{ - const zend_encoding *script_encoding; - - if (CG(detect_unicode)) { - /* check out bom(byte order mark) and see if containing wchars */ - script_encoding = zend_multibyte_detect_unicode(TSRMLS_C); - if (script_encoding != NULL) { - /* bom or wchar detection is prior to 'script_encoding' option */ - return script_encoding; - } - } - - /* if no script_encoding specified, just leave alone */ - if (!CG(script_encoding_list) || !CG(script_encoding_list_size)) { - return NULL; - } - - /* if multiple encodings specified, detect automagically */ - if (CG(script_encoding_list_size) > 1) { - return zend_multibyte_encoding_detector(LANG_SCNG(script_org), LANG_SCNG(script_org_size), CG(script_encoding_list), CG(script_encoding_list_size) TSRMLS_CC); - } - - return CG(script_encoding_list)[0]; -} - -ZEND_API int zend_multibyte_set_filter(const zend_encoding *onetime_encoding TSRMLS_DC) -{ - const zend_encoding *internal_encoding = zend_multibyte_get_internal_encoding(TSRMLS_C); - const zend_encoding *script_encoding = onetime_encoding ? onetime_encoding: zend_multibyte_find_script_encoding(TSRMLS_C); - - if (!script_encoding) { - return FAILURE; - } - - /* judge input/output filter */ - LANG_SCNG(script_encoding) = script_encoding; - LANG_SCNG(input_filter) = NULL; - LANG_SCNG(output_filter) = NULL; - - if (!internal_encoding || LANG_SCNG(script_encoding) == internal_encoding) { - if (!zend_multibyte_check_lexer_compatibility(LANG_SCNG(script_encoding))) { - /* and if not, work around w/ script_encoding -> utf-8 -> script_encoding conversion */ - LANG_SCNG(input_filter) = encoding_filter_script_to_intermediate; - LANG_SCNG(output_filter) = encoding_filter_intermediate_to_script; - } else { - LANG_SCNG(input_filter) = NULL; - LANG_SCNG(output_filter) = NULL; - } - return SUCCESS; - } - - if (zend_multibyte_check_lexer_compatibility(internal_encoding)) { - LANG_SCNG(input_filter) = encoding_filter_script_to_internal; - LANG_SCNG(output_filter) = NULL; - } else if (zend_multibyte_check_lexer_compatibility(LANG_SCNG(script_encoding))) { - LANG_SCNG(input_filter) = NULL; - LANG_SCNG(output_filter) = encoding_filter_script_to_internal; - } else { - /* both script and internal encodings are incompatible w/ flex */ - LANG_SCNG(input_filter) = encoding_filter_script_to_intermediate; - LANG_SCNG(output_filter) = encoding_filter_intermediate_to_internal; - } - - return 0; -} - -ZEND_API int open_file_for_scanning(zend_file_handle *file_handle TSRMLS_DC) -{ - const char *file_path = NULL; - char *buf; - size_t size, offset = 0; - - /* The shebang line was read, get the current position to obtain the buffer start */ - if (CG(start_lineno) == 2 && file_handle->type == ZEND_HANDLE_FP && file_handle->handle.fp) { - if ((offset = ftell(file_handle->handle.fp)) == -1) { - offset = 0; - } - } - - if (zend_stream_fixup(file_handle, &buf, &size TSRMLS_CC) == FAILURE) { - return FAILURE; - } - - zend_llist_add_element(&CG(open_files), file_handle); - if (file_handle->handle.stream.handle >= (void*)file_handle && file_handle->handle.stream.handle <= (void*)(file_handle+1)) { - zend_file_handle *fh = (zend_file_handle*)zend_llist_get_last(&CG(open_files)); - size_t diff = (char*)file_handle->handle.stream.handle - (char*)file_handle; - fh->handle.stream.handle = (void*)(((char*)fh) + diff); - file_handle->handle.stream.handle = fh->handle.stream.handle; - } - - /* Reset the scanner for scanning the new file */ - SCNG(yy_in) = file_handle; - SCNG(yy_start) = NULL; - - if (size != -1) { - if (CG(multibyte)) { - SCNG(script_org) = (unsigned char*)buf; - SCNG(script_org_size) = size; - SCNG(script_filtered) = NULL; - - zend_multibyte_set_filter(NULL TSRMLS_CC); - - if (SCNG(input_filter)) { - if ((size_t)-1 == SCNG(input_filter)(&SCNG(script_filtered), &SCNG(script_filtered_size), SCNG(script_org), SCNG(script_org_size) TSRMLS_CC)) { - zend_error_noreturn(E_COMPILE_ERROR, "Could not convert the script from the detected " - "encoding \"%s\" to a compatible encoding", zend_multibyte_get_encoding_name(LANG_SCNG(script_encoding))); - } - buf = (char*)SCNG(script_filtered); - size = SCNG(script_filtered_size); - } - } - SCNG(yy_start) = (unsigned char *)buf - offset; - yy_scan_buffer(buf, size TSRMLS_CC); - } else { - zend_error_noreturn(E_COMPILE_ERROR, "zend_stream_mmap() failed"); - } - - BEGIN(INITIAL); - - if (file_handle->opened_path) { - file_path = file_handle->opened_path; - } else { - file_path = file_handle->filename; - } - - zend_set_compiled_filename(file_path TSRMLS_CC); - - if (CG(start_lineno)) { - CG(zend_lineno) = CG(start_lineno); - CG(start_lineno) = 0; - } else { - CG(zend_lineno) = 1; - } - - RESET_DOC_COMMENT(); - CG(increment_lineno) = 0; - return SUCCESS; -} -END_EXTERN_C() - - -ZEND_API zend_op_array *compile_file(zend_file_handle *file_handle, int type TSRMLS_DC) -{ - zend_lex_state original_lex_state; - zend_op_array *op_array = (zend_op_array *) emalloc(sizeof(zend_op_array)); - zend_op_array *original_active_op_array = CG(active_op_array); - zend_op_array *retval=NULL; - int compiler_result; - zend_bool compilation_successful=0; - znode retval_znode; - zend_bool original_in_compilation = CG(in_compilation); - - retval_znode.op_type = IS_CONST; - INIT_PZVAL(&retval_znode.u.constant); - ZVAL_LONG(&retval_znode.u.constant, 1); - - zend_save_lexical_state(&original_lex_state TSRMLS_CC); - - retval = op_array; /* success oriented */ - - if (open_file_for_scanning(file_handle TSRMLS_CC)==FAILURE) { - if (type==ZEND_REQUIRE) { - zend_message_dispatcher(ZMSG_FAILED_REQUIRE_FOPEN, file_handle->filename TSRMLS_CC); - zend_bailout(); - } else { - zend_message_dispatcher(ZMSG_FAILED_INCLUDE_FOPEN, file_handle->filename TSRMLS_CC); - } - compilation_successful=0; - } else { - init_op_array(op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE TSRMLS_CC); - CG(in_compilation) = 1; - CG(active_op_array) = op_array; - zend_stack_push(&CG(context_stack), (void *) &CG(context), sizeof(CG(context))); - zend_init_compiler_context(TSRMLS_C); - compiler_result = zendparse(TSRMLS_C); - zend_do_return(&retval_znode, 0 TSRMLS_CC); - CG(in_compilation) = original_in_compilation; - if (compiler_result != 0) { /* parser error */ - zend_bailout(); - } - compilation_successful=1; - } - - if (retval) { - CG(active_op_array) = original_active_op_array; - if (compilation_successful) { - pass_two(op_array TSRMLS_CC); - zend_release_labels(0 TSRMLS_CC); - } else { - efree(op_array); - retval = NULL; - } - } - zend_restore_lexical_state(&original_lex_state TSRMLS_CC); - return retval; -} - - -zend_op_array *compile_filename(int type, zval *filename TSRMLS_DC) -{ - zend_file_handle file_handle; - zval tmp; - zend_op_array *retval; - char *opened_path = NULL; - - if (filename->type != IS_STRING) { - tmp = *filename; - zval_copy_ctor(&tmp); - convert_to_string(&tmp); - filename = &tmp; - } - file_handle.filename = Z_STRVAL_P(filename); - file_handle.free_filename = 0; - file_handle.type = ZEND_HANDLE_FILENAME; - file_handle.opened_path = NULL; - file_handle.handle.fp = NULL; - - retval = zend_compile_file(&file_handle, type TSRMLS_CC); - if (retval && file_handle.handle.stream.handle) { - int dummy = 1; - - if (!file_handle.opened_path) { - file_handle.opened_path = opened_path = estrndup(Z_STRVAL_P(filename), Z_STRLEN_P(filename)); - } - - zend_hash_add(&EG(included_files), file_handle.opened_path, strlen(file_handle.opened_path)+1, (void *)&dummy, sizeof(int), NULL); - - if (opened_path) { - efree(opened_path); - } - } - zend_destroy_file_handle(&file_handle TSRMLS_CC); - - if (filename==&tmp) { - zval_dtor(&tmp); - } - return retval; -} - -ZEND_API int zend_prepare_string_for_scanning(zval *str, char *filename TSRMLS_DC) -{ - char *buf; - size_t size; - - /* enforce ZEND_MMAP_AHEAD trailing NULLs for flex... */ - Z_STRVAL_P(str) = str_erealloc(Z_STRVAL_P(str), Z_STRLEN_P(str) + ZEND_MMAP_AHEAD); - memset(Z_STRVAL_P(str) + Z_STRLEN_P(str), 0, ZEND_MMAP_AHEAD); - - SCNG(yy_in) = NULL; - SCNG(yy_start) = NULL; - - buf = Z_STRVAL_P(str); - size = Z_STRLEN_P(str); - - if (CG(multibyte)) { - SCNG(script_org) = (unsigned char*)buf; - SCNG(script_org_size) = size; - SCNG(script_filtered) = NULL; - - zend_multibyte_set_filter(zend_multibyte_get_internal_encoding(TSRMLS_C) TSRMLS_CC); - - if (SCNG(input_filter)) { - if ((size_t)-1 == SCNG(input_filter)(&SCNG(script_filtered), &SCNG(script_filtered_size), SCNG(script_org), SCNG(script_org_size) TSRMLS_CC)) { - zend_error_noreturn(E_COMPILE_ERROR, "Could not convert the script from the detected " - "encoding \"%s\" to a compatible encoding", zend_multibyte_get_encoding_name(LANG_SCNG(script_encoding))); - } - buf = (char*)SCNG(script_filtered); - size = SCNG(script_filtered_size); - } - } - - yy_scan_buffer(buf, size TSRMLS_CC); - - zend_set_compiled_filename(filename TSRMLS_CC); - CG(zend_lineno) = 1; - CG(increment_lineno) = 0; - RESET_DOC_COMMENT(); - return SUCCESS; -} - - -ZEND_API size_t zend_get_scanned_file_offset(TSRMLS_D) -{ - size_t offset = SCNG(yy_cursor) - SCNG(yy_start); - if (SCNG(input_filter)) { - size_t original_offset = offset, length = 0; - do { - unsigned char *p = NULL; - if ((size_t)-1 == SCNG(input_filter)(&p, &length, SCNG(script_org), offset TSRMLS_CC)) { - return (size_t)-1; - } - efree(p); - if (length > original_offset) { - offset--; - } else if (length < original_offset) { - offset++; - } - } while (original_offset != length); - } - return offset; -} - - -zend_op_array *compile_string(zval *source_string, char *filename TSRMLS_DC) -{ - zend_lex_state original_lex_state; - zend_op_array *op_array = (zend_op_array *) emalloc(sizeof(zend_op_array)); - zend_op_array *original_active_op_array = CG(active_op_array); - zend_op_array *retval; - zval tmp; - int compiler_result; - zend_bool original_in_compilation = CG(in_compilation); - - if (Z_STRLEN_P(source_string)==0) { - efree(op_array); - return NULL; - } - - CG(in_compilation) = 1; - - tmp = *source_string; - zval_copy_ctor(&tmp); - convert_to_string(&tmp); - source_string = &tmp; - - zend_save_lexical_state(&original_lex_state TSRMLS_CC); - if (zend_prepare_string_for_scanning(source_string, filename TSRMLS_CC)==FAILURE) { - efree(op_array); - retval = NULL; - } else { - zend_bool orig_interactive = CG(interactive); - - CG(interactive) = 0; - init_op_array(op_array, ZEND_EVAL_CODE, INITIAL_OP_ARRAY_SIZE TSRMLS_CC); - CG(interactive) = orig_interactive; - CG(active_op_array) = op_array; - zend_stack_push(&CG(context_stack), (void *) &CG(context), sizeof(CG(context))); - zend_init_compiler_context(TSRMLS_C); - BEGIN(ST_IN_SCRIPTING); - compiler_result = zendparse(TSRMLS_C); - - if (SCNG(script_filtered)) { - efree(SCNG(script_filtered)); - SCNG(script_filtered) = NULL; - } - - if (compiler_result != 0) { - CG(active_op_array) = original_active_op_array; - CG(unclean_shutdown)=1; - destroy_op_array(op_array TSRMLS_CC); - efree(op_array); - retval = NULL; - } else { - zend_do_return(NULL, 0 TSRMLS_CC); - CG(active_op_array) = original_active_op_array; - pass_two(op_array TSRMLS_CC); - zend_release_labels(0 TSRMLS_CC); - retval = op_array; - } - } - zend_restore_lexical_state(&original_lex_state TSRMLS_CC); - zval_dtor(&tmp); - CG(in_compilation) = original_in_compilation; - return retval; -} - - -BEGIN_EXTERN_C() -int highlight_file(char *filename, zend_syntax_highlighter_ini *syntax_highlighter_ini TSRMLS_DC) -{ - zend_lex_state original_lex_state; - zend_file_handle file_handle; - - file_handle.type = ZEND_HANDLE_FILENAME; - file_handle.filename = filename; - file_handle.free_filename = 0; - file_handle.opened_path = NULL; - zend_save_lexical_state(&original_lex_state TSRMLS_CC); - if (open_file_for_scanning(&file_handle TSRMLS_CC)==FAILURE) { - zend_message_dispatcher(ZMSG_FAILED_HIGHLIGHT_FOPEN, filename TSRMLS_CC); - zend_restore_lexical_state(&original_lex_state TSRMLS_CC); - return FAILURE; - } - zend_highlight(syntax_highlighter_ini TSRMLS_CC); - if (SCNG(script_filtered)) { - efree(SCNG(script_filtered)); - SCNG(script_filtered) = NULL; - } - zend_destroy_file_handle(&file_handle TSRMLS_CC); - zend_restore_lexical_state(&original_lex_state TSRMLS_CC); - return SUCCESS; -} - -int highlight_string(zval *str, zend_syntax_highlighter_ini *syntax_highlighter_ini, char *str_name TSRMLS_DC) -{ - zend_lex_state original_lex_state; - zval tmp = *str; - - str = &tmp; - zval_copy_ctor(str); - zend_save_lexical_state(&original_lex_state TSRMLS_CC); - if (zend_prepare_string_for_scanning(str, str_name TSRMLS_CC)==FAILURE) { - zend_restore_lexical_state(&original_lex_state TSRMLS_CC); - return FAILURE; - } - BEGIN(INITIAL); - zend_highlight(syntax_highlighter_ini TSRMLS_CC); - if (SCNG(script_filtered)) { - efree(SCNG(script_filtered)); - SCNG(script_filtered) = NULL; - } - zend_restore_lexical_state(&original_lex_state TSRMLS_CC); - zval_dtor(str); - return SUCCESS; -} - -ZEND_API void zend_multibyte_yyinput_again(zend_encoding_filter old_input_filter, const zend_encoding *old_encoding TSRMLS_DC) -{ - size_t length; - unsigned char *new_yy_start; - - /* convert and set */ - if (!SCNG(input_filter)) { - if (SCNG(script_filtered)) { - efree(SCNG(script_filtered)); - SCNG(script_filtered) = NULL; - } - SCNG(script_filtered_size) = 0; - length = SCNG(script_org_size); - new_yy_start = SCNG(script_org); - } else { - if ((size_t)-1 == SCNG(input_filter)(&new_yy_start, &length, SCNG(script_org), SCNG(script_org_size) TSRMLS_CC)) { - zend_error_noreturn(E_COMPILE_ERROR, "Could not convert the script from the detected " - "encoding \"%s\" to a compatible encoding", zend_multibyte_get_encoding_name(LANG_SCNG(script_encoding))); - } - SCNG(script_filtered) = new_yy_start; - SCNG(script_filtered_size) = length; - } - - SCNG(yy_cursor) = new_yy_start + (SCNG(yy_cursor) - SCNG(yy_start)); - SCNG(yy_marker) = new_yy_start + (SCNG(yy_marker) - SCNG(yy_start)); - SCNG(yy_text) = new_yy_start + (SCNG(yy_text) - SCNG(yy_start)); - SCNG(yy_limit) = new_yy_start + (SCNG(yy_limit) - SCNG(yy_start)); - - SCNG(yy_start) = new_yy_start; -} - - -# define zend_copy_value(zendlval, yytext, yyleng) \ - if (SCNG(output_filter)) { \ - size_t sz = 0; \ - SCNG(output_filter)((unsigned char **)&Z_STRVAL_P(zendlval), &sz, (unsigned char *)yytext, (size_t)yyleng TSRMLS_CC); \ - Z_STRLEN_P(zendlval) = sz; \ - } else { \ - Z_STRVAL_P(zendlval) = (char *) estrndup(yytext, yyleng); \ - Z_STRLEN_P(zendlval) = yyleng; \ - } - -static void zend_scan_escape_string(zval *zendlval, char *str, int len, char quote_type TSRMLS_DC) -{ - register char *s, *t; - char *end; - - ZVAL_STRINGL(zendlval, str, len, 1); - - /* convert escape sequences */ - s = t = Z_STRVAL_P(zendlval); - end = s+Z_STRLEN_P(zendlval); - while (s= end) { - *t++ = '\\'; - break; - } - - switch(*s) { - case 'n': - *t++ = '\n'; - Z_STRLEN_P(zendlval)--; - break; - case 'r': - *t++ = '\r'; - Z_STRLEN_P(zendlval)--; - break; - case 't': - *t++ = '\t'; - Z_STRLEN_P(zendlval)--; - break; - case 'f': - *t++ = '\f'; - Z_STRLEN_P(zendlval)--; - break; - case 'v': - *t++ = '\v'; - Z_STRLEN_P(zendlval)--; - break; - case 'e': -#ifdef PHP_WIN32 - *t++ = VK_ESCAPE; -#else - *t++ = '\e'; -#endif - Z_STRLEN_P(zendlval)--; - break; - case '"': - case '`': - if (*s != quote_type) { - *t++ = '\\'; - *t++ = *s; - break; - } - case '\\': - case '$': - *t++ = *s; - Z_STRLEN_P(zendlval)--; - break; - case 'x': - case 'X': - if (ZEND_IS_HEX(*(s+1))) { - char hex_buf[3] = { 0, 0, 0 }; - - Z_STRLEN_P(zendlval)--; /* for the 'x' */ - - hex_buf[0] = *(++s); - Z_STRLEN_P(zendlval)--; - if (ZEND_IS_HEX(*(s+1))) { - hex_buf[1] = *(++s); - Z_STRLEN_P(zendlval)--; - } - *t++ = (char) strtol(hex_buf, NULL, 16); - } else { - *t++ = '\\'; - *t++ = *s; - } - break; - default: - /* check for an octal */ - if (ZEND_IS_OCT(*s)) { - char octal_buf[4] = { 0, 0, 0, 0 }; - - octal_buf[0] = *s; - Z_STRLEN_P(zendlval)--; - if (ZEND_IS_OCT(*(s+1))) { - octal_buf[1] = *(++s); - Z_STRLEN_P(zendlval)--; - if (ZEND_IS_OCT(*(s+1))) { - octal_buf[2] = *(++s); - Z_STRLEN_P(zendlval)--; - } - } - *t++ = (char) strtol(octal_buf, NULL, 8); - } else { - *t++ = '\\'; - *t++ = *s; - } - break; - } - } else { - *t++ = *s; - } - - if (*s == '\n' || (*s == '\r' && (*(s+1) != '\n'))) { - CG(zend_lineno)++; - } - s++; - } - *t = 0; - if (SCNG(output_filter)) { - size_t sz = 0; - s = Z_STRVAL_P(zendlval); - SCNG(output_filter)((unsigned char **)&Z_STRVAL_P(zendlval), &sz, (unsigned char *)s, (size_t)Z_STRLEN_P(zendlval) TSRMLS_CC); - Z_STRLEN_P(zendlval) = sz; - efree(s); - } -} - - -int lex_scan(zval *zendlval TSRMLS_DC) -{ -restart: - SCNG(yy_text) = YYCURSOR; - -yymore_restart: - - -#line 1001 "Zend/zend_language_scanner.c" -{ - YYCTYPE yych; - unsigned int yyaccept = 0; - if (YYGETCONDITION() < 5) { - if (YYGETCONDITION() < 2) { - if (YYGETCONDITION() < 1) { - goto yyc_ST_IN_SCRIPTING; - } else { - goto yyc_ST_LOOKING_FOR_PROPERTY; - } - } else { - if (YYGETCONDITION() < 3) { - goto yyc_ST_BACKQUOTE; - } else { - if (YYGETCONDITION() < 4) { - goto yyc_ST_DOUBLE_QUOTES; - } else { - goto yyc_ST_HEREDOC; - } - } - } - } else { - if (YYGETCONDITION() < 7) { - if (YYGETCONDITION() < 6) { - goto yyc_ST_LOOKING_FOR_VARNAME; - } else { - goto yyc_ST_VAR_OFFSET; - } - } else { - if (YYGETCONDITION() < 8) { - goto yyc_INITIAL; - } else { - if (YYGETCONDITION() < 9) { - goto yyc_ST_END_HEREDOC; - } else { - goto yyc_ST_NOWDOC; - } - } - } - } -/* *********************************** */ -yyc_INITIAL: - { - static const unsigned char yybm[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 128, 128, 0, 0, 128, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 128, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }; - - YYDEBUG(0, *YYCURSOR); - YYFILL(8); - yych = *YYCURSOR; - if (yych != '<') goto yy4; - YYDEBUG(2, *YYCURSOR); - yyaccept = 0; - yych = *(YYMARKER = ++YYCURSOR); - if (yych <= '?') { - if (yych == '%') goto yy7; - if (yych >= '?') goto yy5; - } else { - if (yych <= 'S') { - if (yych >= 'S') goto yy9; - } else { - if (yych == 's') goto yy9; - } - } -yy3: - YYDEBUG(3, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 1749 "Zend/zend_language_scanner.l" - { - if (YYCURSOR > YYLIMIT) { - return 0; - } - -inline_char_handler: - - while (1) { - YYCTYPE *ptr = memchr(YYCURSOR, '<', YYLIMIT - YYCURSOR); - - YYCURSOR = ptr ? ptr + 1 : YYLIMIT; - - if (YYCURSOR < YYLIMIT) { - switch (*YYCURSOR) { - case '?': - if (CG(short_tags) || !strncasecmp((char*)YYCURSOR + 1, "php", 3) || (*(YYCURSOR + 1) == '=')) { /* Assume [ \t\n\r] follows "php" */ - break; - } - continue; - case '%': - if (CG(asp_tags)) { - break; - } - continue; - case 's': - case 'S': - /* Probably NOT an opening PHP