Permalink
Browse files

Addres limitation of __HALT_COMPILER() that allowed only one instance

per request.

# Patch by Greg Beaver
  • Loading branch information...
1 parent a9ca51f commit 17c0c49a54db2a5dd6dc2205d0e02978b3070bae Ilia Alshanetsky committed Apr 4, 2007
View
8 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)
View
23 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==
View
10 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==
View
10 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
View
13 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)
{
View
1 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);
View
28 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)) {
View
2 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; }
;

0 comments on commit 17c0c49

Please sign in to comment.