per request.
# Patch by Greg Beaver
--- /dev/null
+--TEST--
+__HALT_COMPILER();
+--FILE--
+<?php echo 'test'; var_dump(__COMPILER_HALT_OFFSET__); __HALT_COMPILER();
+?>
+===DONE===
+--EXPECT--
+testint(73)
\ No newline at end of file
--- /dev/null
+--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
--- /dev/null
+--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
--- /dev/null
+--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
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)
{
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);
*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);
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);
}
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)) {
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; }
;