]> granicus.if.org Git - php/commitdiff
Fixed bug #40236 (php -a function allocation eats memory)
authorDmitry Stogov <dmitry@php.net>
Thu, 15 Feb 2007 10:38:28 +0000 (10:38 +0000)
committerDmitry Stogov <dmitry@php.net>
Thu, 15 Feb 2007 10:38:28 +0000 (10:38 +0000)
NEWS
Zend/tests/bug40236.inc [new file with mode: 0755]
Zend/tests/bug40236.phpt [new file with mode: 0755]
Zend/zend_compile.c
Zend/zend_compile.h
Zend/zend_execute_API.c
Zend/zend_language_scanner.l
Zend/zend_opcode.c

diff --git a/NEWS b/NEWS
index 206ccd1119ddd7bb9d46ecc559e8a77f84904dd9..b71ae88463b3b4aa0500e917991be4df943ed31c 100644 (file)
--- 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 (executable)
index 0000000..fc03349
--- /dev/null
@@ -0,0 +1,10 @@
+<?php
+function func1() { }
+function func2() { }
+function func3() { }
+function func4() { }
+function func5() { }
+function func6() { }
+function func7() { }
+print ("ok\n");
+?>
\ No newline at end of file
diff --git a/Zend/tests/bug40236.phpt b/Zend/tests/bug40236.phpt
new file mode 100755 (executable)
index 0000000..106784a
--- /dev/null
@@ -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
index 713c18305ad2d3fd4c6654b3ea4c4501ae53ec8b..d0b0b70b6731bcb227e71ea10c83d15f1e58e1b6 100644 (file)
@@ -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;
index f47169461128530f34113a444d15422c74eef9cc..9aeba56912ee79600eec9205fb82020cfa012079 100644 (file)
@@ -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
index acc1349974a54a927d97c746c604a6ac7a23791a..1ba358bc92e176151b47cd9d832b6bfc13dd057a 100644 (file)
@@ -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) {
index f0524de50d0feb1175b7dbe0f42b7193708d9046..c981aa86428e131a5138f6942a51f8ebd66be641 100644 (file)
@@ -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);
index 8b9e1f4c42dc031033217afd974d91298c6e5c3a..e352deccdd66ce05003f772d809a4c4584cad6b2 100644 (file)
@@ -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;
        }