From: Zeev Suraski Date: Thu, 23 Dec 1999 15:03:25 +0000 (+0000) Subject: - require() of a dynamic expression now has the standard require() semantics X-Git-Tag: PRE_ISSET_TYPE~84 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=67b4b3a63416efb21b1669b24e803d2df1039473;p=php - require() of a dynamic expression now has the standard require() semantics - Fixed a memory leak in require() of a dynamic expression --- diff --git a/Zend/zend-parser.y b/Zend/zend-parser.y index 78c743947e..d286245f17 100644 --- a/Zend/zend-parser.y +++ b/Zend/zend-parser.y @@ -187,7 +187,7 @@ statement: | T_ECHO echo_expr_list ';' | T_INLINE_HTML { do_echo(&$1 CLS_CC); } | expr ';' { do_free(&$1 CLS_CC); } - | T_REQUIRE expr ';' { if ($2.op_type==IS_CONST && $2.u.constant.type==IS_STRING) { require_filename($2.u.constant.value.str.val CLS_CC); zval_dtor(&$2.u.constant); } else { do_include_or_eval(ZEND_INCLUDE, &$$, &$2 CLS_CC); } } + | T_REQUIRE expr ';' { do_require(&$2 CLS_CC); } | T_USE use_filename ';' { use_filename($2.u.constant.value.str.val, $2.u.constant.value.str.len CLS_CC); zval_dtor(&$2.u.constant); } | T_UNSET '(' r_cvar ')' ';' { do_unset(&$3 CLS_CC); } | T_FOREACH '(' expr T_AS { do_foreach_begin(&$1, &$3, &$2, &$4 CLS_CC); } w_cvar foreach_optional_arg ')' { do_foreach_cont(&$6, &$7, &$4 CLS_CC); } foreach_statement { do_foreach_end(&$1, &$2 CLS_CC); } diff --git a/Zend/zend-scanner.l b/Zend/zend-scanner.l index 238a6544b2..64e059a15a 100644 --- a/Zend/zend-scanner.l +++ b/Zend/zend-scanner.l @@ -381,11 +381,12 @@ ZEND_API zend_op_array *v_compile_files(int mark_as_ref CLS_DC, int file_count, } -zend_op_array *compile_filename(zval *filename, zend_bool unique CLS_DC) +zend_op_array *compile_filename(int mode, zval *filename CLS_DC ELS_DC) { zend_file_handle file_handle; zval tmp; zend_op_array *retval; + int error_reporting; if (filename->type != IS_STRING) { tmp = *filename; @@ -397,7 +398,25 @@ zend_op_array *compile_filename(zval *filename, zend_bool unique CLS_DC) file_handle.free_filename = 0; file_handle.type = ZEND_HANDLE_FILENAME; file_handle.opened_path = NULL; + + + if (mode==ZEND_REQUIRE) { + /* We don't want to hear about inclusion failures; If we fail, + * we'll generate a require failure + */ + error_reporting = EG(error_reporting); + EG(error_reporting) = 0; + } retval = zend_compile_files(1 CLS_CC, 1, &file_handle); + + if (mode==ZEND_REQUIRE) { + EG(error_reporting) = error_reporting; + if (!retval) { + zend_message_dispatcher(ZMSG_FAILED_REQUIRE_FOPEN, filename->value.str.val); + zend_bailout(); + } + } + if (filename==&tmp) { zval_dtor(&tmp); } diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 802cd7e0c7..0b8ad01a22 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -1852,6 +1852,22 @@ void do_include_or_eval(int type, znode *result, znode *op1 CLS_DC) SET_UNUSED(opline->op2); opline->op2.u.constant.value.lval = type; *result = opline->result; + if (type==ZEND_REQUIRE) { + opline->result.u.EA.type |= EXT_TYPE_UNUSED; + } +} + + +void do_require(znode *filename CLS_DC) +{ + if (filename->op_type==IS_CONST + && filename->u.constant.type==IS_STRING) { + require_filename(filename->u.constant.value.str.val CLS_CC); + } else { + znode result; + + do_include_or_eval(ZEND_REQUIRE, &result, filename CLS_CC); + } } diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index ecc2b02a8d..b7d100ec91 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -317,6 +317,7 @@ void do_new_list_end(CLS_D); void do_cast(znode *result, znode *expr, int type CLS_DC); void do_include_or_eval(int type, znode *result, znode *op1 CLS_DC); +void do_require(znode *filename CLS_DC); void do_unset(znode *variable CLS_DC); void do_isset_or_isempty(int type, znode *result, znode *variable CLS_DC); @@ -351,7 +352,7 @@ ZEND_API int use_filename(char *filename, uint filename_length CLS_DC); ZEND_API zend_op_array *compile_files(int mark_as_ref CLS_DC, int file_count, ...); ZEND_API zend_op_array *v_compile_files(int mark_as_ref CLS_DC, int file_count, va_list files); ZEND_API zend_op_array *compile_string(zval *source_string CLS_DC); -ZEND_API zend_op_array *compile_filename(zval *filename, zend_bool unique CLS_DC); +ZEND_API zend_op_array *compile_filename(int mode, zval *filename CLS_DC ELS_DC); ZEND_API int open_file_for_scanning(zend_file_handle *file_handle CLS_DC); ZEND_API void init_op_array(zend_op_array *op_array, int initial_ops_size); ZEND_API void destroy_op_array(zend_op_array *op_array); @@ -538,6 +539,7 @@ int zendlex(znode *zendlval CLS_DC); #define ZEND_EVAL (1<<0) #define ZEND_INCLUDE (1<<1) #define ZEND_IMPORT (1<<2) +#define ZEND_REQUIRE (1<<3) #define ZEND_ISSET (1<<0) #define ZEND_ISEMPTY (1<<1) diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 31b30e5ce6..dabb0a5633 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -1971,14 +1971,13 @@ send_by_ref: switch (opline->op2.u.constant.value.lval) { case ZEND_INCLUDE: - new_op_array = compile_filename(get_zval_ptr(&opline->op1, Ts, &EG(free_op1), BP_VAR_R), 0 CLS_CC); + case ZEND_IMPORT: + case ZEND_REQUIRE: + new_op_array = compile_filename(opline->op2.u.constant.value.lval, get_zval_ptr(&opline->op1, Ts, &EG(free_op1), BP_VAR_R) CLS_CC ELS_CC); break; case ZEND_EVAL: new_op_array = compile_string(get_zval_ptr(&opline->op1, Ts, &EG(free_op1), BP_VAR_R) CLS_CC); break; - case ZEND_IMPORT: - new_op_array = compile_filename(get_zval_ptr(&opline->op1, Ts, &EG(free_op1), BP_VAR_R), 1 CLS_CC); - break; } FREE_OP(&opline->op1, EG(free_op1)); Ts[opline->result.u.var].var.ptr = NULL;