Browse Source

Addres limitation of __HALT_COMPILER() that allowed only one instance


			
			
				experimental/5.2-WITH_DRCP
			
			
		
Ilia Alshanetsky 20 years ago
parent
commit
17c0c49a54
  1. 8
      Zend/tests/halt_compiler1.phpt
  2. 23
      Zend/tests/halt_compiler2.phpt
  3. 10
      Zend/tests/halt_compiler3.phpt
  4. 10
      Zend/tests/halt_compiler4.phpt
  5. 13
      Zend/zend_compile.c
  6. 1
      Zend/zend_compile.h
  7. 28
      Zend/zend_constants.c
  8. 2
      Zend/zend_language_parser.y

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)

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==

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==

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

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)
{

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);

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)) {

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; }
;

Loading…
Cancel
Save