Permalink
Browse files

Fixed bug #40236 (php -a function allocation eats memory)

  • Loading branch information...
1 parent b997390 commit 0291ad5fa68a3c87faba5c181d36ec2d5f6c2345 Dmitry Stogov committed Feb 15, 2007
Showing with 45 additions and 7 deletions.
  1. +1 −0 NEWS
  2. +10 −0 Zend/tests/bug40236.inc
  3. +14 −0 Zend/tests/bug40236.phpt
  4. +5 −1 Zend/zend_compile.c
  5. +6 −3 Zend/zend_compile.h
  6. +1 −1 Zend/zend_execute_API.c
  7. +4 −0 Zend/zend_language_scanner.l
  8. +4 −2 Zend/zend_opcode.c
View
1 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)
View
@@ -0,0 +1,10 @@
+<?php
+function func1() { }
+function func2() { }
+function func3() { }
+function func4() { }
+function func5() { }
+function func6() { }
+function func7() { }
+print ("ok\n");
+?>
View
@@ -0,0 +1,14 @@
+--TEST--
+Bug #40236 (php -a function allocation eats memory)
+--SKIPIF--
+if (php_sapi_name() != "cli") die("skip CLI only");
+--FILE--
+<?php
+$php = getenv('TEST_PHP_EXECUTABLE');
+$cmd = "$php -d memory_limit=4M -a ".dirname(__FILE__)."/bug40236.inc";
+echo `$cmd`;
+?>
+--EXPECTF--
+Interactive %s
+
+ok
View
@@ -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;
View
@@ -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
View
@@ -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) {
@@ -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);
View
@@ -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;
}

0 comments on commit 0291ad5

Please sign in to comment.