diff options
-rw-r--r-- | NEWS | 3 | ||||
-rw-r--r-- | Zend/zend_alloc.c | 13 | ||||
-rw-r--r-- | Zend/zend_compile.c | 54 | ||||
-rw-r--r-- | Zend/zend_compile.h | 5 | ||||
-rw-r--r-- | Zend/zend_execute.c | 30 | ||||
-rw-r--r-- | Zend/zend_gc.c | 2 | ||||
-rw-r--r-- | Zend/zend_generators.c | 8 | ||||
-rw-r--r-- | Zend/zend_indent.c | 2 | ||||
-rw-r--r-- | Zend/zend_opcode.c | 11 | ||||
-rw-r--r-- | Zend/zend_vm_def.h | 80 | ||||
-rw-r--r-- | Zend/zend_vm_execute.h | 80 | ||||
-rw-r--r-- | ext/filter/filter.c | 4 | ||||
-rw-r--r-- | ext/filter/filter_private.h | 5 | ||||
-rw-r--r-- | ext/filter/logical_filters.c | 87 | ||||
-rw-r--r-- | ext/filter/php_filter.h | 1 | ||||
-rw-r--r-- | ext/filter/tests/008.phpt | 34 | ||||
-rw-r--r-- | ext/filter/tests/015.phpt | 32 | ||||
-rw-r--r-- | ext/filter/tests/033.phpt | 3 | ||||
-rw-r--r-- | ext/filter/tests/056.phpt | 68 | ||||
-rw-r--r-- | ext/mbstring/config.w32 | 99 | ||||
-rw-r--r-- | ext/opcache/Optimizer/block_pass.c | 6 | ||||
-rw-r--r-- | ext/zlib/tests/bug_52944-darwin.phpt | 24 | ||||
-rw-r--r-- | ext/zlib/tests/bug_52944.phpt | 4 |
23 files changed, 445 insertions, 210 deletions
@@ -34,6 +34,9 @@ PHP NEWS - Fileinfo: . Fixed bug #66242 (libmagic: don't assume char is signed). (ArdB) +- Filter: + . New FILTER_VALIDATE_DOMAIN and better RFC conformance for FILTER_VALIDATE_URL. (Kevin Dunglas) + - FPM: . Fixed bug #65933 (Cannot specify config lines longer than 1024 bytes). (Chris Wright) diff --git a/Zend/zend_alloc.c b/Zend/zend_alloc.c index 3041857dc6..1614690414 100644 --- a/Zend/zend_alloc.c +++ b/Zend/zend_alloc.c @@ -2130,6 +2130,7 @@ ZEND_API void* ZEND_FASTCALL _emalloc_huge(size_t size) return zend_mm_alloc_huge(AG(mm_heap), size); } +#if ZEND_DEBUG # define _ZEND_BIN_FREE(_num, _size, _elements, _pages, x, y) \ ZEND_API void ZEND_FASTCALL _efree_ ## _size(void *ptr) { \ TSRMLS_FETCH(); \ @@ -2144,6 +2145,18 @@ ZEND_API void* ZEND_FASTCALL _emalloc_huge(size_t size) zend_mm_free_small(AG(mm_heap), ptr, _num); \ } \ } +#else +# define _ZEND_BIN_FREE(_num, _size, _elements, _pages, x, y) \ + ZEND_API void ZEND_FASTCALL _efree_ ## _size(void *ptr) { \ + TSRMLS_FETCH(); \ + ZEND_MM_CUSTOM_DEALLOCATOR(ptr); \ + { \ + zend_mm_chunk *chunk = (zend_mm_chunk*)ZEND_MM_ALIGNED_BASE(ptr, ZEND_MM_CHUNK_SIZE); \ + ZEND_MM_CHECK(chunk->heap == AG(mm_heap), "zend_mm_heap corrupted"); \ + zend_mm_free_small(AG(mm_heap), ptr, _num); \ + } \ + } +#endif ZEND_MM_BINS_INFO(_ZEND_BIN_FREE, x, y) diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 55be6176bf..5d409c7518 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -159,6 +159,7 @@ void zend_init_compiler_context(TSRMLS_D) /* {{{ */ CG(context).current_brk_cont = -1; CG(context).backpatch_count = 0; CG(context).in_finally = 0; + CG(context).fast_call_var = -1; CG(context).labels = NULL; } /* }}} */ @@ -1810,7 +1811,7 @@ static inline uint32_t zend_delayed_compile_begin(TSRMLS_D) /* {{{ */ static zend_op *zend_delayed_compile_end(uint32_t offset TSRMLS_DC) /* {{{ */ { - zend_op *opline, *oplines = zend_stack_base(&CG(delayed_oplines_stack)); + zend_op *opline = NULL, *oplines = zend_stack_base(&CG(delayed_oplines_stack)); uint32_t i, count = zend_stack_count(&CG(delayed_oplines_stack)); ZEND_ASSERT(count > offset); @@ -3126,7 +3127,9 @@ void zend_compile_return(zend_ast *ast TSRMLS_DC) /* {{{ */ zend_free_foreach_and_switch_variables(TSRMLS_C); if (CG(context).in_finally) { - zend_emit_op(NULL, ZEND_DISCARD_EXCEPTION, NULL, NULL TSRMLS_CC); + opline = zend_emit_op(NULL, ZEND_DISCARD_EXCEPTION, NULL, NULL TSRMLS_CC); + opline->op1_type = IS_TMP_VAR; + opline->op1.var = CG(context).fast_call_var; } opline = zend_emit_op(NULL, by_ref ? ZEND_RETURN_BY_REF : ZEND_RETURN, @@ -3431,7 +3434,7 @@ void zend_compile_if(zend_ast *ast TSRMLS_DC) /* {{{ */ { zend_ast_list *list = zend_ast_get_list(ast); uint32_t i; - uint32_t *jmp_opnums; + uint32_t *jmp_opnums = NULL; if (list->children > 1) { jmp_opnums = safe_emalloc(sizeof(uint32_t), list->children - 1, 0); @@ -3621,8 +3624,15 @@ void zend_compile_try(zend_ast *ast TSRMLS_DC) /* {{{ */ if (finally_ast) { uint32_t opnum_jmp = get_next_op_number(CG(active_op_array)) + 1; + if (!(CG(active_op_array)->fn_flags & ZEND_ACC_HAS_FINALLY_BLOCK)) { + CG(active_op_array)->fn_flags |= ZEND_ACC_HAS_FINALLY_BLOCK; + CG(context).fast_call_var = get_temporary_variable(CG(active_op_array)); + } + opline = zend_emit_op(NULL, ZEND_FAST_CALL, NULL, NULL TSRMLS_CC); opline->op1.opline_num = opnum_jmp + 1; + opline->result_type = IS_TMP_VAR; + opline->result.var = CG(context).fast_call_var; zend_emit_op(NULL, ZEND_JMP, NULL, NULL TSRMLS_CC); @@ -3633,9 +3643,10 @@ void zend_compile_try(zend_ast *ast TSRMLS_DC) /* {{{ */ CG(active_op_array)->try_catch_array[try_catch_offset].finally_op = opnum_jmp + 1; CG(active_op_array)->try_catch_array[try_catch_offset].finally_end = get_next_op_number(CG(active_op_array)); - CG(active_op_array)->fn_flags |= ZEND_ACC_HAS_FINALLY_BLOCK; - zend_emit_op(NULL, ZEND_FAST_RET, NULL, NULL TSRMLS_CC); + opline = zend_emit_op(NULL, ZEND_FAST_RET, NULL, NULL TSRMLS_CC); + opline->op1_type = IS_TMP_VAR; + opline->op1.var = CG(context).fast_call_var; zend_update_jump_target_to_next(opnum_jmp TSRMLS_CC); } @@ -5524,13 +5535,11 @@ void zend_compile_silence(znode *result, zend_ast *ast TSRMLS_DC) /* {{{ */ { zend_ast *expr_ast = ast->child[0]; znode silence_node; - uint32_t opline_num; - zend_op *begin_silence, *end_silence; + uint32_t begin_opline_num, end_opline_num; + zend_brk_cont_element *brk_cont_element; - opline_num = get_next_op_number(CG(active_op_array)); - begin_silence = zend_emit_op_tmp(&silence_node, ZEND_BEGIN_SILENCE, NULL, NULL TSRMLS_CC); - /* pair BEGIN_SILENCE and END_SILENCE opcodes */ - begin_silence->op2.num = opline_num; + begin_opline_num = get_next_op_number(CG(active_op_array)); + zend_emit_op_tmp(&silence_node, ZEND_BEGIN_SILENCE, NULL, NULL TSRMLS_CC); if (expr_ast->kind == ZEND_AST_VAR) { /* For @$var we need to force a FETCH instruction, otherwise the CV access will @@ -5540,9 +5549,15 @@ void zend_compile_silence(znode *result, zend_ast *ast TSRMLS_DC) /* {{{ */ zend_compile_expr(result, expr_ast TSRMLS_CC); } - end_silence = zend_emit_op(NULL, ZEND_END_SILENCE, &silence_node, NULL TSRMLS_CC); - /* pair BEGIN_SILENCE and END_SILENCE opcodes */ - end_silence->op2.num = opline_num; + end_opline_num = get_next_op_number(CG(active_op_array)); + zend_emit_op(NULL, ZEND_END_SILENCE, &silence_node, NULL TSRMLS_CC); + + /* Store BEGIN_SILENCE/END_SILENCE pair to restore previous + * EG(error_reporting) value on exception */ + brk_cont_element = get_next_brk_cont_element(CG(active_op_array)); + brk_cont_element->start = begin_opline_num; + brk_cont_element->cont = brk_cont_element->brk = end_opline_num; + brk_cont_element->parent = -1; } /* }}} */ @@ -5792,14 +5807,14 @@ void zend_compile_encaps_list(znode *result, zend_ast *ast TSRMLS_DC) /* {{{ */ void zend_compile_magic_const(znode *result, zend_ast *ast TSRMLS_DC) /* {{{ */ { - zend_class_entry *ce = CG(active_class_entry); - if (zend_try_ct_eval_magic_const(&result->u.constant, ast TSRMLS_CC)) { result->op_type = IS_CONST; return; } - ZEND_ASSERT(ast->attr == T_CLASS_C && ce && ZEND_CE_IS_TRAIT(ce)); + ZEND_ASSERT(ast->attr == T_CLASS_C && + CG(active_class_entry) && + ZEND_CE_IS_TRAIT(CG(active_class_entry))); { zend_ast *const_ast = zend_ast_create(ZEND_AST_CONST, @@ -5930,10 +5945,11 @@ void zend_compile_const_expr_resolve_class_name(zend_ast **ast_ptr TSRMLS_DC) /* void zend_compile_const_expr_magic_const(zend_ast **ast_ptr TSRMLS_DC) /* {{{ */ { zend_ast *ast = *ast_ptr; - zend_class_entry *ce = CG(active_class_entry); /* Other cases already resolved by constant folding */ - ZEND_ASSERT(ast->attr == T_CLASS_C && ce && ZEND_CE_IS_TRAIT(ce)); + ZEND_ASSERT(ast->attr == T_CLASS_C && + CG(active_class_entry) && + ZEND_CE_IS_TRAIT(CG(active_class_entry))); { zval const_zv; diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index f9a66a37d8..4cf60c6181 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -52,6 +52,7 @@ typedef struct _zend_compiler_context { int current_brk_cont; int backpatch_count; int in_finally; + uint32_t fast_call_var; HashTable *labels; } zend_compiler_context; @@ -376,10 +377,6 @@ struct _zend_execute_data { zval *return_value; zend_class_entry *scope; /* function scope (self) */ zend_array *symbol_table; - const zend_op *fast_ret; /* used by FAST_CALL/FAST_RET (finally keyword) */ - zend_object *delayed_exception; - uint32_t silence_op_num; - uint32_t old_error_reporting; }; #define VM_FRAME_KIND_MASK 0x000000ff diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 6c8ebca707..2fbd1d5011 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -558,20 +558,24 @@ ZEND_API void zend_verify_arg_error(int error_type, const zend_function *zf, uin fclass = ""; } - if (arg && zf->common.type == ZEND_USER_FUNCTION) { - ZVAL_COPY_VALUE(&old_arg, arg); - ZVAL_UNDEF(arg); - } + if (zf->common.type == ZEND_USER_FUNCTION) { + if (arg) { + ZVAL_COPY_VALUE(&old_arg, arg); + ZVAL_UNDEF(arg); + } - if (zf->common.type == ZEND_USER_FUNCTION && ptr && ptr->func && ZEND_USER_CODE(ptr->func->common.type)) { - zend_error(error_type, "Argument %d passed to %s%s%s() must %s%s, %s%s given, called in %s on line %d and defined", arg_num, fclass, fsep, fname, need_msg, need_kind, given_msg, given_kind, ptr->func->op_array.filename->val, ptr->opline->lineno); + if (ptr && ptr->func && ZEND_USER_CODE(ptr->func->common.type)) { + zend_error(error_type, "Argument %d passed to %s%s%s() must %s%s, %s%s given, called in %s on line %d and defined", arg_num, fclass, fsep, fname, need_msg, need_kind, given_msg, given_kind, ptr->func->op_array.filename->val, ptr->opline->lineno); + } else { + zend_error(error_type, "Argument %d passed to %s%s%s() must %s%s, %s%s given", arg_num, fclass, fsep, fname, need_msg, need_kind, given_msg, given_kind); + } + + if (arg) { + ZVAL_COPY_VALUE(arg, &old_arg); + } } else { zend_error(error_type, "Argument %d passed to %s%s%s() must %s%s, %s%s given", arg_num, fclass, fsep, fname, need_msg, need_kind, given_msg, given_kind); } - - if (arg && zf->common.type == ZEND_USER_FUNCTION) { - ZVAL_COPY_VALUE(arg, &old_arg); - } } static int is_null_constant(zval *default_value TSRMLS_DC) @@ -1485,8 +1489,6 @@ static zend_always_inline void i_init_func_execute_data(zend_execute_data *execu EX(opline) = op_array->opcodes; EX(call) = NULL; EX(return_value) = return_value; - EX(delayed_exception) = NULL; - EX(silence_op_num) = -1; /* Handle arguments */ first_extra_arg = op_array->num_args; @@ -1552,8 +1554,6 @@ static zend_always_inline void i_init_code_execute_data(zend_execute_data *execu EX(call) = NULL; EX(return_value) = return_value; EX(scope) = EG(scope); - EX(delayed_exception) = NULL; - EX(silence_op_num) = -1; zend_attach_symbol_table(execute_data); @@ -1579,8 +1579,6 @@ static zend_always_inline void i_init_execute_data(zend_execute_data *execute_da EX(call) = NULL; EX(return_value) = return_value; EX(scope) = EG(scope); - EX(delayed_exception) = NULL; - EX(silence_op_num) = -1; if (UNEXPECTED(EX(symbol_table) != NULL)) { zend_attach_symbol_table(execute_data); diff --git a/Zend/zend_gc.c b/Zend/zend_gc.c index e47b5350d4..f6aad866a7 100644 --- a/Zend/zend_gc.c +++ b/Zend/zend_gc.c @@ -641,7 +641,7 @@ static int gc_collect_roots(TSRMLS_D) static void gc_remove_nested_data_from_buffer(zend_refcounted *ref TSRMLS_DC) { - HashTable *ht; + HashTable *ht = NULL; uint idx; Bucket *p; diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c index b38657f7b7..ef0b520eb0 100644 --- a/Zend/zend_generators.c +++ b/Zend/zend_generators.c @@ -133,7 +133,7 @@ static void zend_generator_dtor_storage(zend_object *object TSRMLS_DC) /* {{{ */ { zend_generator *generator = (zend_generator*) object; zend_execute_data *ex = generator->execute_data; - uint32_t op_num, finally_op_num; + uint32_t op_num, finally_op_num, finally_op_end; int i; if (!ex || !(ex->func->op_array.fn_flags & ZEND_ACC_HAS_FINALLY_BLOCK)) { @@ -146,6 +146,7 @@ static void zend_generator_dtor_storage(zend_object *object TSRMLS_DC) /* {{{ */ /* Find next finally block */ finally_op_num = 0; + finally_op_end = 0; for (i = 0; i < ex->func->op_array.last_try_catch; i++) { zend_try_catch_element *try_catch = &ex->func->op_array.try_catch_array[i]; @@ -155,14 +156,17 @@ static void zend_generator_dtor_storage(zend_object *object TSRMLS_DC) /* {{{ */ if (op_num < try_catch->finally_op) { finally_op_num = try_catch->finally_op; + finally_op_end = try_catch->finally_end; } } /* If a finally block was found we jump directly to it and * resume the generator. */ if (finally_op_num) { + zval *fast_call = EX_VAR_2(ex, ex->func->op_array.opcodes[finally_op_end].op1.var); + + fast_call->u2.lineno = (uint32_t)-1; ex->opline = &ex->func->op_array.opcodes[finally_op_num]; - ex->fast_ret = NULL; generator->flags |= ZEND_GENERATOR_FORCED_CLOSE; zend_generator_resume(generator TSRMLS_CC); } diff --git a/Zend/zend_indent.c b/Zend/zend_indent.c index 93c10108f8..b5884c72c0 100644 --- a/Zend/zend_indent.c +++ b/Zend/zend_indent.c @@ -31,7 +31,7 @@ #define zendleng LANG_SCNG(yy_leng) -static void handle_whitespace(int *emit_whitespace) +static void handle_whitespace(unsigned int *emit_whitespace) { unsigned char c; int i; diff --git a/Zend/zend_opcode.c b/Zend/zend_opcode.c index 5902abd4c5..1bbd35f40f 100644 --- a/Zend/zend_opcode.c +++ b/Zend/zend_opcode.c @@ -532,12 +532,19 @@ static void zend_resolve_finally_call(zend_op_array *op_array, uint32_t op_num, (dst_num < op_array->try_catch_array[i].try_op || dst_num > op_array->try_catch_array[i].finally_end)) { /* we have a jump out of try block that needs executing finally */ + uint32_t fast_call_var; + + /* Must be ZEND_FAST_RET */ + ZEND_ASSERT(op_array->opcodes[op_array->try_catch_array[i].finally_end].opcode == ZEND_FAST_RET); + fast_call_var = op_array->opcodes[op_array->try_catch_array[i].finally_end].op1.var; /* generate a FAST_CALL to finally block */ start_op = get_next_op_number(op_array); opline = get_next_op(op_array TSRMLS_CC); opline->opcode = ZEND_FAST_CALL; + opline->result_type = IS_TMP_VAR; + opline->result.var = fast_call_var; SET_UNUSED(opline->op1); SET_UNUSED(opline->op2); zend_adjust_fast_call(op_array, start_op, @@ -550,6 +557,8 @@ static void zend_resolve_finally_call(zend_op_array *op_array, uint32_t op_num, /* generate a FAST_CALL to hole CALL_FROM_FINALLY */ opline = get_next_op(op_array TSRMLS_CC); opline->opcode = ZEND_FAST_CALL; + opline->result_type = IS_TMP_VAR; + opline->result.var = fast_call_var; SET_UNUSED(opline->op1); SET_UNUSED(opline->op2); zend_resolve_fast_call(op_array, start_op + 1, op_array->try_catch_array[i].finally_op - 2 TSRMLS_CC); @@ -569,6 +578,8 @@ static void zend_resolve_finally_call(zend_op_array *op_array, uint32_t op_num, opline = get_next_op(op_array TSRMLS_CC); opline->opcode = ZEND_FAST_CALL; + opline->result_type = IS_TMP_VAR; + opline->result.var = fast_call_var; SET_UNUSED(opline->op1); SET_UNUSED(opline->op2); opline->op1.opline_num = op_array->try_catch_array[i].finally_op; diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 223f43dda7..760f5f99f7 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -5113,10 +5113,6 @@ ZEND_VM_HANDLER(57, ZEND_BEGIN_SILENCE, ANY, ANY) SAVE_OPLINE(); ZVAL_LONG(EX_VAR(opline->result.var), EG(error_reporting)); - if (EX(silence_op_num) == -1) { - EX(silence_op_num) = opline->op2.num; - EX(old_error_reporting) = EG(error_reporting); - } if (EG(error_reporting)) { do { @@ -5154,9 +5150,6 @@ ZEND_VM_HANDLER(58, ZEND_END_SILENCE, TMP, ANY) if (!EG(error_reporting) && Z_LVAL_P(EX_VAR(opline->op1.var)) != 0) { EG(error_reporting) = Z_LVAL_P(EX_VAR(opline->op1.var)); } - if (EX(silence_op_num) == opline->op2.num) { - EX(silence_op_num) = -1; - } ZEND_VM_NEXT_OPCODE(); } @@ -5476,6 +5469,7 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY) } if (op_num < EX(func)->op_array.try_catch_array[i].finally_op) { finally_op_num = EX(func)->op_array.try_catch_array[i].finally_op; + finally_op_end = EX(func)->op_array.try_catch_array[i].finally_end; } if (op_num >= EX(func)->op_array.try_catch_array[i].finally_op && op_num < EX(func)->op_array.try_catch_array[i].finally_end) { @@ -5522,40 +5516,47 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY) if (!(brk_opline->extended_value & EXT_TYPE_FREE_ON_RETURN)) { zval_ptr_dtor_nogc(EX_VAR(brk_opline->op1.var)); } + } else if (brk_opline->opcode == ZEND_END_SILENCE) { + /* restore previous error_reporting value */ + if (!EG(error_reporting) && Z_LVAL_P(EX_VAR(brk_opline->op1.var)) != 0) { + EG(error_reporting) = Z_LVAL_P(EX_VAR(brk_opline->op1.var)); + } } } } } - /* restore previous error_reporting value */ - if (!EG(error_reporting) && EX(silence_op_num) != -1 && EX(old_error_reporting) != 0) { - EG(error_reporting) = EX(old_error_reporting); - } - EX(silence_op_num) = -1; - if (finally_op_num && (!catch_op_num || catch_op_num >= finally_op_num)) { - if (EX(delayed_exception)) { - zend_exception_set_previous(EG(exception), EX(delayed_exception) TSRMLS_CC); + zval *fast_call = EX_VAR(EX(func)->op_array.opcodes[finally_op_end].op1.var); + + if (Z_OBJ_P(fast_call)) { + zend_exception_set_previous(EG(exception), Z_OBJ_P(fast_call) TSRMLS_CC); } - EX(delayed_exception) = EG(exception); + Z_OBJ_P(fast_call) = EG(exception); EG(exception) = NULL; - EX(fast_ret) = NULL; + fast_call->u2.lineno = (uint32_t)-1; ZEND_VM_SET_OPCODE(&EX(func)->op_array.opcodes[finally_op_num]); ZEND_VM_CONTINUE(); } else if (catch_op_num) { if (finally_op_end && catch_op_num > finally_op_end) { /* we are going out of current finally scope */ - if (EX(delayed_exception)) { - zend_exception_set_previous(EG(exception), EX(delayed_exception) TSRMLS_CC); - EX(delayed_exception) = NULL; + zval *fast_call = EX_VAR(EX(func)->op_array.opcodes[finally_op_end].op1.var); + + if (Z_OBJ_P(fast_call)) { + zend_exception_set_previous(EG(exception), Z_OBJ_P(fast_call) TSRMLS_CC); + Z_OBJ_P(fast_call) = NULL; } } ZEND_VM_SET_OPCODE(&EX(func)->op_array.opcodes[catch_op_num]); ZEND_VM_CONTINUE(); } else { - if (EX(delayed_exception)) { - zend_exception_set_previous(EG(exception), EX(delayed_exception) TSRMLS_CC); - EX(delayed_exception) = NULL; + if (finally_op_end) { + zval *fast_call = EX_VAR(EX(func)->op_array.opcodes[finally_op_end].op1.var); + + if (Z_OBJ_P(fast_call)) { + zend_exception_set_previous(EG(exception), Z_OBJ_P(fast_call) TSRMLS_CC); + Z_OBJ_P(fast_call) = NULL; + } } if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_GENERATOR) != 0)) { ZEND_VM_DISPATCH_TO_HANDLER(ZEND_GENERATOR_RETURN); @@ -5815,10 +5816,14 @@ ZEND_VM_HANDLER(160, ZEND_YIELD, CONST|TMP|VAR|CV|UNUSED, CONST|TMP|VAR|CV|UNUSE ZEND_VM_HANDLER(159, ZEND_DISCARD_EXCEPTION, ANY, ANY) { - if (EX(delayed_exception) != NULL) { + USE_OPLINE + zval *fast_call = EX_VAR(opline->op1.var); + + /* check for delayed exception */ + if (Z_OBJ_P(fast_call) != NULL) { /* discard the previously thrown exception */ - OBJ_RELEASE(EX(delayed_exception)); - EX(delayed_exception) = NULL; + OBJ_RELEASE(Z_OBJ_P(fast_call)); + Z_OBJ_P(fast_call) = NULL; } ZEND_VM_NEXT_OPCODE(); @@ -5827,6 +5832,7 @@ ZEND_VM_HANDLER(159, ZEND_DISCARD_EXCEPTION, ANY, ANY) ZEND_VM_HANDLER(162, ZEND_FAST_CALL, ANY, ANY) { USE_OPLINE + zval *fast_call = EX_VAR(opline->result.var); if ((opline->extended_value & ZEND_FAST_CALL_FROM_CATCH) && UNEXPECTED(EG(prev_exception) != NULL)) { @@ -5834,18 +5840,24 @@ ZEND_VM_HANDLER(162, ZEND_FAST_CALL, ANY, ANY) ZEND_VM_SET_OPCODE(&EX(func)->op_array.opcodes[opline->op2.opline_num]); ZEND_VM_CONTINUE(); } - EX(fast_ret) = opline; - EX(delayed_exception) = NULL; + /* set no delayed exception */ + Z_OBJ_P(fast_call) = NULL; + /* set return address */ + fast_call->u2.lineno = opline - EX(func)->op_array.opcodes; ZEND_VM_SET_OPCODE(opline->op1.jmp_addr); ZEND_VM_CONTINUE(); } ZEND_VM_HANDLER(163, ZEND_FAST_RET, ANY, ANY) { - if (EX(fast_ret)) { - ZEND_VM_SET_OPCODE(EX(fast_ret) + 1); - if ((EX(fast_ret)->extended_value & ZEND_FAST_CALL_FROM_FINALLY)) { - EX(fast_ret) = &EX(func)->op_array.opcodes[EX(fast_ret)->op2.opline_num]; + USE_OPLINE + zval *fast_call = EX_VAR(opline->op1.var); + + if (fast_call->u2.lineno != (uint32_t)-1) { + const zend_op *fast_ret = EX(func)->op_array.opcodes + fast_call->u2.lineno; + ZEND_VM_SET_OPCODE(fast_ret + 1); + if (fast_ret->extended_value & ZEND_FAST_CALL_FROM_FINALLY) { + fast_call->u2.lineno = fast_ret->op2.opline_num; } ZEND_VM_CONTINUE(); } else { @@ -5856,8 +5868,8 @@ ZEND_VM_HANDLER(163, ZEND_FAST_RET, ANY, ANY) ZEND_VM_SET_OPCODE(&EX(func)->op_array.opcodes[opline->op2.opline_num]); ZEND_VM_CONTINUE(); } else { - EG(exception) = EX(delayed_exception); - EX(delayed_exception) = NULL; + EG(exception) = Z_OBJ_P(fast_call); + Z_OBJ_P(fast_call) = NULL; if (opline->extended_value == ZEND_FAST_RET_TO_CATCH) { ZEND_VM_SET_OPCODE(&EX(func)->op_array.opcodes[opline->op2.opline_num]); ZEND_VM_CONTINUE(); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 5210484370..dc3ee25c52 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -1029,10 +1029,6 @@ static int ZEND_FASTCALL ZEND_BEGIN_SILENCE_SPEC_HANDLER(ZEND_OPCODE_HANDLER_AR SAVE_OPLINE(); ZVAL_LONG(EX_VAR(opline->result.var), EG(error_reporting)); - if (EX(silence_op_num) == -1) { - EX(silence_op_num) = opline->op2.num; - EX(old_error_reporting) = EG(error_reporting); - } if (EG(error_reporting)) { do { @@ -1218,6 +1214,7 @@ static int ZEND_FASTCALL ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER } if (op_num < EX(func)->op_array.try_catch_array[i].finally_op) { finally_op_num = EX(func)->op_array.try_catch_array[i].finally_op; + finally_op_end = EX(func)->op_array.try_catch_array[i].finally_end; } if (op_num >= EX(func)->op_array.try_catch_array[i].finally_op && op_num < EX(func)->op_array.try_catch_array[i].finally_end) { @@ -1264,40 +1261,47 @@ static int ZEND_FASTCALL ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER if (!(brk_opline->extended_value & EXT_TYPE_FREE_ON_RETURN)) { zval_ptr_dtor_nogc(EX_VAR(brk_opline->op1.var)); } + } else if (brk_opline->opcode == ZEND_END_SILENCE) { + /* restore previous error_reporting value */ + if (!EG(error_reporting) && Z_LVAL_P(EX_VAR(brk_opline->op1.var)) != 0) { + EG(error_reporting) = Z_LVAL_P(EX_VAR(brk_opline->op1.var)); + } } } } } - /* restore previous error_reporting value */ - if (!EG(error_reporting) && EX(silence_op_num) != -1 && EX(old_error_reporting) != 0) { - EG(error_reporting) = EX(old_error_reporting); - } - EX(silence_op_num) = -1; - if (finally_op_num && (!catch_op_num || catch_op_num >= finally_op_num)) { - if (EX(delayed_exception)) { - zend_exception_set_previous(EG(exception), EX(delayed_exception) TSRMLS_CC); + zval *fast_call = EX_VAR(EX(func)->op_array.opcodes[finally_op_end].op1.var); + + if (Z_OBJ_P(fast_call)) { + zend_exception_set_previous(EG(exception), Z_OBJ_P(fast_call) TSRMLS_CC); } - EX(delayed_exception) = EG(exception); + Z_OBJ_P(fast_call) = EG(exception); EG(exception) = NULL; - EX(fast_ret) = NULL; + fast_call->u2.lineno = (uint32_t)-1; ZEND_VM_SET_OPCODE(&EX(func)->op_array.opcodes[finally_op_num]); ZEND_VM_CONTINUE(); } else if (catch_op_num) { if (finally_op_end && catch_op_num > finally_op_end) { /* we are going out of current finally scope */ - if (EX(delayed_exception)) { - zend_exception_set_previous(EG(exception), EX(delayed_exception) TSRMLS_CC); - EX(delayed_exception) = NULL; + zval *fast_call = EX_VAR(EX(func)->op_array.opcodes[finally_op_end].op1.var); + + if (Z_OBJ_P(fast_call)) { + zend_exception_set_previous(EG(exception), Z_OBJ_P(fast_call) TSRMLS_CC); + Z_OBJ_P(fast_call) = NULL; } } ZEND_VM_SET_OPCODE(&EX(func)->op_array.opcodes[catch_op_num]); ZEND_VM_CONTINUE(); } else { - if (EX(delayed_exception)) { - zend_exception_set_previous(EG(exception), EX(delayed_exception) TSRMLS_CC); - EX(delayed_exception) = NULL; + if (finally_op_end) { + zval *fast_call = EX_VAR(EX(func)->op_array.opcodes[finally_op_end].op1.var); + + if (Z_OBJ_P(fast_call)) { + zend_exception_set_previous(EG(exception), Z_OBJ_P(fast_call) TSRMLS_CC); + Z_OBJ_P(fast_call) = NULL; + } } if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_GENERATOR) != 0)) { return ZEND_GENERATOR_RETURN_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -1348,10 +1352,14 @@ static int ZEND_FASTCALL ZEND_USER_OPCODE_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS static int ZEND_FASTCALL ZEND_DISCARD_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - if (EX(delayed_exception) != NULL) { + USE_OPLINE + zval *fast_call = EX_VAR(opline->op1.var); + + /* check for delayed exception */ + if (Z_OBJ_P(fast_call) != NULL) { /* discard the previously thrown exception */ - OBJ_RELEASE(EX(delayed_exception)); - EX(delayed_exception) = NULL; + OBJ_RELEASE(Z_OBJ_P(fast_call)); + Z_OBJ_P(fast_call) = NULL; } ZEND_VM_NEXT_OPCODE(); @@ -1360,6 +1368,7 @@ static int ZEND_FASTCALL ZEND_DISCARD_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLE static int ZEND_FASTCALL ZEND_FAST_CALL_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE + zval *fast_call = EX_VAR(opline->result.var); if ((opline->extended_value & ZEND_FAST_CALL_FROM_CATCH) && UNEXPECTED(EG(prev_exception) != NULL)) { @@ -1367,18 +1376,24 @@ static int ZEND_FASTCALL ZEND_FAST_CALL_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS) ZEND_VM_SET_OPCODE(&EX(func)->op_array.opcodes[opline->op2.opline_num]); ZEND_VM_CONTINUE(); } - EX(fast_ret) = opline; - EX(delayed_exception) = NULL; + /* set no delayed exception */ + Z_OBJ_P(fast_call) = NULL; + /* set return address */ + fast_call->u2.lineno = opline - EX(func)->op_array.opcodes; ZEND_VM_SET_OPCODE(opline->op1.jmp_addr); ZEND_VM_CONTINUE(); } static int ZEND_FASTCALL ZEND_FAST_RET_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - if (EX(fast_ret)) { - ZEND_VM_SET_OPCODE(EX(fast_ret) + 1); - if ((EX(fast_ret)->extended_value & ZEND_FAST_CALL_FROM_FINALLY)) { - EX(fast_ret) = &EX(func)->op_array.opcodes[EX(fast_ret)->op2.opline_num]; + USE_OPLINE + zval *fast_call = EX_VAR(opline->op1.var); + + if (fast_call->u2.lineno != (uint32_t)-1) { + const zend_op *fast_ret = EX(func)->op_array.opcodes + fast_call->u2.lineno; + ZEND_VM_SET_OPCODE(fast_ret + 1); + if (fast_ret->extended_value & ZEND_FAST_CALL_FROM_FINALLY) { + fast_call->u2.lineno = fast_ret->op2.opline_num; } ZEND_VM_CONTINUE(); } else { @@ -1389,8 +1404,8 @@ static int ZEND_FASTCALL ZEND_FAST_RET_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS) ZEND_VM_SET_OPCODE(&EX(func)->op_array.opcodes[opline->op2.opline_num]); ZEND_VM_CONTINUE(); } else { - EG(exception) = EX(delayed_exception); - EX(delayed_exception) = NULL; + EG(exception) = Z_OBJ_P(fast_call); + Z_OBJ_P(fast_call) = NULL; if (opline->extended_value == ZEND_FAST_RET_TO_CATCH) { ZEND_VM_SET_OPCODE(&EX(func)->op_array.opcodes[opline->op2.opline_num]); ZEND_VM_CONTINUE(); @@ -10251,9 +10266,6 @@ static int ZEND_FASTCALL ZEND_END_SILENCE_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ if (!EG(error_reporting) && Z_LVAL_P(EX_VAR(opline->op1.var)) != 0) { EG(error_reporting) = Z_LVAL_P(EX_VAR(opline->op1.var)); } - if (EX(silence_op_num) == opline->op2.num) { - EX(silence_op_num) = -1; - } ZEND_VM_NEXT_OPCODE(); } diff --git a/ext/filter/filter.c b/ext/filter/filter.c index a8602a9f32..d1b2abf2aa 100644 --- a/ext/filter/filter.c +++ b/ext/filter/filter.c @@ -44,6 +44,7 @@ static const filter_list_entry filter_list[] = { { "float", FILTER_VALIDATE_FLOAT, php_filter_float }, { "validate_regexp", FILTER_VALIDATE_REGEXP, php_filter_validate_regexp }, + { "validate_domain", FILTER_VALIDATE_DOMAIN, php_filter_validate_domain }, { "validate_url", FILTER_VALIDATE_URL, php_filter_validate_url }, { "validate_email", FILTER_VALIDATE_EMAIL, php_filter_validate_email }, { "validate_ip", FILTER_VALIDATE_IP, php_filter_validate_ip }, @@ -237,6 +238,7 @@ PHP_MINIT_FUNCTION(filter) REGISTER_LONG_CONSTANT("FILTER_VALIDATE_FLOAT", FILTER_VALIDATE_FLOAT, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("FILTER_VALIDATE_REGEXP", FILTER_VALIDATE_REGEXP, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("FILTER_VALIDATE_DOMAIN", FILTER_VALIDATE_DOMAIN, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("FILTER_VALIDATE_URL", FILTER_VALIDATE_URL, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("FILTER_VALIDATE_EMAIL", FILTER_VALIDATE_EMAIL, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("FILTER_VALIDATE_IP", FILTER_VALIDATE_IP, CONST_CS | CONST_PERSISTENT); @@ -284,6 +286,8 @@ PHP_MINIT_FUNCTION(filter) REGISTER_LONG_CONSTANT("FILTER_FLAG_NO_RES_RANGE", FILTER_FLAG_NO_RES_RANGE, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("FILTER_FLAG_NO_PRIV_RANGE", FILTER_FLAG_NO_PRIV_RANGE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("FILTER_FLAG_HOSTNAME", FILTER_FLAG_HOSTNAME, CONST_CS | CONST_PERSISTENT); + sapi_register_input_filter(php_sapi_filter, php_sapi_filter_init TSRMLS_CC); return SUCCESS; diff --git a/ext/filter/filter_private.h b/ext/filter/filter_private.h index b07b6ca534..8bfbb2df8b 100644 --- a/ext/filter/filter_private.h +++ b/ext/filter/filter_private.h @@ -55,6 +55,8 @@ #define FILTER_FLAG_NO_RES_RANGE 0x400000 #define FILTER_FLAG_NO_PRIV_RANGE 0x800000 +#define FILTER_FLAG_HOSTNAME 0x100000 + #define FILTER_VALIDATE_INT 0x0101 #define FILTER_VALIDATE_BOOLEAN 0x0102 #define FILTER_VALIDATE_FLOAT 0x0103 @@ -64,7 +66,8 @@ #define FILTER_VALIDATE_EMAIL 0x0112 #define FILTER_VALIDATE_IP 0x0113 #define FILTER_VALIDATE_MAC 0x0114 -#define FILTER_VALIDATE_LAST 0x0114 +#define FILTER_VALIDATE_DOMAIN 0x0115 +#define FILTER_VALIDATE_LAST 0x0115 #define FILTER_VALIDATE_ALL 0x0100 diff --git a/ext/filter/logical_filters.c b/ext/filter/logical_filters.c index be1c2f0d40..01497192f0 100644 --- a/ext/filter/logical_filters.c +++ b/ext/filter/logical_filters.c @@ -14,6 +14,7 @@ +----------------------------------------------------------------------+ | Authors: Derick Rethans <derick@php.net> | | Pierre-A. Joye <pierre@php.net> | + | Kévin Dunglas <dunglas@gmail.com> | +----------------------------------------------------------------------+ */ @@ -80,6 +81,8 @@ #define FORMAT_IPV4 4 #define FORMAT_IPV6 6 +static int _php_filter_validate_ipv6(char *str, size_t str_len TSRMLS_DC); + static int php_filter_parse_int(const char *str, size_t str_len, zend_long *ret TSRMLS_DC) { /* {{{ */ zend_long ctx_value; int sign = 0, digit = 0; @@ -452,6 +455,65 @@ void php_filter_validate_regexp(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */ RETURN_VALIDATION_FAILED } } + +static int _php_filter_validate_domain(char * domain, int len, zend_long flags) /* {{{ */ +{ + char *e, *s, *t; + size_t l; + int hostname = flags & FILTER_FLAG_HOSTNAME; + unsigned char i = 1; + + s = domain; + l = len; + e = domain + l; + t = e - 1; + + /* Ignore trailing dot */ + if (*t == '.') { + e = t; + l--; + } + + /* The total length cannot exceed 253 characters (final dot not included) */ + if (l > 253) { + return 0; + } + + /* First char must be alphanumeric */ + if(*s == '.' || (hostname && !isalnum((int)*(unsigned char *)s))) { + return 0; + } + + while (s < e) { + if (*s == '.') { + /* The first and the last character of a label must be alphanumeric */ + if (*(s + 1) == '.' || (hostname && (!isalnum((int)*(unsigned char *)(s - 1)) || !isalnum((int)*(unsigned char *)(s + 1))))) { + return 0; + } + + /* Reset label length counter */ + i = 1; + } else { + if (i > 63 || (hostname && *s != '-' && !isalnum((int)*(unsigned char *)s))) { + return 0; + } + + i++; + } + + s++; + } + + return 1; +} +/* }}} */ + +void php_filter_validate_domain(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */ +{ + if (!_php_filter_validate_domain(Z_STRVAL_P(value), Z_STRLEN_P(value), flags)) { + RETURN_VALIDATION_FAILED + } +} /* }}} */ void php_filter_validate_url(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */ @@ -473,25 +535,28 @@ void php_filter_validate_url(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */ } if (url->scheme != NULL && (!strcasecmp(url->scheme, "http") || !strcasecmp(url->scheme, "https"))) { - char *e, *s; + char *e, *s, *t; + size_t l; if (url->host == NULL) { goto bad_url; } - e = url->host + strlen(url->host); s = url->host; - - /* First char of hostname must be alphanumeric */ - if(!isalnum((int)*(unsigned char *)s)) { - goto bad_url; + l = strlen(s); + e = url->host + l; + t = e - 1; + + /* An IPv6 enclosed by square brackets is a valid hostname */ + if (*s == '[' && *t == ']' && _php_filter_validate_ipv6((s + 1), l - 2 TSRMLS_CC)) { + php_url_free(url); + return; } - while (s < e) { - if (!isalnum((int)*(unsigned char *)s) && *s != '-' && *s != '.') { - goto bad_url; - } - s++; + // Validate domain + if (!_php_filter_validate_domain(url->host, l, FILTER_FLAG_HOSTNAME)) { + php_url_free(url); + RETURN_VALIDATION_FAILED } } diff --git a/ext/filter/php_filter.h b/ext/filter/php_filter.h index a1e7e6602c..7ddb009b87 100644 --- a/ext/filter/php_filter.h +++ b/ext/filter/php_filter.h @@ -76,6 +76,7 @@ void php_filter_int(PHP_INPUT_FILTER_PARAM_DECL); void php_filter_boolean(PHP_INPUT_FILTER_PARAM_DECL); void php_filter_float(PHP_INPUT_FILTER_PARAM_DECL); void php_filter_validate_regexp(PHP_INPUT_FILTER_PARAM_DECL); +void php_filter_validate_domain(PHP_INPUT_FILTER_PARAM_DECL); void php_filter_validate_url(PHP_INPUT_FILTER_PARAM_DECL); void php_filter_validate_email(PHP_INPUT_FILTER_PARAM_DECL); void php_filter_validate_ip(PHP_INPUT_FILTER_PARAM_DECL); diff --git a/ext/filter/tests/008.phpt b/ext/filter/tests/008.phpt index a499219ee7..54880e59cc 100644 --- a/ext/filter/tests/008.phpt +++ b/ext/filter/tests/008.phpt @@ -11,7 +11,7 @@ var_dump(filter_list(array())); echo "Done\n"; ?> --EXPECTF-- -array(20) { +array(21) { [0]=> string(3) "int" [1]=> @@ -21,36 +21,38 @@ array(20) { [3]=> string(15) "validate_regexp" [4]=> - string(12) "validate_url" + string(15) "validate_domain" [5]=> - string(14) "validate_email" + string(12) "validate_url" [6]=> - string(11) "validate_ip" + string(14) "validate_email" [7]=> - string(12) "validate_mac" + string(11) "validate_ip" [8]=> - string(6) "string" + string(12) "validate_mac" [9]=> - string(8) "stripped" + string(6) "string" [10]=> - string(7) "encoded" + string(8) "stripped" [11]=> - string(13) "special_chars" + string(7) "encoded" [12]=> - string(18) "full_special_chars" + string(13) "special_chars" [13]=> - string(10) "unsafe_raw" + string(18) "full_special_chars" [14]=> - string(5) "email" + string(10) "unsafe_raw" [15]=> - string(3) "url" + string(5) "email" [16]=> - string(10) "number_int" + string(3) "url" [17]=> - string(12) "number_float" + string(10) "number_int" [18]=> - string(12) "magic_quotes" + string(12) "number_float" [19]=> + string(12) "magic_quotes" + [20]=> string(8) "callback" } diff --git a/ext/filter/tests/015.phpt b/ext/filter/tests/015.phpt index 476615ae37..44926a1cac 100644 --- a/ext/filter/tests/015.phpt +++ b/ext/filter/tests/015.phpt @@ -11,6 +11,22 @@ $values = Array( 'http://www.example/img/test.png', 'http://www.example/img/dir/', 'http://www.example/img/dir', +'http://www.thelongestdomainnameintheworldandthensomeandthensomemoreandmore.com/', +'http://toolongtoolongtoolongtoolongtoolongtoolongtoolongtoolongtoolongtoolong.com', +'http://eauBcFReEmjLcoZwI0RuONNnwU4H9r151juCaqTI5VeIP5jcYIqhx1lh5vV00l2rTs6y7hOp7rYw42QZiq6VIzjcYrRm8gFRMk9U9Wi1grL8Mr5kLVloYLthHgyA94QK3SaXCATklxgo6XvcbXIqAGG7U0KxTr8hJJU1p2ZQ2mXHmp4DhYP8N9SRuEKzaCPcSIcW7uj21jZqBigsLsNAXEzU8SPXZjmVQVtwQATPWeWyGW4GuJhjP4Q8o0.com', +'http://kDTvHt1PPDgX5EiP2MwiXjcoWNOhhTuOVAUWJ3TmpBYCC9QoJV114LMYrV3Zl58.kDTvHt1PPDgX5EiP2MwiXjcoWNOhhTuOVAUWJ3TmpBYCC9QoJV114LMYrV3Zl58.kDTvHt1PPDgX5EiP2MwiXjcoWNOhhTuOVAUWJ3TmpBYCC9QoJV114LMYrV3Zl58.CQ1oT5Uq3jJt6Uhy3VH9u3Gi5YhfZCvZVKgLlaXNFhVKB1zJxvunR7SJa.com.', +'http://kDTvHt1PPDgX5EiP2MwiXjcoWNOhhTuOVAUWJ3TmpBYCC9QoJV114LMYrV3Zl58R.example.com', +'http://[2001:0db8:0000:85a3:0000:0000:ac1f:8001]', +'http://[2001:db8:0:85a3:0:0:ac1f:8001]:123/me.html', +'http://[2001:db8:0:85a3::ac1f:8001]/', +'http://[::1]', +'http://cont-ains.h-yph-en-s.com', +'http://..com', +'http://a.-bc.com', +'http://ab.cd-.com', +'http://-.abc.com', +'http://abc.-.abc.com', +'http://underscore_.example.com', 'http//www.example/wrong/url/', 'http:/www.example', 'file:///tmp/test.c', @@ -56,6 +72,22 @@ string(32) "http://www.example.com/index.php" string(31) "http://www.example/img/test.png" string(27) "http://www.example/img/dir/" string(26) "http://www.example/img/dir" +string(79) "http://www.thelongestdomainnameintheworldandthensomeandthensomemoreandmore.com/" +bool(false) +bool(false) +string(261) "http://kDTvHt1PPDgX5EiP2MwiXjcoWNOhhTuOVAUWJ3TmpBYCC9QoJV114LMYrV3Zl58.kDTvHt1PPDgX5EiP2MwiXjcoWNOhhTuOVAUWJ3TmpBYCC9QoJV114LMYrV3Zl58.kDTvHt1PPDgX5EiP2MwiXjcoWNOhhTuOVAUWJ3TmpBYCC9QoJV114LMYrV3Zl58.CQ1oT5Uq3jJt6Uhy3VH9u3Gi5YhfZCvZVKgLlaXNFhVKB1zJxvunR7SJa.com." +bool(false) +string(48) "http://[2001:0db8:0000:85a3:0000:0000:ac1f:8001]" +string(50) "http://[2001:db8:0:85a3:0:0:ac1f:8001]:123/me.html" +string(36) "http://[2001:db8:0:85a3::ac1f:8001]/" +string(12) "http://[::1]" +string(31) "http://cont-ains.h-yph-en-s.com" +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) bool(false) bool(false) string(18) "file:///tmp/test.c" diff --git a/ext/filter/tests/033.phpt b/ext/filter/tests/033.phpt index d76f9ab3b8..3819c6a01c 100644 --- a/ext/filter/tests/033.phpt +++ b/ext/filter/tests/033.phpt @@ -14,6 +14,7 @@ int 1 123 boolean 1 float 1 123 validate_regexp O'Henry +validate_domain PHP 1 foo@bar.com http://a.b.c 1.2.3.4 123 123abc<>() O'Henry 하퍼 aa:bb:cc:dd:ee:ff validate_url http://a.b.c validate_email foo@bar.com validate_ip 1.2.3.4 @@ -29,4 +30,4 @@ url PHP 1 foo@bar.com http://a.b.c 1.2.3.4 123 12 number_int 1 1234 123 123 number_float 1 1234 123 123 magic_quotes PHP 1 foo@bar.com http://a.b.c 1.2.3.4 123 123abc<>() O\'Henry 하퍼 aa:bb:cc:dd:ee:ff -callback PHP 1 FOO@BAR.COM HTTP://A.B.C 1.2.3.4 123 123ABC<>() O'HENRY 하퍼 AA:BB:CC:DD:EE:FF
\ No newline at end of file +callback PHP 1 FOO@BAR.COM HTTP://A.B.C 1.2.3.4 123 123ABC<>() O'HENRY 하퍼 AA:BB:CC:DD:EE:FF diff --git a/ext/filter/tests/056.phpt b/ext/filter/tests/056.phpt new file mode 100644 index 0000000000..4a27a9fa10 --- /dev/null +++ b/ext/filter/tests/056.phpt @@ -0,0 +1,68 @@ +--TEST-- +filter_var() and FILTER_VALIDATE_DOMAIN +--SKIPIF-- +<?php if (!extension_loaded("filter")) die("skip"); ?> +--FILE-- +<?php + +$values = Array( +'example.com', +'www.thelongestdomainnameintheworldandthensomeandthensomemoreandmore.com', +'toolongtoolongtoolongtoolongtoolongtoolongtoolongtoolongtoolongtoolong.com', +'eauBcFReEmjLcoZwI0RuONNnwU4H9r151juCaqTI5VeIP5jcYIqhx1lh5vV00l2rTs6y7hOp7rYw42QZiq6VIzjcYrRm8gFRMk9U9Wi1grL8Mr5kLVloYLthHgyA94QK3SaXCATklxgo6XvcbXIqAGG7U0KxTr8hJJU1p2ZQ2mXHmp4DhYP8N9SRuEKzaCPcSIcW7uj21jZqBigsLsNAXEzU8SPXZjmVQVtwQATPWeWyGW4GuJhjP4Q8o0.com', +'kDTvHt1PPDgX5EiP2MwiXjcoWNOhhTuOVAUWJ3TmpBYCC9QoJV114LMYrV3Zl58.kDTvHt1PPDgX5EiP2MwiXjcoWNOhhTuOVAUWJ3TmpBYCC9QoJV114LMYrV3Zl58.kDTvHt1PPDgX5EiP2MwiXjcoWNOhhTuOVAUWJ3TmpBYCC9QoJV114LMYrV3Zl58.CQ1oT5Uq3jJt6Uhy3VH9u3Gi5YhfZCvZVKgLlaXNFhVKB1zJxvunR7SJa.com.', +'cont-ains.h-yph-en-s.com', +'..com', +'ab..cc.dd', +'a.-bc.com', +'ab.cd-.com', +'-.abc.com', +'abc.-.abc.com', +'underscore_.example.com', +'', +-1, +array(), +'\r\n', +); +foreach ($values as $value) { + var_dump(filter_var($value, FILTER_VALIDATE_DOMAIN, FILTER_FLAG_HOSTNAME)); +} + +var_dump(filter_var('_example.com', FILTER_VALIDATE_DOMAIN)); +var_dump(filter_var('_example.com', FILTER_VALIDATE_DOMAIN, FILTER_FLAG_HOSTNAME)); +var_dump(filter_var('test_.example.com', FILTER_VALIDATE_DOMAIN)); +var_dump(filter_var('test_.example.com', FILTER_VALIDATE_DOMAIN, FILTER_FLAG_HOSTNAME)); +var_dump(filter_var('te_st.example.com', FILTER_VALIDATE_DOMAIN)); +var_dump(filter_var('te_st.example.com', FILTER_VALIDATE_DOMAIN, FILTER_FLAG_HOSTNAME)); +var_dump(filter_var('test._example.com', FILTER_VALIDATE_DOMAIN)); +var_dump(filter_var('test._example.com', FILTER_VALIDATE_DOMAIN, FILTER_FLAG_HOSTNAME)); + +echo "Done\n"; +?> +--EXPECT-- +string(11) "example.com" +string(71) "www.thelongestdomainnameintheworldandthensomeandthensomemoreandmore.com" +bool(false) +bool(false) +string(254) "kDTvHt1PPDgX5EiP2MwiXjcoWNOhhTuOVAUWJ3TmpBYCC9QoJV114LMYrV3Zl58.kDTvHt1PPDgX5EiP2MwiXjcoWNOhhTuOVAUWJ3TmpBYCC9QoJV114LMYrV3Zl58.kDTvHt1PPDgX5EiP2MwiXjcoWNOhhTuOVAUWJ3TmpBYCC9QoJV114LMYrV3Zl58.CQ1oT5Uq3jJt6Uhy3VH9u3Gi5YhfZCvZVKgLlaXNFhVKB1zJxvunR7SJa.com." +string(24) "cont-ains.h-yph-en-s.com" +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +string(12) "_example.com" +bool(false) +string(17) "test_.example.com" +bool(false) +string(17) "te_st.example.com" +bool(false) +string(17) "test._example.com" +bool(false) +Done diff --git a/ext/mbstring/config.w32 b/ext/mbstring/config.w32 index 27a8143686..ca1fbcdf28 100644 --- a/ext/mbstring/config.w32 +++ b/ext/mbstring/config.w32 @@ -1,53 +1,71 @@ // $Id$ // vim:ft=javascript +ARG_WITH("libmbfl", "use external libmbfl", "no"); ARG_ENABLE("mbstring", "multibyte string functions", "no"); ARG_ENABLE("mbregex", "multibyte regex support", "no"); ARG_ENABLE("mbregex-backtrack", "check multibyte regex backtrack", "yes"); if (PHP_MBSTRING != "no") { - FSO.CopyFile("ext\\mbstring\\libmbfl\\config.h.w32", - "ext\\mbstring\\libmbfl\\config.h", true); - FSO.CopyFile("ext\\mbstring\\oniguruma\\win32\\config.h", - "ext\\mbstring\\oniguruma\\config.h", true); - - EXTENSION("mbstring", "mbstring.c php_unicode.c mb_gpc.c", PHP_MBSTRING_SHARED, - "-Iext/mbstring/libmbfl -Iext/mbstring/libmbfl/mbfl \ - -Iext/mbstring/oniguruma /D NOT_RUBY=1 /D LIBMBFL_EXPORTS=1 \ - /D HAVE_STDARG_PROTOTYPES=1 /D HAVE_CONFIG_H /D HAVE_STDLIB_H \ - /D HAVE_STRICMP /D MBFL_DLL_EXPORT=1 /D EXPORT /DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); - - ADD_SOURCES("ext/mbstring/libmbfl/filters", "html_entities.c \ - mbfilter_7bit.c mbfilter_ascii.c mbfilter_base64.c mbfilter_big5.c \ - mbfilter_byte2.c mbfilter_byte4.c mbfilter_cp1251.c mbfilter_cp1252.c \ - mbfilter_cp866.c mbfilter_cp932.c mbfilter_cp936.c mbfilter_cp51932.c \ - mbfilter_euc_cn.c mbfilter_euc_jp.c mbfilter_euc_jp_win.c mbfilter_euc_kr.c \ - mbfilter_euc_tw.c mbfilter_htmlent.c mbfilter_hz.c mbfilter_iso2022_kr.c \ - mbfilter_iso8859_1.c mbfilter_iso8859_10.c mbfilter_iso8859_13.c \ - mbfilter_iso8859_14.c mbfilter_iso8859_15.c mbfilter_iso8859_16.c \ - mbfilter_iso8859_2.c mbfilter_iso8859_3.c mbfilter_iso8859_4.c \ - mbfilter_iso8859_5.c mbfilter_iso8859_6.c mbfilter_iso8859_7.c \ - mbfilter_iso8859_8.c mbfilter_iso8859_9.c mbfilter_jis.c \ - mbfilter_iso2022_jp_ms.c mbfilter_gb18030.c mbfilter_sjis_2004.c \ - mbfilter_koi8r.c mbfilter_qprint.c mbfilter_sjis.c mbfilter_ucs2.c \ - mbfilter_ucs4.c mbfilter_uhc.c mbfilter_utf16.c mbfilter_utf32.c \ - mbfilter_utf7.c mbfilter_utf7imap.c mbfilter_utf8.c mbfilter_utf8_mobile.c \ - mbfilter_koi8u.c mbfilter_cp1254.c mbfilter_euc_jp_2004.c \ - mbfilter_uuencode.c mbfilter_armscii8.c mbfilter_cp850.c \ - mbfilter_cp5022x.c mbfilter_sjis_open.c mbfilter_sjis_mobile.c \ - mbfilter_sjis_mac.c \ - mbfilter_iso2022jp_2004.c mbfilter_iso2022jp_mobile.c \ - mbfilter_tl_jisx0201_jisx0208.c", "mbstring"); + EXTENSION("mbstring", "mbstring.c php_unicode.c mb_gpc.c", PHP_MBSTRING_SHARED); + + if (PHP_LIBMBFL != "no" && + CHECK_HEADER_ADD_INCLUDE("mbfl/mbfilter.h", "CFLAGS_LIBMBFL", PHP_LIBMBFL + "\\include") && + CHECK_LIB("mbfl.lib", "libmbfl", PHP_LIBMBFL + "\\lib")) { + + ADD_FLAG("LIBS_MBSTRING", get_define("LIBS_LIBMBFL")); + ADD_FLAG("LDFLAGS_MBSTRING", get_define("LDFLAGS_LIBMBFL")); + ADD_FLAG("CFLAGS_MBSTRING", get_define("CFLAGS_LIBMBFL") + + " /I ext/mbstring/oniguruma /D NOT_RUBY=1 \ + /D HAVE_STDARG_PROTOTYPES=1 /D HAVE_STDLIB_H \ + /D HAVE_STRICMP /D EXPORT /DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); + + PHP_INSTALL_HEADERS("ext/mbstring", "mbstring.h oniguruma/oniguruma.h php_mbregex.h php_onig_compat.h"); + } else { + STDOUT.WriteLine("Using bundled libmbfl..."); + + ADD_FLAG("CFLAGS_MBSTRING", "-Iext/mbstring/libmbfl -Iext/mbstring/libmbfl/mbfl \ + -Iext/mbstring/oniguruma /D NOT_RUBY=1 /D LIBMBFL_EXPORTS=1 \ + /D HAVE_STDARG_PROTOTYPES=1 /D HAVE_CONFIG_H /D HAVE_STDLIB_H \ + /D HAVE_STRICMP /D MBFL_DLL_EXPORT=1 /D EXPORT /DZEND_ENABLE_STATIC_TSRMLS_CACHE=1") - ADD_SOURCES("ext/mbstring/libmbfl/mbfl", "mbfilter.c mbfilter_8bit.c \ - mbfilter_pass.c mbfilter_wchar.c mbfl_convert.c mbfl_encoding.c \ - mbfl_filter_output.c mbfl_ident.c mbfl_language.c mbfl_memory_device.c \ - mbfl_string.c mbfl_allocators.c", "mbstring"); + FSO.CopyFile("ext\\mbstring\\libmbfl\\config.h.w32", + "ext\\mbstring\\libmbfl\\config.h", true); - ADD_SOURCES("ext/mbstring/libmbfl/nls", "nls_de.c nls_en.c nls_ja.c \ - nls_kr.c nls_neutral.c nls_ru.c nls_uni.c nls_zh.c nls_hy.c \ - nls_ua.c nls_tr.c", "mbstring"); + ADD_SOURCES("ext/mbstring/libmbfl/filters", "html_entities.c \ + mbfilter_7bit.c mbfilter_ascii.c mbfilter_base64.c mbfilter_big5.c \ + mbfilter_byte2.c mbfilter_byte4.c mbfilter_cp1251.c mbfilter_cp1252.c \ + mbfilter_cp866.c mbfilter_cp932.c mbfilter_cp936.c mbfilter_cp51932.c \ + mbfilter_euc_cn.c mbfilter_euc_jp.c mbfilter_euc_jp_win.c mbfilter_euc_kr.c \ + mbfilter_euc_tw.c mbfilter_htmlent.c mbfilter_hz.c mbfilter_iso2022_kr.c \ + mbfilter_iso8859_1.c mbfilter_iso8859_10.c mbfilter_iso8859_13.c \ + mbfilter_iso8859_14.c mbfilter_iso8859_15.c mbfilter_iso8859_16.c \ + mbfilter_iso8859_2.c mbfilter_iso8859_3.c mbfilter_iso8859_4.c \ + mbfilter_iso8859_5.c mbfilter_iso8859_6.c mbfilter_iso8859_7.c \ + mbfilter_iso8859_8.c mbfilter_iso8859_9.c mbfilter_jis.c \ + mbfilter_iso2022_jp_ms.c mbfilter_gb18030.c mbfilter_sjis_2004.c \ + mbfilter_koi8r.c mbfilter_qprint.c mbfilter_sjis.c mbfilter_ucs2.c \ + mbfilter_ucs4.c mbfilter_uhc.c mbfilter_utf16.c mbfilter_utf32.c \ + mbfilter_utf7.c mbfilter_utf7imap.c mbfilter_utf8.c mbfilter_utf8_mobile.c \ + mbfilter_koi8u.c mbfilter_cp1254.c mbfilter_euc_jp_2004.c \ + mbfilter_uuencode.c mbfilter_armscii8.c mbfilter_cp850.c \ + mbfilter_cp5022x.c mbfilter_sjis_open.c mbfilter_sjis_mobile.c \ + mbfilter_sjis_mac.c \ + mbfilter_iso2022jp_2004.c mbfilter_iso2022jp_mobile.c \ + mbfilter_tl_jisx0201_jisx0208.c", "mbstring"); + + ADD_SOURCES("ext/mbstring/libmbfl/mbfl", "mbfilter.c mbfilter_8bit.c \ + mbfilter_pass.c mbfilter_wchar.c mbfl_convert.c mbfl_encoding.c \ + mbfl_filter_output.c mbfl_ident.c mbfl_language.c mbfl_memory_device.c \ + mbfl_string.c mbfl_allocators.c", "mbstring"); + + ADD_SOURCES("ext/mbstring/libmbfl/nls", "nls_de.c nls_en.c nls_ja.c \ + nls_kr.c nls_neutral.c nls_ru.c nls_uni.c nls_zh.c nls_hy.c \ + nls_ua.c nls_tr.c", "mbstring"); + + PHP_INSTALL_HEADERS("ext/mbstring", "mbstring.h oniguruma/oniguruma.h php_mbregex.h php_onig_compat.h libmbfl/config.h libmbfl/mbfl/eaw_table.h libmbfl/mbfl/mbfilter.h libmbfl/mbfl/mbfilter_8bit.h libmbfl/mbfl/mbfilter_pass.h libmbfl/mbfl/mbfilter_wchar.h libmbfl/mbfl/mbfl_allocators.h libmbfl/mbfl/mbfl_consts.h libmbfl/mbfl/mbfl_convert.h libmbfl/mbfl/mbfl_defs.h libmbfl/mbfl/mbfl_encoding.h libmbfl/mbfl/mbfl_filter_output.h libmbfl/mbfl/mbfl_ident.h libmbfl/mbfl/mbfl_language.h libmbfl/mbfl/mbfl_memory_device.h libmbfl/mbfl/mbfl_string.h"); + } AC_DEFINE('HAVE_MBSTRING', 1, 'Have mbstring support'); AC_DEFINE('HAVE_MBSTR_CN', 1, 'CN'); @@ -56,7 +74,8 @@ if (PHP_MBSTRING != "no") { AC_DEFINE('HAVE_MBSTR_RU', 1, 'RU'); AC_DEFINE('HAVE_MBSTR_TW', 1, 'TW'); - PHP_INSTALL_HEADERS("ext/mbstring", "mbstring.h oniguruma/oniguruma.h php_mbregex.h php_onig_compat.h libmbfl/config.h libmbfl/mbfl/eaw_table.h libmbfl/mbfl/mbfilter.h libmbfl/mbfl/mbfilter_8bit.h libmbfl/mbfl/mbfilter_pass.h libmbfl/mbfl/mbfilter_wchar.h libmbfl/mbfl/mbfl_allocators.h libmbfl/mbfl/mbfl_consts.h libmbfl/mbfl/mbfl_convert.h libmbfl/mbfl/mbfl_defs.h libmbfl/mbfl/mbfl_encoding.h libmbfl/mbfl/mbfl_filter_output.h libmbfl/mbfl/mbfl_ident.h libmbfl/mbfl/mbfl_language.h libmbfl/mbfl/mbfl_memory_device.h libmbfl/mbfl/mbfl_string.h"); + FSO.CopyFile("ext\\mbstring\\oniguruma\\win32\\config.h", + "ext\\mbstring\\oniguruma\\config.h", true); if (PHP_MBREGEX != "no") { AC_DEFINE('HAVE_STDARG_PROTOTYPES', 1, 'have stdarg.h'); diff --git a/ext/opcache/Optimizer/block_pass.c b/ext/opcache/Optimizer/block_pass.c index 5c6880beea..6f3f1310a0 100644 --- a/ext/opcache/Optimizer/block_pass.c +++ b/ext/opcache/Optimizer/block_pass.c @@ -204,7 +204,8 @@ static int find_code_blocks(zend_op_array *op_array, zend_cfg *cfg, zend_optimiz j = 0; for (i = 0; i< op_array->last_brk_cont; i++) { if (op_array->brk_cont_array[i].start >= 0 && - op_array->opcodes[op_array->brk_cont_array[i].brk].opcode == ZEND_FREE) { + (op_array->opcodes[op_array->brk_cont_array[i].brk].opcode == ZEND_FREE || + op_array->opcodes[op_array->brk_cont_array[i].brk].opcode == ZEND_END_SILENCE)) { int parent = op_array->brk_cont_array[i].parent; while (parent >= 0 && @@ -223,7 +224,8 @@ static int find_code_blocks(zend_op_array *op_array, zend_cfg *cfg, zend_optimiz j = 0; for (i = 0; i< op_array->last_brk_cont; i++) { if (op_array->brk_cont_array[i].start >= 0 && - op_array->opcodes[op_array->brk_cont_array[i].brk].opcode == ZEND_FREE) { + (op_array->opcodes[op_array->brk_cont_array[i].brk].opcode == ZEND_FREE || + op_array->opcodes[op_array->brk_cont_array[i].brk].opcode == ZEND_END_SILENCE)) { if (i != j) { op_array->brk_cont_array[j] = op_array->brk_cont_array[i]; } diff --git a/ext/zlib/tests/bug_52944-darwin.phpt b/ext/zlib/tests/bug_52944-darwin.phpt deleted file mode 100644 index c25babadf5..0000000000 --- a/ext/zlib/tests/bug_52944-darwin.phpt +++ /dev/null @@ -1,24 +0,0 @@ ---TEST-- -Bug #52944 (segfault with zlib filter and corrupted data) ---SKIPIF-- -<?php if (!extension_loaded("zlib")) print "skip"; ?> -<?php -if (PHP_OS != 'Darwin') { - die("skip Darwin only"); -} ---INI-- -allow_url_fopen=1 ---FILE-- -<?php -require dirname(__FILE__) . "/bug_52944_corrupted_data.inc"; - -$fp = fopen('data://text/plain;base64,' . $data, 'r'); -stream_filter_append($fp, 'zlib.inflate', STREAM_FILTER_READ); -var_dump(fread($fp,1)); -var_dump(fread($fp,1)); -fclose($fp); -echo "Done.\n"; ---EXPECT-- -string(1) "%" -string(1) "C" -Done. diff --git a/ext/zlib/tests/bug_52944.phpt b/ext/zlib/tests/bug_52944.phpt index ff82d29cc7..68bd53791d 100644 --- a/ext/zlib/tests/bug_52944.phpt +++ b/ext/zlib/tests/bug_52944.phpt @@ -2,10 +2,6 @@ Bug #52944 (segfault with zlib filter and corrupted data) --SKIPIF-- <?php if (!extension_loaded("zlib")) print "skip"; ?> -<?php -if (PHP_OS == 'Darwin') { - die("skip not for Darwin"); -} --INI-- allow_url_fopen=1 --FILE-- |