From: Dmitry Stogov Date: Thu, 15 Feb 2007 10:38:28 +0000 (+0000) Subject: Fixed bug #40236 (php -a function allocation eats memory) X-Git-Tag: php-5.2.2RC1~397 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=0291ad5fa68a3c87faba5c181d36ec2d5f6c2345;p=php Fixed bug #40236 (php -a function allocation eats memory) --- diff --git a/NEWS b/NEWS index 206ccd1119..b71ae88463 100644 --- a/NEWS +++ b/NEWS @@ -14,6 +14,7 @@ PHP NEWS node). (Tony) - Fixed bug #40428 (imagepstext() doesn't accept optional parameter). (Pierre) - Fixed bug #40410 (ext/posix does not compile on MacOS 10.3.9). (Tony) +- Fixed bug #40236 (php -a function allocation eats memory). (Dmitry) - Fixed bug #40109 (iptcembed fails on non-jfif jpegs). (Tony) - Fixed bug #39836 (SplObjectStorage empty after unserialize). (Marcus) - Fixed bug #39322 (proc_terminate() destroys process resource). (Nuno) diff --git a/Zend/tests/bug40236.inc b/Zend/tests/bug40236.inc new file mode 100755 index 0000000000..fc03349f7e --- /dev/null +++ b/Zend/tests/bug40236.inc @@ -0,0 +1,10 @@ + \ No newline at end of file diff --git a/Zend/tests/bug40236.phpt b/Zend/tests/bug40236.phpt new file mode 100755 index 0000000000..106784a70e --- /dev/null +++ b/Zend/tests/bug40236.phpt @@ -0,0 +1,14 @@ +--TEST-- +Bug #40236 (php -a function allocation eats memory) +--SKIPIF-- +if (php_sapi_name() != "cli") die("skip CLI only"); +--FILE-- + +--EXPECTF-- +Interactive %s + +ok diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 713c18305a..d0b0b70b67 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -1067,6 +1067,7 @@ void zend_do_begin_function_declaration(znode *function_token, znode *function_n int function_begin_line = function_token->u.opline_num; zend_uint fn_flags; char *lcname; + zend_bool orig_interactive; if (is_method) { if (CG(active_class_entry)->ce_flags & ZEND_ACC_INTERFACE) { @@ -1086,11 +1087,14 @@ void zend_do_begin_function_declaration(znode *function_token, znode *function_n function_token->u.op_array = CG(active_op_array); lcname = zend_str_tolower_dup(name, name_len); + orig_interactive = CG(interactive); + CG(interactive) = 0; init_op_array(&op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE TSRMLS_CC); + CG(interactive) = orig_interactive; op_array.function_name = name; op_array.return_reference = return_reference; - op_array.fn_flags = fn_flags; + op_array.fn_flags |= fn_flags; op_array.pass_rest_by_reference = 0; op_array.scope = is_method?CG(active_class_entry):NULL; diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index f471694611..9aeba56912 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -36,9 +36,9 @@ #define SET_UNUSED(op) (op).op_type = IS_UNUSED -#define INC_BPC(op_array) if (CG(interactive)) { ((op_array)->backpatch_count++); } -#define DEC_BPC(op_array) if (CG(interactive)) { ((op_array)->backpatch_count--); } -#define HANDLE_INTERACTIVE() if (CG(interactive)) { execute_new_code(TSRMLS_C); } +#define INC_BPC(op_array) if (op_array->fn_flags & ZEND_ACC_INTERACTIVE) { ((op_array)->backpatch_count++); } +#define DEC_BPC(op_array) if (op_array->fn_flags & ZEND_ACC_INTERACTIVE) { ((op_array)->backpatch_count--); } +#define HANDLE_INTERACTIVE() if (CG(active_op_array)->fn_flags & ZEND_ACC_INTERACTIVE) { execute_new_code(TSRMLS_C); } #define RESET_DOC_COMMENT() \ { \ @@ -116,6 +116,9 @@ typedef struct _zend_try_catch_element { #define ZEND_ACC_FINAL_CLASS 0x40 #define ZEND_ACC_INTERFACE 0x80 +/* op_array flags */ +#define ZEND_ACC_INTERACTIVE 0x10 + /* method flags (visibility) */ /* The order of those must be kept - public < protected < private */ #define ZEND_ACC_PUBLIC 0x100 diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index acc1349974..1ba358bc92 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -1197,7 +1197,7 @@ void execute_new_code(TSRMLS_D) zend_op *ret_opline; zval *local_retval=NULL; - if (!CG(interactive) + if (!(CG(active_op_array)->fn_flags & ZEND_ACC_INTERACTIVE) || CG(active_op_array)->backpatch_count>0 || CG(active_op_array)->function_name || CG(active_op_array)->type!=ZEND_USER_FUNCTION) { diff --git a/Zend/zend_language_scanner.l b/Zend/zend_language_scanner.l index f0524de50d..c981aa8642 100644 --- a/Zend/zend_language_scanner.l +++ b/Zend/zend_language_scanner.l @@ -545,7 +545,11 @@ zend_op_array *compile_string(zval *source_string, char *filename TSRMLS_DC) efree(op_array); retval = NULL; } else { + zend_bool orig_interactive = CG(interactive); + + CG(interactive) = 0; init_op_array(op_array, ZEND_EVAL_CODE, INITIAL_OP_ARRAY_SIZE TSRMLS_CC); + CG(interactive) = orig_interactive; CG(active_op_array) = op_array; BEGIN(ST_IN_SCRIPTING); compiler_result = zendparse(TSRMLS_C); diff --git a/Zend/zend_opcode.c b/Zend/zend_opcode.c index 8b9e1f4c42..e352deccdd 100644 --- a/Zend/zend_opcode.c +++ b/Zend/zend_opcode.c @@ -99,6 +99,8 @@ void init_op_array(zend_op_array *op_array, zend_uchar type, int initial_ops_siz op_array->start_op = NULL; + op_array->fn_flags = CG(interactive)?ZEND_ACC_INTERACTIVE:0; + zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_op_array_ctor_handler, op_array TSRMLS_CC); } @@ -294,7 +296,7 @@ zend_op *get_next_op(zend_op_array *op_array TSRMLS_DC) zend_op *next_op; if (next_op_num >= op_array->size) { - if (CG(interactive)) { + if (op_array->fn_flags & ZEND_ACC_INTERACTIVE) { /* we messed up */ zend_printf("Ran out of opcode space!\n" "You should probably consider writing this huge script into a file!\n"); @@ -367,7 +369,7 @@ int pass_two(zend_op_array *op_array TSRMLS_DC) zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_op_array_handler, op_array TSRMLS_CC); } - if (!CG(interactive) && op_array->size != op_array->last) { + if (!(op_array->fn_flags & ZEND_ACC_INTERACTIVE) && op_array->size != op_array->last) { op_array->opcodes = (zend_op *) erealloc(op_array->opcodes, sizeof(zend_op)*op_array->last); op_array->size = op_array->last; }