summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIlia Alshanetsky <iliaa@php.net>2007-04-04 00:42:42 +0000
committerIlia Alshanetsky <iliaa@php.net>2007-04-04 00:42:42 +0000
commit17c0c49a54db2a5dd6dc2205d0e02978b3070bae (patch)
treee1bd13682153b272b30d64af86acfe605d34af97
parenta9ca51ff1aa4b444d842d5ad771bd6f0a65e5c5c (diff)
downloadphp-git-17c0c49a54db2a5dd6dc2205d0e02978b3070bae.tar.gz
Addres limitation of __HALT_COMPILER() that allowed only one instance
per request. # Patch by Greg Beaver
-rw-r--r--Zend/tests/halt_compiler1.phpt8
-rw-r--r--Zend/tests/halt_compiler2.phpt23
-rw-r--r--Zend/tests/halt_compiler3.phpt10
-rw-r--r--Zend/tests/halt_compiler4.phpt10
-rw-r--r--Zend/zend_compile.c13
-rw-r--r--Zend/zend_compile.h1
-rw-r--r--Zend/zend_constants.c28
-rw-r--r--Zend/zend_language_parser.y2
8 files changed, 89 insertions, 6 deletions
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--
+<?php echo 'test'; var_dump(__COMPILER_HALT_OFFSET__); __HALT_COMPILER();
+?>
+===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--
+<?php
+$text = "<?php echo 'test'; var_dump(__COMPILER_HALT_OFFSET__); __HALT_COMPILER(); ?>
+hi there";
+file_put_contents(dirname(__FILE__) . '/test1.php', $text);
+$text = "<?php echo 'test2'; var_dump(__COMPILER_HALT_OFFSET__); __HALT_COMPILER(); ?>
+hi there 2";
+file_put_contents(dirname(__FILE__) . '/test2.php', $text);
+include dirname(__FILE__) . '/test1.php';
+include dirname(__FILE__) . '/test2.php';
+?>
+==DONE==
+--CLEAN--
+<?php
+unlink(dirname(__FILE__) . '/test1.php');
+unlink(dirname(__FILE__) . '/test2.php');
+?>
+--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--
+<?php
+define ('__COMPILER_HALT_OFFSET__', 1);
+?>
+==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--
+<?php
+define ('__COMPILER_HALT_OFFSET__', 1);
+__HALT_COMPILER();
+?>
+==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; }
;