From: Ilia Alshanetsky Date: Wed, 4 Apr 2007 00:42:42 +0000 (+0000) Subject: Addres limitation of __HALT_COMPILER() that allowed only one instance X-Git-Tag: php-5.2.2RC1~59 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=17c0c49a54db2a5dd6dc2205d0e02978b3070bae;p=php Addres limitation of __HALT_COMPILER() that allowed only one instance per request. # Patch by Greg Beaver --- diff --git a/Zend/tests/halt_compiler1.phpt b/Zend/tests/halt_compiler1.phpt new file mode 100644 index 0000000000..4987b29b2c --- /dev/null +++ b/Zend/tests/halt_compiler1.phpt @@ -0,0 +1,8 @@ +--TEST-- +__HALT_COMPILER(); +--FILE-- + +===DONE=== +--EXPECT-- +testint(73) \ No newline at end of file diff --git a/Zend/tests/halt_compiler2.phpt b/Zend/tests/halt_compiler2.phpt new file mode 100644 index 0000000000..0ced2142cd --- /dev/null +++ b/Zend/tests/halt_compiler2.phpt @@ -0,0 +1,23 @@ +--TEST-- +__HALT_COMPILER(); 2 files +--FILE-- + +hi there"; +file_put_contents(dirname(__FILE__) . '/test1.php', $text); +$text = " +hi there 2"; +file_put_contents(dirname(__FILE__) . '/test2.php', $text); +include dirname(__FILE__) . '/test1.php'; +include dirname(__FILE__) . '/test2.php'; +?> +==DONE== +--CLEAN-- + +--EXPECT-- +testint(73) +test2int(74) +==DONE== \ No newline at end of file diff --git a/Zend/tests/halt_compiler3.phpt b/Zend/tests/halt_compiler3.phpt new file mode 100644 index 0000000000..6ee16f79b9 --- /dev/null +++ b/Zend/tests/halt_compiler3.phpt @@ -0,0 +1,10 @@ +--TEST-- +__HALT_COMPILER(); bad define() of __COMPILER_HALT_OFFSET__ 1 +--FILE-- + +==DONE== +--EXPECTF-- +Notice: Constant __COMPILER_HALT_OFFSET__ already defined in %s on line %d +==DONE== \ No newline at end of file diff --git a/Zend/tests/halt_compiler4.phpt b/Zend/tests/halt_compiler4.phpt new file mode 100644 index 0000000000..43e532ce7d --- /dev/null +++ b/Zend/tests/halt_compiler4.phpt @@ -0,0 +1,10 @@ +--TEST-- +__HALT_COMPILER(); bad define() of __COMPILER_HALT_OFFSET__ 2 +--FILE-- + +==DONE== +--EXPECTF-- +Notice: Constant __COMPILER_HALT_OFFSET__ already defined in %s on line %d \ No newline at end of file diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index faf63e0ef3..dee710318f 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -3101,7 +3101,18 @@ void zend_do_fetch_property(znode *result, znode *object, znode *property TSRMLS zend_llist_add_element(fetch_list_ptr, &opline); } - +void zend_do_halt_compiler_register(TSRMLS_D) +{ + char *name, *cfilename; + char haltoff[] = "__COMPILER_HALT_OFFSET__"; + int len, clen; + cfilename = zend_get_compiled_filename(TSRMLS_C); + clen = strlen(cfilename); + zend_mangle_property_name(&name, &len, haltoff, + sizeof("__COMPILER_HALT_OFFSET__") - 1, cfilename, clen, 0); + zend_register_long_constant(name, len+1, zend_get_scanned_file_offset(TSRMLS_C), CONST_CS, 0 TSRMLS_CC); + pefree(name, 0); +} void zend_do_declare_implicit_property(TSRMLS_D) { diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index 9aeba56912..cd177bb0d5 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -450,6 +450,7 @@ void zend_do_declare_class_constant(znode *var_name, znode *value TSRMLS_DC); void zend_do_fetch_property(znode *result, znode *object, znode *property TSRMLS_DC); +void zend_do_halt_compiler_register(TSRMLS_D); void zend_do_push_object(znode *object TSRMLS_DC); void zend_do_pop_object(znode *object TSRMLS_DC); diff --git a/Zend/zend_constants.c b/Zend/zend_constants.c index 1574b8d1b5..9fe79d4d97 100644 --- a/Zend/zend_constants.c +++ b/Zend/zend_constants.c @@ -274,10 +274,10 @@ ZEND_API int zend_get_constant_ex(char *name, uint name_len, zval *result, zend_ *result = **ret_constant; zval_copy_ctor(result); } - + return retval; } - + if (zend_hash_find(EG(zend_constants), name, name_len+1, (void **) &c) == FAILURE) { lookup_name = estrndup(name, name_len); zend_str_tolower(lookup_name, name_len); @@ -287,7 +287,26 @@ ZEND_API int zend_get_constant_ex(char *name, uint name_len, zval *result, zend_ retval=0; } } else { - retval=0; + char haltoff[] = "__COMPILER_HALT_OFFSET__"; + if (!EG(in_execution)) { + retval = 0; + } else if (name_len == sizeof("__COMPILER_HALT_OFFSET__") - 1 && memcmp(haltoff, name, name_len) == 0) { + char *cfilename, *haltname; + int len, clen; + cfilename = zend_get_executed_filename(TSRMLS_C); + clen = strlen(cfilename); + /* check for __COMPILER_HALT_OFFSET__ */ + zend_mangle_property_name(&haltname, &len, haltoff, + sizeof("__COMPILER_HALT_OFFSET__") - 1, cfilename, clen, 0); + if (zend_hash_find(EG(zend_constants), haltname, len+1, (void **) &c) == SUCCESS) { + retval = 1; + } else { + retval=0; + } + pefree(haltname, 0); + } else { + retval = 0; + } } efree(lookup_name); } @@ -326,7 +345,8 @@ ZEND_API int zend_register_constant(zend_constant *c TSRMLS_DC) name = c->name; } - if (zend_hash_add(EG(zend_constants), name, c->name_len, (void *) c, sizeof(zend_constant), NULL)==FAILURE) { + if ((strncmp(name, "__COMPILER_HALT_OFFSET__", sizeof("__COMPILER_HALT_OFFSET__") - 1) == 0) || + zend_hash_add(EG(zend_constants), name, c->name_len, (void *) c, sizeof(zend_constant), NULL)==FAILURE) { zend_error(E_NOTICE,"Constant %s already defined", name); free(c->name); if (!(c->flags & CONST_PERSISTENT)) { diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y index 88b9a483fe..5d401e4c8e 100644 --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@ -162,7 +162,7 @@ top_statement: statement | function_declaration_statement { zend_do_early_binding(TSRMLS_C); } | class_declaration_statement { zend_do_early_binding(TSRMLS_C); } - | T_HALT_COMPILER '(' ')' ';' { zval c; if (zend_get_constant("__COMPILER_HALT_OFFSET__", sizeof("__COMPILER_HALT_OFFSET__") - 1, &c TSRMLS_CC)) { zval_dtor(&c); zend_error(E_COMPILE_ERROR, "__HALT_COMPILER() can only be used once per request"); } else { REGISTER_MAIN_LONG_CONSTANT("__COMPILER_HALT_OFFSET__", zend_get_scanned_file_offset(TSRMLS_C), CONST_CS); } YYACCEPT; } + | T_HALT_COMPILER '(' ')' ';' { zend_do_halt_compiler_register(TSRMLS_C); YYACCEPT; } ;