Skip to content
Browse files

- require() of a dynamic expression now has the standard require() se…

…mantics

- Fixed a memory leak in require() of a dynamic expression
  • Loading branch information...
1 parent 63d0849 commit 67b4b3a63416efb21b1669b24e803d2df1039473 @zsuraski zsuraski committed
Showing with 43 additions and 7 deletions.
  1. +1 −1 Zend/zend-parser.y
  2. +20 −1 Zend/zend-scanner.l
  3. +16 −0 Zend/zend_compile.c
  4. +3 −1 Zend/zend_compile.h
  5. +3 −4 Zend/zend_execute.c
View
2 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); }
View
21 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);
}
View
16 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);
+ }
}
View
4 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)
View
7 Zend/zend_execute.c
@@ -1971,14 +1971,13 @@ binary_assign_op_addr: {
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;

0 comments on commit 67b4b3a

Please sign in to comment.
Something went wrong with that request. Please try again.