com php-src: Fix encoding declaration handling: Zend/tests/decl are_001.phpt Zend/tests/declare_003.phpt Zend/zend_compile.c Zend/zend_compile.h
Zend/zen d_language_parser.y

From: Date: Mon, 18 Aug 2014 14:27:53 +0000
Subject: com php-src: Fix encoding declaration handling: Zend/tests/decl are_001.phpt Zend/tests/declare_003.phpt Zend/zend_compile.c Zend/zend_compile.h
Zend/zen d_language_parser.y
Groups: php.cvs 
Request: Send a blank email to php-cvs+get-80857@lists.php.net to get a copy of this message
Commit: 458f67cd2109620c5f59305a56c64f07c886720d Author: Nikita Popov <nikic@php.net> Mon, 18 Aug 2014 16:07:18 +0200 Parents: 2a26cbb70e11c045cbb21966c1053e41b805d18f Branches: master Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=458f67cd2109620c5f59305a56c64f07c886720d Log: Fix encoding declaration handling As the encoding declaration influences lexing it needs to be immidiately handled in the parser. Changed paths: M Zend/tests/declare_001.phpt M Zend/tests/declare_003.phpt M Zend/zend_compile.c M Zend/zend_compile.h M Zend/zend_language_parser.y Diff: diff --git a/Zend/tests/declare_001.phpt b/Zend/tests/declare_001.phpt index 21d7978..4eff180 100644 --- a/Zend/tests/declare_001.phpt +++ b/Zend/tests/declare_001.phpt @@ -13,7 +13,6 @@ zend.multibyte=1 declare(encoding = 1); declare(encoding = 112313123213131232100); -declare(encoding = NULL); declare(encoding = 'utf-8'); declare(encoding = M_PI); @@ -25,6 +24,4 @@ Warning: Unsupported encoding [1] in %sdeclare_001.php on line %d Warning: Unsupported encoding [1.1231312321313E+20] in %sdeclare_001.php on line %d -Warning: Unsupported encoding [] in %sdeclare_001.php on line %d - -Fatal error: Cannot use constants as encoding in %sdeclare_001.php on line %d +Fatal error: Encoding must be a literal in %s on line %d diff --git a/Zend/tests/declare_003.phpt b/Zend/tests/declare_003.phpt index 2980f75..2f3e887 100644 --- a/Zend/tests/declare_003.phpt +++ b/Zend/tests/declare_003.phpt @@ -8,7 +8,6 @@ zend.multibyte=1 declare(encoding = 1); declare(encoding = 11111111111111); -declare(encoding = NULL); declare(encoding = M_PI); print 'DONE'; @@ -19,6 +18,4 @@ Warning: Unsupported encoding [1] in %sdeclare_003.php on line %d Warning: Unsupported encoding [11111111111111] in %sdeclare_003.php on line %d -Warning: Unsupported encoding [] in %sdeclare_003.php on line %d - -Fatal error: Cannot use constants as encoding in %sdeclare_003.php on line %d +Fatal error: Encoding must be a literal in %s on line %d diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 4a04862..5b35233 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -5113,61 +5113,31 @@ void zend_compile_try(zend_ast *ast TSRMLS_DC) { efree(jmp_opnums); } -void zend_compile_declare(zend_ast *ast TSRMLS_DC) { - zend_ast_list *declares = zend_ast_get_list(ast->child[0]); - zend_ast *stmt_ast = ast->child[1]; - zend_declarables orig_declarables = CG(declarables); +/* Encoding declarations must already be handled during parsing */ +void zend_handle_encoding_declaration(zend_ast_list *declares TSRMLS_DC) { zend_uint i; - for (i = 0; i < declares->children; ++i) { zend_ast *declare_ast = declares->child[i]; zend_ast *name_ast = declare_ast->child[0]; zend_ast *value_ast = declare_ast->child[1]; - zend_string *name = zend_ast_get_str(name_ast); - zval value_zv; - - zend_const_expr_to_zval(&value_zv, value_ast TSRMLS_CC); - - if (zend_str_equals_literal_ci(name, "ticks")) { - convert_to_long(&value_zv); - ZVAL_COPY_VALUE(&CG(declarables).ticks, &value_zv); - } else if (zend_str_equals_literal_ci(name, "encoding")) { - if (Z_TYPE(value_zv) == IS_CONSTANT) { - zend_error_noreturn(E_COMPILE_ERROR, "Cannot use constants as encoding"); - } - - /* - * Check that the pragma comes before any opcodes. If the compilation - * got as far as this, the previous portion of the script must have been - * parseable according to the .ini script_encoding setting. We still - * want to tell them to put declare() at the top. - */ - { - zend_uint num = CG(active_op_array)->last; - /* ignore ZEND_EXT_STMT and ZEND_TICKS */ - while (num > 0 && - (CG(active_op_array)->opcodes[num-1].opcode == ZEND_EXT_STMT || - CG(active_op_array)->opcodes[num-1].opcode == ZEND_TICKS)) { - --num; - } - if (num > 0) { - zend_error_noreturn(E_COMPILE_ERROR, "Encoding declaration pragma must be " - "the very first statement in the script"); - } + if (zend_str_equals_literal_ci(name, "encoding")) { + if (value_ast->kind != ZEND_AST_ZVAL) { + zend_error_noreturn(E_COMPILE_ERROR, "Encoding must be a literal"); } if (CG(multibyte)) { + zend_string *encoding_name = zval_get_string(zend_ast_get_zval(value_ast)); + const zend_encoding *new_encoding, *old_encoding; zend_encoding_filter old_input_filter; CG(encoding_declared) = 1; - convert_to_string(&value_zv); - new_encoding = zend_multibyte_fetch_encoding(Z_STRVAL(value_zv) TSRMLS_CC); + new_encoding = zend_multibyte_fetch_encoding(encoding_name->val TSRMLS_CC); if (!new_encoding) { - zend_error(E_COMPILE_WARNING, "Unsupported encoding [%s]", Z_STRVAL(value_zv)); + zend_error(E_COMPILE_WARNING, "Unsupported encoding [%s]", encoding_name->val); } else { old_input_filter = LANG_SCNG(input_filter); old_encoding = LANG_SCNG(script_encoding); @@ -5179,14 +5149,50 @@ void zend_compile_declare(zend_ast *ast TSRMLS_DC) { zend_multibyte_yyinput_again(old_input_filter, old_encoding TSRMLS_CC); } } + + STR_RELEASE(encoding_name); } else { zend_error(E_COMPILE_WARNING, "declare(encoding=...) ignored because " "Zend multibyte feature is turned off by settings"); } + } + } +} + +void zend_compile_declare(zend_ast *ast TSRMLS_DC) { + zend_ast_list *declares = zend_ast_get_list(ast->child[0]); + zend_ast *stmt_ast = ast->child[1]; + zend_declarables orig_declarables = CG(declarables); + zend_uint i; + + for (i = 0; i < declares->children; ++i) { + zend_ast *declare_ast = declares->child[i]; + zend_ast *name_ast = declare_ast->child[0]; + zend_ast *value_ast = declare_ast->child[1]; + + zend_string *name = zend_ast_get_str(name_ast); + if (zend_str_equals_literal_ci(name, "ticks")) { + zval value_zv; + zend_const_expr_to_zval(&value_zv, value_ast TSRMLS_CC); + convert_to_long(&value_zv); + ZVAL_COPY_VALUE(&CG(declarables).ticks, &value_zv); zval_dtor(&value_zv); + } else if (zend_str_equals_literal_ci(name, "encoding")) { + /* Encoding declaration was already handled during parsing. Here we + * only check that it is the first statement in the file. */ + zend_uint num = CG(active_op_array)->last; + while (num > 0 && + (CG(active_op_array)->opcodes[num-1].opcode == ZEND_EXT_STMT || + CG(active_op_array)->opcodes[num-1].opcode == ZEND_TICKS)) { + --num; + } + + if (num > 0) { + zend_error_noreturn(E_COMPILE_ERROR, "Encoding declaration pragma must be " + "the very first statement in the script"); + } } else { zend_error(E_COMPILE_WARNING, "Unsupported declare '%s'", name->val); - zval_dtor(&value_zv); } } diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index 41761ab..cecba02 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -453,6 +453,7 @@ void zend_emit_final_return(zval *zv TSRMLS_DC); zend_ast *zend_ast_append_str(zend_ast *left, zend_ast *right); zend_uint zend_add_member_modifier(zend_uint flags, zend_uint new_flag); zend_ast_list *zend_ast_append_doc_comment(zend_ast_list *list TSRMLS_DC); +void zend_handle_encoding_declaration(zend_ast_list *declares TSRMLS_DC); /* parser-driven code generators */ void zend_do_free(znode *op1 TSRMLS_DC); diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y index a7e75fb..340371a 100644 --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@ -349,8 +349,10 @@ unticked_statement: foreach_statement { $$.ast = zend_ast_create(ZEND_AST_FOREACH, $3.ast, $7.ast, $5.ast, $9.ast); } - | T_DECLARE '(' const_list ')' declare_statement - { $$.ast = zend_ast_create(ZEND_AST_DECLARE, $3.ast, $5.ast); } + | T_DECLARE '(' const_list ')' + { zend_handle_encoding_declaration($3.list TSRMLS_CC); } + declare_statement + { $$.ast = zend_ast_create(ZEND_AST_DECLARE, $3.ast, $6.ast); } | ';' /* empty statement */ { $$.ast = NULL; } | T_TRY '{' inner_statement_list '}' catch_list finally_statement { $$.ast = zend_ast_create(ZEND_AST_TRY, $3.ast, $5.ast, $6.ast); }

« previous php.cvs (#80857) next »