From a07c1f56aac1c0f6c8334760009b678cbf9d6138 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Wed, 2 Sep 2020 10:13:42 +0200 Subject: [PATCH 01/87] Fix infinite loop on string offset during by-ref list assign There is a deeper underlying issue here, in that the opcodes violate VM write-fetch safety, but let's fix the infinite loop first. This fixes oss-fuzz #25352. --- .../list_assign_ref_string_offset_error.phpt | 16 ++++++++++++++++ Zend/zend_execute.c | 1 + 2 files changed, 17 insertions(+) create mode 100644 Zend/tests/list_assign_ref_string_offset_error.phpt diff --git a/Zend/tests/list_assign_ref_string_offset_error.phpt b/Zend/tests/list_assign_ref_string_offset_error.phpt new file mode 100644 index 0000000000000..c4e99d01a2f94 --- /dev/null +++ b/Zend/tests/list_assign_ref_string_offset_error.phpt @@ -0,0 +1,16 @@ +--TEST-- +String offset error during list() by-ref assignment +--FILE-- + +--EXPECTF-- +Fatal error: Uncaught Error: Cannot create references to/from string offsets in %s:%d +Stack trace: +#0 {main} + thrown in %s on line %d diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 0eb6639b2e428..9a891273bc602 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -1329,6 +1329,7 @@ static zend_never_inline ZEND_COLD void zend_wrong_string_offset(EXECUTE_DATA_D) msg = "Cannot create references to/from string offsets"; break; } + opline++; } break; EMPTY_SWITCH_DEFAULT_CASE(); From 8b6b2bda093b26640d0d1d640e4566684df88011 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Wed, 2 Sep 2020 10:23:44 +0200 Subject: [PATCH 02/87] Fix by-ref list assign LIST_W+MAKE_REF separation Shift the responsibility for emitting MAKE_REF to the list assignment code, to make sure that LIST_W and MAKE_REF are directly adjacent, and there are no opcodes in between that could modify the LIST_W result. Additionally, adjust the zend_wrong_string_offset() code to not perform a loop over opcodes and assert that the next opcode is a relevant one. The VM write-safety model requires this. This is a followup to a07c1f56aac1c0f6c8334760009b678cbf9d6138 and the full fix for oss-fuzz #25352. --- Zend/zend_compile.c | 7 ++- Zend/zend_execute.c | 140 +++++++++++++++++++++----------------------- 2 files changed, 72 insertions(+), 75 deletions(-) diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 190e7e49d843a..8d76148fc2a33 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -2984,10 +2984,10 @@ static void zend_compile_list_assign( zend_handle_numeric_dim(opline, &dim_node); } + if (elem_ast->attr) { + zend_emit_op(&fetch_result, ZEND_MAKE_REF, &fetch_result, NULL); + } if (var_ast->kind == ZEND_AST_ARRAY) { - if (elem_ast->attr) { - zend_emit_op(&fetch_result, ZEND_MAKE_REF, &fetch_result, NULL); - } zend_compile_list_assign(NULL, var_ast, &fetch_result, var_ast->attr); } else if (elem_ast->attr) { zend_emit_assign_ref_znode(var_ast, &fetch_result); @@ -3180,6 +3180,7 @@ void zend_compile_assign_ref(znode *result, zend_ast *ast) /* {{{ */ if ((target_ast->kind != ZEND_AST_VAR || target_ast->child[0]->kind != ZEND_AST_ZVAL) + && source_ast->kind != ZEND_AST_ZNODE && source_node.op_type != IS_CV) { /* Both LHS and RHS expressions may modify the same data structure, * and the modification during RHS evaluation may dangle the pointer diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 52260e9f81cc7..6e66ba72d66cd 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -1374,7 +1374,6 @@ static zend_never_inline ZEND_COLD void zend_wrong_string_offset(EXECUTE_DATA_D) { const char *msg = NULL; const zend_op *opline = EX(opline); - const zend_op *end; uint32_t var; if (UNEXPECTED(EG(exception) != NULL)) { @@ -1396,78 +1395,75 @@ static zend_never_inline ZEND_COLD void zend_wrong_string_offset(EXECUTE_DATA_D) /* TODO: Encode the "reason" into opline->extended_value??? */ var = opline->result.var; opline++; - end = EG(current_execute_data)->func->op_array.opcodes + - EG(current_execute_data)->func->op_array.last; - while (opline < end) { - if (opline->op1_type == IS_VAR && opline->op1.var == var) { - switch (opline->opcode) { - case ZEND_FETCH_OBJ_W: - case ZEND_FETCH_OBJ_RW: - case ZEND_FETCH_OBJ_FUNC_ARG: - case ZEND_FETCH_OBJ_UNSET: - case ZEND_ASSIGN_OBJ: - case ZEND_ASSIGN_OBJ_OP: - case ZEND_ASSIGN_OBJ_REF: - msg = "Cannot use string offset as an object"; - break; - case ZEND_FETCH_DIM_W: - case ZEND_FETCH_DIM_RW: - case ZEND_FETCH_DIM_FUNC_ARG: - case ZEND_FETCH_DIM_UNSET: - case ZEND_FETCH_LIST_W: - case ZEND_ASSIGN_DIM: - case ZEND_ASSIGN_DIM_OP: - msg = "Cannot use string offset as an array"; - break; - case ZEND_ASSIGN_STATIC_PROP_OP: - case ZEND_ASSIGN_OP: - msg = "Cannot use assign-op operators with string offsets"; - break; - case ZEND_PRE_INC_OBJ: - case ZEND_PRE_DEC_OBJ: - case ZEND_POST_INC_OBJ: - case ZEND_POST_DEC_OBJ: - case ZEND_PRE_INC: - case ZEND_PRE_DEC: - case ZEND_POST_INC: - case ZEND_POST_DEC: - msg = "Cannot increment/decrement string offsets"; - break; - case ZEND_ASSIGN_REF: - case ZEND_ADD_ARRAY_ELEMENT: - case ZEND_INIT_ARRAY: - case ZEND_MAKE_REF: - msg = "Cannot create references to/from string offsets"; - break; - case ZEND_RETURN_BY_REF: - case ZEND_VERIFY_RETURN_TYPE: - msg = "Cannot return string offsets by reference"; - break; - case ZEND_UNSET_DIM: - case ZEND_UNSET_OBJ: - msg = "Cannot unset string offsets"; - break; - case ZEND_YIELD: - msg = "Cannot yield string offsets by reference"; - break; - case ZEND_SEND_REF: - case ZEND_SEND_VAR_EX: - case ZEND_SEND_FUNC_ARG: - msg = "Only variables can be passed by reference"; - break; - case ZEND_FE_RESET_RW: - msg = "Cannot iterate on string offsets by reference"; - break; - EMPTY_SWITCH_DEFAULT_CASE(); - } - break; - } - if (opline->op2_type == IS_VAR && opline->op2.var == var) { - ZEND_ASSERT(opline->opcode == ZEND_ASSIGN_REF); - msg = "Cannot create references to/from string offsets"; - break; + ZEND_ASSERT(opline < execute_data->func->op_array.opcodes + + execute_data->func->op_array.last); + if (opline->op1_type == IS_VAR && opline->op1.var == var) { + switch (opline->opcode) { + case ZEND_FETCH_OBJ_W: + case ZEND_FETCH_OBJ_RW: + case ZEND_FETCH_OBJ_FUNC_ARG: + case ZEND_FETCH_OBJ_UNSET: + case ZEND_ASSIGN_OBJ: + case ZEND_ASSIGN_OBJ_OP: + case ZEND_ASSIGN_OBJ_REF: + msg = "Cannot use string offset as an object"; + break; + case ZEND_FETCH_DIM_W: + case ZEND_FETCH_DIM_RW: + case ZEND_FETCH_DIM_FUNC_ARG: + case ZEND_FETCH_DIM_UNSET: + case ZEND_FETCH_LIST_W: + case ZEND_ASSIGN_DIM: + case ZEND_ASSIGN_DIM_OP: + msg = "Cannot use string offset as an array"; + break; + case ZEND_ASSIGN_STATIC_PROP_OP: + case ZEND_ASSIGN_OP: + msg = "Cannot use assign-op operators with string offsets"; + break; + case ZEND_PRE_INC_OBJ: + case ZEND_PRE_DEC_OBJ: + case ZEND_POST_INC_OBJ: + case ZEND_POST_DEC_OBJ: + case ZEND_PRE_INC: + case ZEND_PRE_DEC: + case ZEND_POST_INC: + case ZEND_POST_DEC: + msg = "Cannot increment/decrement string offsets"; + break; + case ZEND_ASSIGN_REF: + case ZEND_ADD_ARRAY_ELEMENT: + case ZEND_INIT_ARRAY: + case ZEND_MAKE_REF: + msg = "Cannot create references to/from string offsets"; + break; + case ZEND_RETURN_BY_REF: + case ZEND_VERIFY_RETURN_TYPE: + msg = "Cannot return string offsets by reference"; + break; + case ZEND_UNSET_DIM: + case ZEND_UNSET_OBJ: + msg = "Cannot unset string offsets"; + break; + case ZEND_YIELD: + msg = "Cannot yield string offsets by reference"; + break; + case ZEND_SEND_REF: + case ZEND_SEND_VAR_EX: + case ZEND_SEND_FUNC_ARG: + msg = "Only variables can be passed by reference"; + break; + case ZEND_FE_RESET_RW: + msg = "Cannot iterate on string offsets by reference"; + break; + EMPTY_SWITCH_DEFAULT_CASE(); } - opline++; + break; + } + if (opline->op2_type == IS_VAR && opline->op2.var == var) { + ZEND_ASSERT(opline->opcode == ZEND_ASSIGN_REF); + msg = "Cannot create references to/from string offsets"; + break; } break; EMPTY_SWITCH_DEFAULT_CASE(); From c98e1747a8cd7d02bfaf76391ebef5d0b4d60c53 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Wed, 2 Sep 2020 11:49:42 +0300 Subject: [PATCH 03/87] Minimal JIT support for JMP_NULL --- ext/opcache/jit/zend_jit.c | 5 +---- ext/opcache/jit/zend_jit_trace.c | 2 ++ ext/opcache/jit/zend_jit_x86.dasc | 3 +++ 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/ext/opcache/jit/zend_jit.c b/ext/opcache/jit/zend_jit.c index a89b21f875afa..7997110c82ffc 100644 --- a/ext/opcache/jit/zend_jit.c +++ b/ext/opcache/jit/zend_jit.c @@ -2972,8 +2972,6 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op goto jit_failure; } goto done; - case ZEND_JMP_NULL: - goto jit_failure; default: break; } @@ -3062,6 +3060,7 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op case ZEND_JMPNZ_EX: case ZEND_JMP_SET: case ZEND_COALESCE: + case ZEND_JMP_NULL: case ZEND_FE_RESET_R: case ZEND_FE_RESET_RW: case ZEND_ASSERT_CHECK: @@ -3112,8 +3111,6 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op } } break; - case ZEND_JMP_NULL: - goto jit_failure; default: if (!zend_jit_handler(&dasm_state, opline, zend_may_throw(opline, ssa_op, op_array, ssa))) { diff --git a/ext/opcache/jit/zend_jit_trace.c b/ext/opcache/jit/zend_jit_trace.c index 4b88a9d03ea90..3203339d028fa 100644 --- a/ext/opcache/jit/zend_jit_trace.c +++ b/ext/opcache/jit/zend_jit_trace.c @@ -280,6 +280,7 @@ static int zend_jit_trace_may_exit(const zend_op_array *op_array, const zend_op case ZEND_JMPNZ_EX: case ZEND_JMP_SET: case ZEND_COALESCE: + case ZEND_JMP_NULL: case ZEND_FE_RESET_R: case ZEND_FE_RESET_RW: case ZEND_ASSERT_CHECK: @@ -4638,6 +4639,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par || opline->opcode == ZEND_QM_ASSIGN || opline->opcode == ZEND_JMP_SET || opline->opcode == ZEND_COALESCE + || opline->opcode == ZEND_JMP_NULL || opline->opcode == ZEND_FE_RESET_R) { /* keep old value */ type = STACK_VAR_TYPE(opline->op1.var); diff --git a/ext/opcache/jit/zend_jit_x86.dasc b/ext/opcache/jit/zend_jit_x86.dasc index 39a8942a844c3..39fd42e263f6c 100644 --- a/ext/opcache/jit/zend_jit_x86.dasc +++ b/ext/opcache/jit/zend_jit_x86.dasc @@ -3329,6 +3329,7 @@ static int zend_jit_trace_handler(dasm_State **Dst, const zend_op_array *op_arra case ZEND_JMPNZ_EX: case ZEND_JMP_SET: case ZEND_COALESCE: + case ZEND_JMP_NULL: case ZEND_FE_RESET_R: case ZEND_FE_RESET_RW: exit_opline = (trace->opline == opline + 1) ? @@ -8335,6 +8336,7 @@ static int zend_jit_needs_call_chain(zend_call_info *call_info, uint32_t b, cons case ZEND_FE_RESET_RW: case ZEND_JMP_SET: case ZEND_COALESCE: + case ZEND_JMP_NULL: case ZEND_ASSERT_CHECK: case ZEND_CATCH: case ZEND_DECLARE_ANON_CLASS: @@ -8416,6 +8418,7 @@ static int zend_jit_needs_call_chain(zend_call_info *call_info, uint32_t b, cons case ZEND_FE_RESET_RW: case ZEND_JMP_SET: case ZEND_COALESCE: + case ZEND_JMP_NULL: case ZEND_ASSERT_CHECK: case ZEND_CATCH: case ZEND_DECLARE_ANON_CLASS: From 2e9e706a8271bbb42ad696c3383912facdd7d45f Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Wed, 2 Sep 2020 10:50:14 +0200 Subject: [PATCH 04/87] Fix throwing of yield from related exceptions into generator Use the general zend_generator_throw_exception() helper for this. Otherwise we don't handle the off-by-one opline correctly (should we maybe just stop doing that?) This is a followup to ad750c3bb6e7b48384c6265eb9d3bcf5b4000652, which fixed a different yield from exception handling problem that happened to show up in the same test case from oss-fuzz #25321. Now both issues should be fixed. --- Zend/tests/generators/yield_from_valid_exception.phpt | 3 ++- Zend/zend_generators.c | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Zend/tests/generators/yield_from_valid_exception.phpt b/Zend/tests/generators/yield_from_valid_exception.phpt index 3af35f53af668..d3e054bfafb9d 100644 --- a/Zend/tests/generators/yield_from_valid_exception.phpt +++ b/Zend/tests/generators/yield_from_valid_exception.phpt @@ -15,7 +15,8 @@ class FooBar implements Iterator { function gen() { try { - yield from new FooBar; + // the fact that the yield from result is used is relevant. + var_dump(yield from new FooBar); } catch (Exception $e) { echo $e->getMessage(), "\n"; } diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c index bb3260b11bfff..0ed92f4ca28cb 100644 --- a/Zend/zend_generators.c +++ b/Zend/zend_generators.c @@ -740,7 +740,7 @@ static int zend_generator_get_next_delegated_value(zend_generator *generator) /* return SUCCESS; exception: - zend_rethrow_exception(generator->execute_data); + zend_generator_throw_exception(generator, NULL); failure: zval_ptr_dtor(&generator->values); From 3e800e997bddc29cd28924c44846f7d2133a8933 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1t=C3=A9=20Kocsis?= Date: Mon, 24 Aug 2020 20:42:29 +0200 Subject: [PATCH 05/87] Move custom type checks to ZPP Closes GH-6034 --- Zend/zend_operators.c | 2 +- ext/mbstring/mbstring.c | 30 ++++----- ext/mbstring/mbstring.stub.php | 3 +- ext/mbstring/mbstring_arginfo.h | 4 +- ext/oci8/oci8.stub.php | 2 +- ext/oci8/oci8_arginfo.h | 2 +- ext/odbc/odbc.stub.php | 7 +-- ext/odbc/odbc_arginfo.h | 4 +- ext/odbc/php_odbc.c | 24 ++++---- ext/xml/tests/bug72714.phpt | 2 +- .../xml_parser_set_option_variation3.phpt | 6 +- ext/xml/xml.c | 3 +- ext/xsl/php_xsl.stub.php | 14 ++--- ext/xsl/php_xsl_arginfo.h | 8 +-- .../xsltprocessor_setparameter-nostring.phpt | 17 +++--- ext/xsl/xsltprocessor.c | 39 ++++++++---- ext/zip/php_zip.c | 61 +++++++++---------- ext/zip/php_zip.stub.php | 7 +-- ext/zip/php_zip_arginfo.h | 4 +- 19 files changed, 117 insertions(+), 122 deletions(-) diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c index 4d20d564648a2..e126f784cfead 100644 --- a/Zend/zend_operators.c +++ b/Zend/zend_operators.c @@ -816,7 +816,7 @@ ZEND_API zend_long ZEND_FASTCALL zval_get_long_func(zval *op) /* {{{ */ } else { /* Previously we used strtol here, not is_numeric_string, * and strtol gives you LONG_MAX/_MIN on overflow. - * We use use saturating conversion to emulate strtol()'s + * We use saturating conversion to emulate strtol()'s * behaviour. */ return zend_dval_to_lval_cap(dval); diff --git a/ext/mbstring/mbstring.c b/ext/mbstring/mbstring.c index 1fba2db34c0a5..13031d90d3e39 100644 --- a/ext/mbstring/mbstring.c +++ b/ext/mbstring/mbstring.c @@ -3513,8 +3513,8 @@ PHP_FUNCTION(mb_send_mail) size_t message_len; char *subject; size_t subject_len; - zval *headers = NULL; zend_string *extra_cmd = NULL; + HashTable *headers_ht = NULL; zend_string *str_headers = NULL, *tmp_headers; size_t n, i; char *to_r = NULL; @@ -3560,30 +3560,24 @@ PHP_FUNCTION(mb_send_mail) Z_PARAM_STRING(subject, subject_len) Z_PARAM_STRING(message, message_len) Z_PARAM_OPTIONAL - Z_PARAM_ZVAL(headers) - Z_PARAM_STR(extra_cmd) + Z_PARAM_STR_OR_ARRAY_HT_OR_NULL(str_headers, headers_ht) + Z_PARAM_STR_OR_NULL(extra_cmd) ZEND_PARSE_PARAMETERS_END(); /* ASCIIZ check */ MAIL_ASCIIZ_CHECK_MBSTRING(to, to_len); MAIL_ASCIIZ_CHECK_MBSTRING(subject, subject_len); MAIL_ASCIIZ_CHECK_MBSTRING(message, message_len); - if (headers) { - switch(Z_TYPE_P(headers)) { - case IS_STRING: - tmp_headers = zend_string_init(Z_STRVAL_P(headers), Z_STRLEN_P(headers), 0); - MAIL_ASCIIZ_CHECK_MBSTRING(ZSTR_VAL(tmp_headers), ZSTR_LEN(tmp_headers)); - str_headers = php_trim(tmp_headers, NULL, 0, 2); - zend_string_release_ex(tmp_headers, 0); - break; - case IS_ARRAY: - str_headers = php_mail_build_headers(Z_ARRVAL_P(headers)); - break; - default: - zend_argument_value_error(4, "must be of type string|array|null, %s given", zend_zval_type_name(headers)); - RETURN_THROWS(); - } + + if (str_headers) { + tmp_headers = zend_string_init(ZSTR_VAL(str_headers), ZSTR_LEN(str_headers), 0); + MAIL_ASCIIZ_CHECK_MBSTRING(ZSTR_VAL(tmp_headers), ZSTR_LEN(tmp_headers)); + str_headers = php_trim(tmp_headers, NULL, 0, 2); + zend_string_release_ex(tmp_headers, 0); + } else if (headers_ht) { + str_headers = php_mail_build_headers(headers_ht); } + if (extra_cmd) { MAIL_ASCIIZ_CHECK_MBSTRING(ZSTR_VAL(extra_cmd), ZSTR_LEN(extra_cmd)); } diff --git a/ext/mbstring/mbstring.stub.php b/ext/mbstring/mbstring.stub.php index 343a5d103d136..d089c24c194cb 100644 --- a/ext/mbstring/mbstring.stub.php +++ b/ext/mbstring/mbstring.stub.php @@ -77,8 +77,7 @@ function mb_encode_numericentity(string $string, array $convmap, ?string $encodi function mb_decode_numericentity(string $string, array $convmap, ?string $encoding = null): string {} -/** @param string|array|null $additional_headers */ -function mb_send_mail(string $to, string $subject, string $message, $additional_headers = null, ?string $additional_parameters = null): bool {} +function mb_send_mail(string $to, string $subject, string $message, array|string|null $additional_headers = null, ?string $additional_parameters = null): bool {} function mb_get_info(string $type = "all"): array|string|int|false {} diff --git a/ext/mbstring/mbstring_arginfo.h b/ext/mbstring/mbstring_arginfo.h index 7267b943ef06e..873a0c86a45cc 100644 --- a/ext/mbstring/mbstring_arginfo.h +++ b/ext/mbstring/mbstring_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 5ad8a8cf20eeae59713d19135ecccbee243754eb */ + * Stub hash: 84096daa0fd395f57401f11e9e79f7c8420e8a93 */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_mb_language, 0, 0, MAY_BE_STRING|MAY_BE_BOOL) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, language, IS_STRING, 1, "null") @@ -178,7 +178,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_mb_send_mail, 0, 3, _IS_BOOL, 0) ZEND_ARG_TYPE_INFO(0, to, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, subject, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, message, IS_STRING, 0) - ZEND_ARG_INFO_WITH_DEFAULT_VALUE(0, additional_headers, "null") + ZEND_ARG_TYPE_MASK(0, additional_headers, MAY_BE_ARRAY|MAY_BE_STRING|MAY_BE_NULL, "null") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, additional_parameters, IS_STRING, 1, "null") ZEND_END_ARG_INFO() diff --git a/ext/oci8/oci8.stub.php b/ext/oci8/oci8.stub.php index 5c964c16f828c..7a17430dc0aea 100644 --- a/ext/oci8/oci8.stub.php +++ b/ext/oci8/oci8.stub.php @@ -266,7 +266,7 @@ function oci_fetch_all($statement_resource, &$output, int $skip = 0, int $maximu /** * @param resource $statement_resource - * @param mixed $output + * @param array $output * @alias oci_fetch_all * @deprecated */ diff --git a/ext/oci8/oci8_arginfo.h b/ext/oci8/oci8_arginfo.h index 77638aa9a0e67..729ac02240444 100644 --- a/ext/oci8/oci8_arginfo.h +++ b/ext/oci8/oci8_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: a5a245b354b48a56c274c8f74c974d92ec430853 */ + * Stub hash: 447880a4bc4add36beab835cc07c09a254dc0c2b */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_oci_define_by_name, 0, 3, _IS_BOOL, 0) ZEND_ARG_INFO(0, statement_resource) diff --git a/ext/odbc/odbc.stub.php b/ext/odbc/odbc.stub.php index 89371024eb9cf..cb318f7ac9d4f 100644 --- a/ext/odbc/odbc.stub.php +++ b/ext/odbc/odbc.stub.php @@ -57,11 +57,8 @@ function odbc_fetch_into($result_id, &$result_array, int $rownumber = 0): int|fa /** @param resource $result_id */ function odbc_fetch_row($result_id, int $row_number = UNKNOWN): bool {} -/** - * @param resource $result_id - * @param string|int $field - */ -function odbc_result($result_id, $field): string|bool|null {} +/** @param resource $result_id */ +function odbc_result($result_id, string|int $field): string|bool|null {} /** @param resource $result_id */ function odbc_result_all($result_id, string $format = ''): int|false {} diff --git a/ext/odbc/odbc_arginfo.h b/ext/odbc/odbc_arginfo.h index 2f5ffbe547af0..778ab242a0b10 100644 --- a/ext/odbc/odbc_arginfo.h +++ b/ext/odbc/odbc_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 14702a5bd87902871d456de2289f4ae236e5bfa5 */ + * Stub hash: cf17952d8c3b88f218bbb8d1c21ba40079574c04 */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_odbc_close_all, 0, 0, IS_VOID, 0) ZEND_END_ARG_INFO() @@ -70,7 +70,7 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_odbc_result, 0, 2, MAY_BE_STRING|MAY_BE_BOOL|MAY_BE_NULL) ZEND_ARG_INFO(0, result_id) - ZEND_ARG_INFO(0, field) + ZEND_ARG_TYPE_MASK(0, field, MAY_BE_STRING|MAY_BE_LONG, NULL) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_odbc_result_all, 0, 1, MAY_BE_LONG|MAY_BE_FALSE) diff --git a/ext/odbc/php_odbc.c b/ext/odbc/php_odbc.c index 7a4495f0d1f3b..af62ecb29dada 100644 --- a/ext/odbc/php_odbc.c +++ b/ext/odbc/php_odbc.c @@ -1736,31 +1736,31 @@ PHP_FUNCTION(odbc_fetch_row) PHP_FUNCTION(odbc_result) { char *field; - zend_string *field_str; + zend_string *field_str, *pv_field_str; + zend_long pv_field_long; int field_ind; SQLSMALLINT sql_c_type = SQL_C_CHAR; odbc_result *result; int i = 0; RETCODE rc; SQLLEN fieldsize; - zval *pv_res, *pv_field; + zval *pv_res; #ifdef HAVE_SQL_EXTENDED_FETCH SQLULEN crow; SQLUSMALLINT RowStatus[1]; #endif - field_ind = -1; - field = NULL; - - if (zend_parse_parameters(ZEND_NUM_ARGS(), "rz", &pv_res, &pv_field) == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_START(2, 2) + Z_PARAM_RESOURCE(pv_res) + Z_PARAM_STR_OR_LONG(pv_field_str, pv_field_long) + ZEND_PARSE_PARAMETERS_END(); - if (Z_TYPE_P(pv_field) == IS_STRING) { - field = Z_STRVAL_P(pv_field); + if (pv_field_str) { + field = ZSTR_VAL(pv_field_str); + field_ind = -1; } else { - convert_to_long_ex(pv_field); - field_ind = Z_LVAL_P(pv_field) - 1; + field = NULL; + field_ind = (int) pv_field_long - 1; } if ((result = (odbc_result *)zend_fetch_resource(Z_RES_P(pv_res), "ODBC result", le_result)) == NULL) { diff --git a/ext/xml/tests/bug72714.phpt b/ext/xml/tests/bug72714.phpt index 53b923904534d..08fff0c06b16b 100644 --- a/ext/xml/tests/bug72714.phpt +++ b/ext/xml/tests/bug72714.phpt @@ -28,6 +28,6 @@ parse(3015809298423721); parse(20); ?> --EXPECTF-- -Notice: xml_parser_set_option(): tagstart ignored, because it is out of range in %s%ebug72714.php on line %d +Warning: xml_parser_set_option(): tagstart ignored, because it is out of range in %s on line %d string(9) "NS1:TOTAL" string(0) "" diff --git a/ext/xml/tests/xml_parser_set_option_variation3.phpt b/ext/xml/tests/xml_parser_set_option_variation3.phpt index b9d4b945e7112..592c9f52e80bc 100644 --- a/ext/xml/tests/xml_parser_set_option_variation3.phpt +++ b/ext/xml/tests/xml_parser_set_option_variation3.phpt @@ -77,9 +77,9 @@ $values = array( // loop through each element of the array for value foreach($values as $value) { - echo @"\nArg value $value \n"; - var_dump( xml_parser_set_option($parser, $option, $value) ); -}; + echo @"\nArg value $value \n"; + var_dump(xml_parser_set_option($parser, $option, $value)); +} fclose($fp); xml_parser_free($parser); diff --git a/ext/xml/xml.c b/ext/xml/xml.c index c670c2ef52e12..00f8798ad0875 100644 --- a/ext/xml/xml.c +++ b/ext/xml/xml.c @@ -1427,7 +1427,7 @@ PHP_FUNCTION(xml_parser_set_option) case PHP_XML_OPTION_SKIP_TAGSTART: parser->toffset = zval_get_long(val); if (parser->toffset < 0) { - php_error_docref(NULL, E_NOTICE, "tagstart ignored, because it is out of range"); + php_error_docref(NULL, E_WARNING, "tagstart ignored, because it is out of range"); parser->toffset = 0; } break; @@ -1445,6 +1445,7 @@ PHP_FUNCTION(xml_parser_set_option) zend_argument_value_error(3, "is not a supported target encoding"); RETURN_THROWS(); } + parser->target_encoding = enc->name; break; } diff --git a/ext/xsl/php_xsl.stub.php b/ext/xsl/php_xsl.stub.php index 9e79c9c63489c..04cad46cbe8cc 100644 --- a/ext/xsl/php_xsl.stub.php +++ b/ext/xsl/php_xsl.stub.php @@ -25,11 +25,8 @@ public function transformToUri(object $document, string $uri) {} */ public function transformToXml(object $document) {} - /** - * @param string|array $name - * @return bool - */ - public function setParameter(string $namespace, $name, string $value = UNKNOWN) {} + /** @return bool */ + public function setParameter(string $namespace, array|string $name, ?string $value = null) {} /** @return string|false */ public function getParameter(string $namespace, string $name) {} @@ -40,11 +37,8 @@ public function removeParameter(string $namespace, string $name) {} /** @return bool */ public function hasExsltSupport() {} - /** - * @param string|array|null $restrict - * @return void - */ - public function registerPHPFunctions($restrict = null) {} + /** @return void */ + public function registerPHPFunctions(array|string|null $restrict = null) {} /** @return bool */ public function setProfiling(?string $filename) {} diff --git a/ext/xsl/php_xsl_arginfo.h b/ext/xsl/php_xsl_arginfo.h index d707c72a7dba6..a776dded68695 100644 --- a/ext/xsl/php_xsl_arginfo.h +++ b/ext/xsl/php_xsl_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 13fd80938fec3bea7ac4bbcfb6e0b69b230fba72 */ + * Stub hash: 4a3997bafb6c17714ee94443837be2d2842386e2 */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_XSLTProcessor_importStylesheet, 0, 0, 1) ZEND_ARG_TYPE_INFO(0, stylesheet, IS_OBJECT, 0) @@ -21,8 +21,8 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_class_XSLTProcessor_setParameter, 0, 0, 2) ZEND_ARG_TYPE_INFO(0, namespace, IS_STRING, 0) - ZEND_ARG_INFO(0, name) - ZEND_ARG_TYPE_INFO(0, value, IS_STRING, 0) + ZEND_ARG_TYPE_MASK(0, name, MAY_BE_ARRAY|MAY_BE_STRING, NULL) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, value, IS_STRING, 1, "null") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_class_XSLTProcessor_getParameter, 0, 0, 2) @@ -36,7 +36,7 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_XSLTProcessor_hasExsltSupport, 0, 0, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_class_XSLTProcessor_registerPHPFunctions, 0, 0, 0) - ZEND_ARG_INFO_WITH_DEFAULT_VALUE(0, restrict, "null") + ZEND_ARG_TYPE_MASK(0, restrict, MAY_BE_ARRAY|MAY_BE_STRING|MAY_BE_NULL, "null") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_class_XSLTProcessor_setProfiling, 0, 0, 1) diff --git a/ext/xsl/tests/xsltprocessor_setparameter-nostring.phpt b/ext/xsl/tests/xsltprocessor_setparameter-nostring.phpt index 87d186eb6fd0a..d39c6559a1a62 100644 --- a/ext/xsl/tests/xsltprocessor_setparameter-nostring.phpt +++ b/ext/xsl/tests/xsltprocessor_setparameter-nostring.phpt @@ -4,20 +4,23 @@ Check xsltprocessor::setparameter error handling with no-string Memleak: http://bugs.php.net/bug.php?id=48221 --SKIPIF-- --FILE-- importStylesheet($xsl); -var_dump($proc->setParameter('', array(4, 'abc'))); +try { + $proc->setParameter('', array(4, 'abc')); +} catch (TypeError $exception) { + echo $exception->getMessage() . "\n"; +} $proc->transformToXml($dom); ?> ---EXPECTF-- -Warning: XSLTProcessor::setParameter(): Invalid parameter array in %s on line %d -bool(false) +--EXPECT-- +XSLTProcessor::setParameter(): Argument #2 ($name) must contain only string keys --CREDITS-- Christian Weiske, cweiske@php.net PHP Testfest Berlin 2009-05-09 diff --git a/ext/xsl/xsltprocessor.c b/ext/xsl/xsltprocessor.c index 29b3ff5fb34e2..26edbb9045668 100644 --- a/ext/xsl/xsltprocessor.c +++ b/ext/xsl/xsltprocessor.c @@ -666,21 +666,35 @@ PHP_METHOD(XSLTProcessor, setParameter) { zval *id = ZEND_THIS; - zval *array_value, *entry, new_string; + zval *entry, new_string; + HashTable *array_value; xsl_object *intern; char *namespace; size_t namespace_len; - zend_string *string_key, *name, *value; + zend_string *string_key, *name, *value = NULL; + + ZEND_PARSE_PARAMETERS_START(2, 3) + Z_PARAM_STRING(namespace, namespace_len) + Z_PARAM_STR_OR_ARRAY_HT(name, array_value) + Z_PARAM_OPTIONAL + Z_PARAM_STR_OR_NULL(value) + ZEND_PARSE_PARAMETERS_END(); + + intern = Z_XSL_P(id); + + if (array_value) { + if (value) { + zend_argument_value_error(3, "must be null when argument #2 ($name) is an array"); + RETURN_THROWS(); + } - if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "sa", &namespace, &namespace_len, &array_value) == SUCCESS) { - intern = Z_XSL_P(id); - ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(array_value), string_key, entry) { + ZEND_HASH_FOREACH_STR_KEY_VAL(array_value, string_key, entry) { zval tmp; zend_string *str; if (string_key == NULL) { - php_error_docref(NULL, E_WARNING, "Invalid parameter array"); - RETURN_FALSE; + zend_argument_type_error(2, "must contain only string keys"); + RETURN_THROWS(); } str = zval_try_get_string(entry); if (UNEXPECTED(!str)) { @@ -690,18 +704,17 @@ PHP_METHOD(XSLTProcessor, setParameter) zend_hash_update(intern->parameter, string_key, &tmp); } ZEND_HASH_FOREACH_END(); RETURN_TRUE; - } else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "sSS", &namespace, &namespace_len, &name, &value) == SUCCESS) { - - intern = Z_XSL_P(id); + } else { + if (!value) { + zend_argument_value_error(3, "cannot be null when argument #2 ($name) is a string"); + RETURN_THROWS(); + } ZVAL_STR_COPY(&new_string, value); zend_hash_update(intern->parameter, name, &new_string); RETURN_TRUE; - } else { - WRONG_PARAM_COUNT; } - } /* }}} end XSLTProcessor::setParameter */ diff --git a/ext/zip/php_zip.c b/ext/zip/php_zip.c index c1a569afec4a7..6ebbc42858da1 100644 --- a/ext/zip/php_zip.c +++ b/ext/zip/php_zip.c @@ -2712,16 +2712,20 @@ PHP_METHOD(ZipArchive, extractTo) struct zip *intern; zval *self = ZEND_THIS; - zval *zval_files = NULL; + zend_string *files_str = NULL; + HashTable *files_ht = NULL; + zval *zval_file = NULL; php_stream_statbuf ssb; char *pathto; size_t pathto_len; int ret; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "p|z", &pathto, &pathto_len, &zval_files) == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_START(1, 2) + Z_PARAM_PATH(pathto, pathto_len) + Z_PARAM_OPTIONAL + Z_PARAM_STR_OR_ARRAY_HT_OR_NULL(files_str, files_ht) + ZEND_PARSE_PARAMETERS_END(); ZIP_FROM_OBJECT(intern, self); @@ -2736,37 +2740,29 @@ PHP_METHOD(ZipArchive, extractTo) } } - if (zval_files && Z_TYPE_P(zval_files) != IS_NULL) { - uint32_t nelems, i; + uint32_t nelems, i; - switch (Z_TYPE_P(zval_files)) { - case IS_STRING: - if (!php_zip_extract_file(intern, pathto, Z_STRVAL_P(zval_files), Z_STRLEN_P(zval_files))) { - RETURN_FALSE; - } - break; - case IS_ARRAY: - nelems = zend_hash_num_elements(Z_ARRVAL_P(zval_files)); - if (nelems == 0 ) { - RETURN_FALSE; - } - for (i = 0; i < nelems; i++) { - if ((zval_file = zend_hash_index_find(Z_ARRVAL_P(zval_files), i)) != NULL) { - switch (Z_TYPE_P(zval_file)) { - case IS_LONG: - break; - case IS_STRING: - if (!php_zip_extract_file(intern, pathto, Z_STRVAL_P(zval_file), Z_STRLEN_P(zval_file))) { - RETURN_FALSE; - } - break; + if (files_str) { + if (!php_zip_extract_file(intern, pathto, ZSTR_VAL(files_str), ZSTR_LEN(files_str))) { + RETURN_FALSE; + } + } else if (files_ht) { + nelems = zend_hash_num_elements(files_ht); + if (nelems == 0 ) { + RETURN_FALSE; + } + for (i = 0; i < nelems; i++) { + if ((zval_file = zend_hash_index_find(files_ht, i)) != NULL) { + switch (Z_TYPE_P(zval_file)) { + case IS_LONG: + break; + case IS_STRING: + if (!php_zip_extract_file(intern, pathto, Z_STRVAL_P(zval_file), Z_STRLEN_P(zval_file))) { + RETURN_FALSE; } - } + break; } - break; - default: - zend_argument_type_error(2, "must be of type array|string|null, %s given", zend_zval_type_name(zval_files)); - RETURN_THROWS(); + } } } else { /* Extract all files */ @@ -2784,6 +2780,7 @@ PHP_METHOD(ZipArchive, extractTo) } } } + RETURN_TRUE; } /* }}} */ diff --git a/ext/zip/php_zip.stub.php b/ext/zip/php_zip.stub.php index 01f055f0ab4ba..cde266261d640 100644 --- a/ext/zip/php_zip.stub.php +++ b/ext/zip/php_zip.stub.php @@ -161,11 +161,8 @@ public function unchangeIndex(int $index) {} /** @return bool */ public function unchangeName(string $name) {} - /** - * @param array|string|null $files - * @return bool - */ - public function extractTo(string $pathto, $files = null) {} + /** @return bool */ + public function extractTo(string $pathto, array|string|null $files = null) {} /** @return string|false */ public function getFromName(string $entryname, int $len = 0, int $flags = 0) {} diff --git a/ext/zip/php_zip_arginfo.h b/ext/zip/php_zip_arginfo.h index 87222c9e08075..c9f90d57f9873 100644 --- a/ext/zip/php_zip_arginfo.h +++ b/ext/zip/php_zip_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 880148896a71ad9bd076bb42c735ff1b83cd0731 */ + * Stub hash: 49f168c537e48f8a3998d67812a5e2e6a2463533 */ ZEND_BEGIN_ARG_INFO_EX(arginfo_zip_open, 0, 0, 1) ZEND_ARG_TYPE_INFO(0, filename, IS_STRING, 0) @@ -175,7 +175,7 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_class_ZipArchive_extractTo, 0, 0, 1) ZEND_ARG_TYPE_INFO(0, pathto, IS_STRING, 0) - ZEND_ARG_INFO_WITH_DEFAULT_VALUE(0, files, "null") + ZEND_ARG_TYPE_MASK(0, files, MAY_BE_ARRAY|MAY_BE_STRING|MAY_BE_NULL, "null") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_class_ZipArchive_getFromName, 0, 0, 1) From 225cd9da865ea66d49f24d5c8f98bdf05efa0592 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Wed, 2 Sep 2020 12:55:16 +0300 Subject: [PATCH 06/87] Improved JIT for VERIFY_RETURN_TYPE --- ext/opcache/jit/zend_jit_trace.c | 38 +++++++++++ ext/opcache/jit/zend_jit_x86.dasc | 101 +++++++++++++++++------------- 2 files changed, 97 insertions(+), 42 deletions(-) diff --git a/ext/opcache/jit/zend_jit_trace.c b/ext/opcache/jit/zend_jit_trace.c index 3203339d028fa..c3c7dbab225f8 100644 --- a/ext/opcache/jit/zend_jit_trace.c +++ b/ext/opcache/jit/zend_jit_trace.c @@ -1447,6 +1447,21 @@ static zend_ssa *zend_jit_trace_build_tssa(zend_jit_trace_rec *trace_buffer, uin case ZEND_QM_ASSIGN: ADD_OP1_TRACE_GUARD(); break; + case ZEND_VERIFY_RETURN_TYPE: + if (opline->op1_type == IS_UNUSED) { + /* Always throws */ + break; + } + if (opline->op1_type == IS_CONST) { + /* TODO Different instruction format, has return value */ + break; + } + if (op_array->fn_flags & ZEND_ACC_RETURN_REFERENCE) { + /* Not worth bothering with */ + break; + } + ADD_OP1_TRACE_GUARD(); + break; case ZEND_FETCH_DIM_FUNC_ARG: if (!frame || !frame->call @@ -4502,6 +4517,29 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par goto jit_failure; } goto done; + case ZEND_VERIFY_RETURN_TYPE: + if (opline->op1_type == IS_UNUSED) { + /* Always throws */ + break; + } + if (opline->op1_type == IS_CONST) { + /* TODO Different instruction format, has return value */ + break; + } + if (op_array->fn_flags & ZEND_ACC_RETURN_REFERENCE) { + /* Not worth bothering with */ + break; + } + op1_info = OP1_INFO(); + CHECK_OP1_TRACE_TYPE(); + if (op1_info & MAY_BE_REF) { + /* TODO May need reference unwrapping. */ + break; + } + if (!zend_jit_verify_return_type(&dasm_state, opline, op_array, op1_info)) { + goto jit_failure; + } + goto done; case ZEND_INIT_METHOD_CALL: case ZEND_INIT_DYNAMIC_CALL: if (!zend_jit_trace_handler(&dasm_state, op_array, opline, zend_may_throw(opline, ssa_op, op_array, ssa), p + 1)) { diff --git a/ext/opcache/jit/zend_jit_x86.dasc b/ext/opcache/jit/zend_jit_x86.dasc index 39fd42e263f6c..09cea053544ff 100644 --- a/ext/opcache/jit/zend_jit_x86.dasc +++ b/ext/opcache/jit/zend_jit_x86.dasc @@ -483,6 +483,11 @@ static void* dasm_labels[zend_lb_MAX]; | mov dword [zv+offsetof(zval,u1.type_info)], type |.endmacro +|.macro GET_ZVAL_TYPE, reg, addr +|| ZEND_ASSERT(Z_MODE(addr) == IS_MEM_ZVAL); +| mov reg, byte [Ra(Z_REG(addr))+Z_OFFSET(addr)+offsetof(zval,u1.v.type)] +|.endmacro + |.macro GET_ZVAL_TYPE_INFO, reg, addr || ZEND_ASSERT(Z_MODE(addr) == IS_MEM_ZVAL); | mov reg, dword [Ra(Z_REG(addr))+Z_OFFSET(addr)+offsetof(zval,u1.type_info)] @@ -12393,53 +12398,65 @@ static zend_bool zend_jit_verify_return_type(dasm_State **Dst, const zend_op *op zend_arg_info *arg_info = &op_array->arg_info[-1]; ZEND_ASSERT(ZEND_TYPE_IS_SET(arg_info->type)); zend_jit_addr op1_addr = OP1_ADDR(); - - | LOAD_ZVAL_ADDR r0, op1_addr - + zend_bool needs_slow_check = 1; + zend_bool slow_check_in_cold = 1; uint32_t type_mask = ZEND_TYPE_PURE_MASK(arg_info->type) & MAY_BE_ANY; + if (type_mask == 0) { - | jmp >7 - } else if (is_power_of_two(type_mask)) { - uint32_t type_code = concrete_type(type_mask); - | cmp byte [r0 + 8], type_code - | jne >7 + slow_check_in_cold = 0; } else { - | mov edx, 1 - | mov cl, byte [r0 + 8] - | shl edx, cl - | test edx, type_mask - | je >7 - } - |.cold_code - |7: - | SAVE_VALID_OPLINE opline, r1 - if (op1_info & MAY_BE_UNDEF) { - | IF_NOT_ZVAL_TYPE op1_addr, IS_UNDEF, >8 - | mov FCARG1a, opline->op1.var - | EXT_CALL zend_jit_undefined_op_helper, FCARG2a - | LOAD_ADDR_ZTS r0, executor_globals, uninitialized_zval + if (((op1_info & MAY_BE_ANY) & type_mask) == 0) { + slow_check_in_cold = 0; + } else if (((op1_info & MAY_BE_ANY) | type_mask) == type_mask) { + needs_slow_check = 0; + } else if (is_power_of_two(type_mask)) { + uint32_t type_code = concrete_type(type_mask); + | IF_NOT_ZVAL_TYPE op1_addr, type_code, >7 + } else { + | mov edx, 1 + | GET_ZVAL_TYPE cl, op1_addr + | shl edx, cl + | test edx, type_mask + | je >7 + } } - |8: - | mov FCARG1a, r0 - | mov r0, EX->run_time_cache - | add r0, opline->op2.num - | mov FCARG2a, EX->func - |.if X64 - | LOAD_ADDR CARG3, (ptrdiff_t)arg_info - | mov CARG4, r0 - | EXT_CALL zend_jit_verify_return_slow, r0 - |.else - | sub r4, 8 - | push r0 - | push (ptrdiff_t)arg_info - | EXT_CALL zend_jit_verify_return_slow, r0 - | add r4, 8 - |.endif - if (!zend_jit_check_exception(Dst)) { - return 0; + if (needs_slow_check) { + if (slow_check_in_cold) { + |.cold_code + |7: + } + | SAVE_VALID_OPLINE opline, r1 + if (op1_info & MAY_BE_UNDEF) { + | IF_NOT_ZVAL_TYPE op1_addr, IS_UNDEF, >8 + | mov FCARG1a, opline->op1.var + | EXT_CALL zend_jit_undefined_op_helper, FCARG2a + | LOAD_ADDR_ZTS r0, executor_globals, uninitialized_zval + } + |8: + | LOAD_ZVAL_ADDR FCARG1a, op1_addr + | mov FCARG2a, EX->func + |.if X64 + | LOAD_ADDR CARG3, (ptrdiff_t)arg_info + | mov r0, EX->run_time_cache + | lea CARG4, aword [r0+opline->op2.num] + | EXT_CALL zend_jit_verify_return_slow, r0 + |.else + | sub r4, 8 + | mov r0, EX->run_time_cache + | add r0, opline->op2.num + | push r0 + | push (ptrdiff_t)arg_info + | EXT_CALL zend_jit_verify_return_slow, r0 + | add r4, 8 + |.endif + if (!zend_jit_check_exception(Dst)) { + return 0; + } + if (slow_check_in_cold) { + | jmp >9 + |.code + } } - | jmp >9 - |.code |9: return 1; } From 4d97ab20fc006ad639b6a5281cdd0123dcbb0abc Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Wed, 2 Sep 2020 12:59:52 +0300 Subject: [PATCH 07/87] Added missing helper --- ext/opcache/jit/zend_jit_disasm_x86.c | 1 + 1 file changed, 1 insertion(+) diff --git a/ext/opcache/jit/zend_jit_disasm_x86.c b/ext/opcache/jit/zend_jit_disasm_x86.c index 6124c947b2345..ce8eec6ebf2fe 100644 --- a/ext/opcache/jit/zend_jit_disasm_x86.c +++ b/ext/opcache/jit/zend_jit_disasm_x86.c @@ -428,6 +428,7 @@ static int zend_jit_disasm_init(void) REGISTER_HELPER(zend_jit_free_call_frame); REGISTER_HELPER(zend_jit_fetch_global_helper); REGISTER_HELPER(zend_jit_verify_arg_slow); + REGISTER_HELPER(zend_jit_verify_return_slow); REGISTER_HELPER(zend_jit_fetch_obj_r_slow); REGISTER_HELPER(zend_jit_fetch_obj_r_dynamic); REGISTER_HELPER(zend_jit_fetch_obj_is_slow); From cb284f668cbefa7b6dff726951c4473345e78bf9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Vo=C5=99=C3=AD=C5=A1ek?= Date: Wed, 2 Sep 2020 12:24:43 +0200 Subject: [PATCH 08/87] Fix typo in test description Closes GH-6062. --- ext/opcache/tests/jit/cmp_003.phpt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/opcache/tests/jit/cmp_003.phpt b/ext/opcache/tests/jit/cmp_003.phpt index 60698dea0403a..e7ed76a66ed3b 100644 --- a/ext/opcache/tests/jit/cmp_003.phpt +++ b/ext/opcache/tests/jit/cmp_003.phpt @@ -1,5 +1,5 @@ --TEST-- -JIT CMP: 003 Comparisoin with NaN +JIT CMP: 003 Comparison with NaN --INI-- opcache.enable=1 opcache.enable_cli=1 From c3299d7dab15aeed52a34535f1967d426f5327de Mon Sep 17 00:00:00 2001 From: Frank Du Date: Wed, 2 Sep 2020 10:53:29 +0000 Subject: [PATCH 09/87] X86: Fast CRC32 computation using PCLMULQDQ instruction Based on: "Fast CRC Computation for Generic Polynomials Using PCLMULQDQ Instruction" V. Gopal, E. Ozturk, et al., 2009, http://intel.ly/2ySEwL0 Signed-off-by: Frank Du Closes GH-6018 --- Zend/zend_cpuinfo.h | 15 ++ Zend/zend_portability.h | 56 +++++ configure.ac | 1 + ext/hash/hash_crc32.c | 25 +- ext/hash/tests/crc32.phpt | 86 ++++++- ext/standard/basic_functions.c | 5 + ext/standard/config.m4 | 2 +- ext/standard/config.w32 | 2 +- ext/standard/crc32.c | 9 +- ext/standard/crc32_x86.c | 349 ++++++++++++++++++++++++++ ext/standard/crc32_x86.h | 52 ++++ ext/standard/tests/strings/crc32.phpt | 28 +++ 12 files changed, 620 insertions(+), 10 deletions(-) create mode 100644 ext/standard/crc32_x86.c create mode 100644 ext/standard/crc32_x86.h diff --git a/Zend/zend_cpuinfo.h b/Zend/zend_cpuinfo.h index b8b08e7ad06ef..0baec57c23a88 100644 --- a/Zend/zend_cpuinfo.h +++ b/Zend/zend_cpuinfo.h @@ -159,6 +159,17 @@ static zend_always_inline int zend_cpu_supports_sse42() { return __builtin_cpu_supports("sse4.2"); } +/* __builtin_cpu_supports has pclmul from gcc9 */ +#if (!defined(__GNUC__) || (ZEND_GCC_VERSION >= 9000)) +ZEND_NO_SANITIZE_ADDRESS +static zend_always_inline int zend_cpu_supports_pclmul() { +#if PHP_HAVE_BUILTIN_CPU_INIT + __builtin_cpu_init(); +#endif + return __builtin_cpu_supports("pclmul"); +} +#endif + ZEND_NO_SANITIZE_ADDRESS static zend_always_inline int zend_cpu_supports_avx() { #if PHP_HAVE_BUILTIN_CPU_INIT @@ -196,6 +207,10 @@ static zend_always_inline int zend_cpu_supports_sse42() { return zend_cpu_supports(ZEND_CPU_FEATURE_SSE42); } +static zend_always_inline int zend_cpu_supports_pclmul() { + return zend_cpu_supports(ZEND_CPU_FEATURE_PCLMULQDQ); +} + static zend_always_inline int zend_cpu_supports_avx() { return zend_cpu_supports(ZEND_CPU_FEATURE_AVX); } diff --git a/Zend/zend_portability.h b/Zend/zend_portability.h index e94560d18f0ce..f4acc9930e8df 100644 --- a/Zend/zend_portability.h +++ b/Zend/zend_portability.h @@ -487,6 +487,10 @@ extern "C++" { # define PHP_HAVE_SSE4_2 # endif +# if defined(HAVE_WMMINTRIN_H) +# define PHP_HAVE_PCLMUL +# endif + /* * AVX2 support was added in gcc 4.7, but AVX2 intrinsics don't work in * __attribute__((target("avx2"))) functions until gcc 4.9. @@ -547,6 +551,58 @@ extern "C++" { # define ZEND_INTRIN_SSE4_2_FUNC_DECL(func) #endif +#ifdef __PCLMUL__ +/* Instructions compiled directly. */ +# define ZEND_INTRIN_PCLMUL_NATIVE 1 +#elif (defined(HAVE_FUNC_ATTRIBUTE_TARGET) && defined(PHP_HAVE_PCLMUL)) || defined(ZEND_WIN32) +/* Function resolved by ifunc or MINIT. */ +# define ZEND_INTRIN_PCLMUL_RESOLVER 1 +#endif + +/* Do not use for conditional declaration of API functions! */ +#if defined(ZEND_INTRIN_PCLMUL_RESOLVER) && defined(ZEND_INTRIN_HAVE_IFUNC_TARGET) && (!defined(__GNUC__) || (ZEND_GCC_VERSION >= 9000)) +/* __builtin_cpu_supports has pclmul from gcc9 */ +# define ZEND_INTRIN_PCLMUL_FUNC_PROTO 1 +#elif defined(ZEND_INTRIN_PCLMUL_RESOLVER) +# define ZEND_INTRIN_PCLMUL_FUNC_PTR 1 +#endif + +#ifdef ZEND_INTRIN_PCLMUL_RESOLVER +# ifdef HAVE_FUNC_ATTRIBUTE_TARGET +# define ZEND_INTRIN_PCLMUL_FUNC_DECL(func) ZEND_API func __attribute__((target("pclmul"))) +# else +# define ZEND_INTRIN_PCLMUL_FUNC_DECL(func) func +# endif +#else +# define ZEND_INTRIN_PCLMUL_FUNC_DECL(func) +#endif + +#if defined(ZEND_INTRIN_SSE4_2_NATIVE) && defined(ZEND_INTRIN_PCLMUL_NATIVE) +/* Instructions compiled directly. */ +# define ZEND_INTRIN_SSE4_2_PCLMUL_NATIVE 1 +#elif (defined(HAVE_FUNC_ATTRIBUTE_TARGET) && defined(PHP_HAVE_SSE4_2) && defined(PHP_HAVE_PCLMUL)) || defined(ZEND_WIN32) +/* Function resolved by ifunc or MINIT. */ +# define ZEND_INTRIN_SSE4_2_PCLMUL_RESOLVER 1 +#endif + +/* Do not use for conditional declaration of API functions! */ +#if defined(ZEND_INTRIN_SSE4_2_PCLMUL_RESOLVER) && defined(ZEND_INTRIN_HAVE_IFUNC_TARGET) && (!defined(__GNUC__) || (ZEND_GCC_VERSION >= 9000)) +/* __builtin_cpu_supports has pclmul from gcc9 */ +# define ZEND_INTRIN_SSE4_2_PCLMUL_FUNC_PROTO 1 +#elif defined(ZEND_INTRIN_SSE4_2_PCLMUL_RESOLVER) +# define ZEND_INTRIN_SSE4_2_PCLMUL_FUNC_PTR 1 +#endif + +#ifdef ZEND_INTRIN_SSE4_2_PCLMUL_RESOLVER +# ifdef HAVE_FUNC_ATTRIBUTE_TARGET +# define ZEND_INTRIN_SSE4_2_PCLMUL_FUNC_DECL(func) ZEND_API func __attribute__((target("sse4.2,pclmul"))) +# else +# define ZEND_INTRIN_SSE4_2_PCLMUL_FUNC_DECL(func) func +# endif +#else +# define ZEND_INTRIN_SSE4_2_PCLMUL_FUNC_DECL(func) +#endif + #ifdef __AVX2__ # define ZEND_INTRIN_AVX2_NATIVE 1 #elif (defined(HAVE_FUNC_ATTRIBUTE_TARGET) && defined(PHP_HAVE_AVX2)) || defined(ZEND_WIN32) diff --git a/configure.ac b/configure.ac index 7e7f3edec48d1..3ff9a91bf9fb5 100644 --- a/configure.ac +++ b/configure.ac @@ -409,6 +409,7 @@ sys/ipc.h \ dlfcn.h \ tmmintrin.h \ nmmintrin.h \ +wmmintrin.h \ immintrin.h ],[],[],[ #ifdef HAVE_SYS_PARAM_H diff --git a/ext/hash/hash_crc32.c b/ext/hash/hash_crc32.c index de270522d7e27..ade32a3b35c1c 100644 --- a/ext/hash/hash_crc32.c +++ b/ext/hash/hash_crc32.c @@ -18,6 +18,7 @@ #include "php_hash.h" #include "php_hash_crc32.h" #include "php_hash_crc32_tables.h" +#include "ext/standard/crc32_x86.h" PHP_HASH_API void PHP_CRC32Init(PHP_CRC32_CTX *context) { @@ -26,27 +27,39 @@ PHP_HASH_API void PHP_CRC32Init(PHP_CRC32_CTX *context) PHP_HASH_API void PHP_CRC32Update(PHP_CRC32_CTX *context, const unsigned char *input, size_t len) { - size_t i; + size_t i = 0; - for (i = 0; i < len; ++i) { +#if ZEND_INTRIN_SSE4_2_PCLMUL_NATIVE || ZEND_INTRIN_SSE4_2_PCLMUL_RESOLVER + i += crc32_x86_simd_update(X86_CRC32, &context->state, input, len); +#endif + + for (; i < len; ++i) { context->state = (context->state << 8) ^ crc32_table[(context->state >> 24) ^ (input[i] & 0xff)]; } } PHP_HASH_API void PHP_CRC32BUpdate(PHP_CRC32_CTX *context, const unsigned char *input, size_t len) { - size_t i; + size_t i = 0; + +#if ZEND_INTRIN_SSE4_2_PCLMUL_NATIVE || ZEND_INTRIN_SSE4_2_PCLMUL_RESOLVER + i += crc32_x86_simd_update(X86_CRC32B, &context->state, input, len); +#endif - for (i = 0; i < len; ++i) { + for (; i < len; ++i) { context->state = (context->state >> 8) ^ crc32b_table[(context->state ^ input[i]) & 0xff]; } } PHP_HASH_API void PHP_CRC32CUpdate(PHP_CRC32_CTX *context, const unsigned char *input, size_t len) { - size_t i; + size_t i = 0; + +#if ZEND_INTRIN_SSE4_2_PCLMUL_NATIVE || ZEND_INTRIN_SSE4_2_PCLMUL_RESOLVER + i += crc32_x86_simd_update(X86_CRC32C, &context->state, input, len); +#endif - for (i = 0; i < len; ++i) { + for (; i < len; ++i) { context->state = (context->state >> 8) ^ crc32c_table[(context->state ^ input[i]) & 0xff]; } } diff --git a/ext/hash/tests/crc32.phpt b/ext/hash/tests/crc32.phpt index f99152b49e03a..fda63c71360b1 100644 --- a/ext/hash/tests/crc32.phpt +++ b/ext/hash/tests/crc32.phpt @@ -10,6 +10,20 @@ echo hash('crc32', 'message digest'), "\n"; echo hash('crc32', 'abcdefghijklmnopqrstuvwxyz'), "\n"; echo hash('crc32', 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'), "\n"; echo hash('crc32', '12345678901234567890123456789012345678901234567890123456789012345678901234567890'), "\n"; +echo hash('crc32', '1234567890123456'), "\n"; +echo hash('crc32', '1234567890123456abc'), "\n"; +echo hash('crc32', '12345678901234561234567890123456'), "\n"; +echo hash('crc32', '12345678901234561234567890123456abc'), "\n"; +echo hash('crc32', '123456789012345612345678901234561234567890123456'), "\n"; +echo hash('crc32', '123456789012345612345678901234561234567890123456abc'), "\n"; +echo hash('crc32', '1234567890123456123456789012345612345678901234561234567890123456'), "\n"; +echo hash('crc32', '1234567890123456123456789012345612345678901234561234567890123456abc'), "\n"; +echo hash('crc32', '12345678901234561234567890123456123456789012345612345678901234561234567890123456'), "\n"; +echo hash('crc32', '12345678901234561234567890123456123456789012345612345678901234561234567890123456abc'), "\n"; +echo hash('crc32', '12345678901234561234567890123456123456789012345612345678901234561234567890123456123456789012345612345678901234561234567890123456'), "\n"; +echo hash('crc32', '12345678901234561234567890123456123456789012345612345678901234561234567890123456123456789012345612345678901234561234567890123456abc'), "\n"; +echo hash('crc32', '123456789012345612345678901234561234567890123456123456789012345612345678901234561234567890123456123456789012345612345678901234561234567890123456'), "\n"; +echo hash('crc32', '123456789012345612345678901234561234567890123456123456789012345612345678901234561234567890123456123456789012345612345678901234561234567890123456abc'), "\n"; echo "crc32b\n"; echo hash('crc32b', ''), "\n"; @@ -19,6 +33,20 @@ echo hash('crc32b', 'message digest'), "\n"; echo hash('crc32b', 'abcdefghijklmnopqrstuvwxyz'), "\n"; echo hash('crc32b', 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'), "\n"; echo hash('crc32b', '12345678901234567890123456789012345678901234567890123456789012345678901234567890'), "\n"; +echo hash('crc32b', '1234567890123456'), "\n"; +echo hash('crc32b', '1234567890123456abc'), "\n"; +echo hash('crc32b', '12345678901234561234567890123456'), "\n"; +echo hash('crc32b', '12345678901234561234567890123456abc'), "\n"; +echo hash('crc32b', '123456789012345612345678901234561234567890123456'), "\n"; +echo hash('crc32b', '123456789012345612345678901234561234567890123456abc'), "\n"; +echo hash('crc32b', '1234567890123456123456789012345612345678901234561234567890123456'), "\n"; +echo hash('crc32b', '1234567890123456123456789012345612345678901234561234567890123456abc'), "\n"; +echo hash('crc32b', '12345678901234561234567890123456123456789012345612345678901234561234567890123456'), "\n"; +echo hash('crc32b', '12345678901234561234567890123456123456789012345612345678901234561234567890123456abc'), "\n"; +echo hash('crc32b', '12345678901234561234567890123456123456789012345612345678901234561234567890123456123456789012345612345678901234561234567890123456'), "\n"; +echo hash('crc32b', '12345678901234561234567890123456123456789012345612345678901234561234567890123456123456789012345612345678901234561234567890123456abc'), "\n"; +echo hash('crc32b', '123456789012345612345678901234561234567890123456123456789012345612345678901234561234567890123456123456789012345612345678901234561234567890123456'), "\n"; +echo hash('crc32b', '123456789012345612345678901234561234567890123456123456789012345612345678901234561234567890123456123456789012345612345678901234561234567890123456abc'), "\n"; echo "crc32c\n"; echo hash('crc32c', ''), "\n"; @@ -59,6 +87,20 @@ echo hash('crc32c', "Even if I could be Shakespeare, I think I should still choo echo hash('crc32c', "The fugacity of a constituent in a mixture of gases at a given temperature is proportional to its mole fraction. Lewis-Randall Rule"), "\n"; echo hash('crc32c', "How can you write a big system without C++? -Paul Glick"), "\n"; echo hash('crc32c', "\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#\$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"), "\n"; +echo hash('crc32c', '1234567890123456'), "\n"; +echo hash('crc32c', '1234567890123456abc'), "\n"; +echo hash('crc32c', '12345678901234561234567890123456'), "\n"; +echo hash('crc32c', '12345678901234561234567890123456abc'), "\n"; +echo hash('crc32c', '123456789012345612345678901234561234567890123456'), "\n"; +echo hash('crc32c', '123456789012345612345678901234561234567890123456abc'), "\n"; +echo hash('crc32c', '1234567890123456123456789012345612345678901234561234567890123456'), "\n"; +echo hash('crc32c', '1234567890123456123456789012345612345678901234561234567890123456abc'), "\n"; +echo hash('crc32c', '12345678901234561234567890123456123456789012345612345678901234561234567890123456'), "\n"; +echo hash('crc32c', '12345678901234561234567890123456123456789012345612345678901234561234567890123456abc'), "\n"; +echo hash('crc32c', '12345678901234561234567890123456123456789012345612345678901234561234567890123456123456789012345612345678901234561234567890123456'), "\n"; +echo hash('crc32c', '12345678901234561234567890123456123456789012345612345678901234561234567890123456123456789012345612345678901234561234567890123456abc'), "\n"; +echo hash('crc32c', '123456789012345612345678901234561234567890123456123456789012345612345678901234561234567890123456123456789012345612345678901234561234567890123456'), "\n"; +echo hash('crc32c', '123456789012345612345678901234561234567890123456123456789012345612345678901234561234567890123456123456789012345612345678901234561234567890123456abc'), "\n"; ?> --EXPECT-- @@ -70,6 +112,20 @@ crc32 9693bf77 882174a0 96790816 +98b0e78d +a6f33d71 +900a1d38 +396978fe +adfc6afe +d3ef9388 +c53911dc +37006f1b +4a54af3a +98d05c71 +5a26f5b4 +b9108715 +cc684112 +b2ac45af crc32b 00000000 e8b7be43 @@ -78,6 +134,20 @@ e8b7be43 4c2750bd 1fc2e6d2 7ca94a72 +1e5fcdb7 +70b54c2f +094fb11e +38210c49 +7399c6ef +83e98d04 +1f26a94e +e2e8634a +0642542d +43b42c9b +262e1ded +b7a463c4 +dfa1bbae +4022d57a crc32c 00000000 c1d04330 @@ -116,4 +186,18 @@ de2e65c5 297a88ed 66ed1d8b dcded527 -9c44184b \ No newline at end of file +9c44184b +9aa4287f +ab2761c5 +cd486b4b +c19c4a41 +1ea5b441 +36d20512 +31d11ffa +65d5bb9e +a0e3e317 +8dc10a7c +7ab04135 +c292a38d +e3e558ec +b6c5e13e diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c index 18e4985da2b16..7051e4a456b8e 100755 --- a/ext/standard/basic_functions.c +++ b/ext/standard/basic_functions.c @@ -33,6 +33,7 @@ #include "ext/standard/php_dns.h" #include "ext/standard/php_uuencode.h" #include "ext/standard/php_mt_rand.h" +#include "ext/standard/crc32_x86.h" #ifdef PHP_WIN32 #include "win32/php_win32_globals.h" @@ -363,6 +364,10 @@ PHP_MINIT_FUNCTION(basic) /* {{{ */ BASIC_MINIT_SUBMODULE(string_intrin) #endif +#if ZEND_INTRIN_SSE4_2_PCLMUL_FUNC_PTR + BASIC_MINIT_SUBMODULE(crc32_x86_intrin) +#endif + #if ZEND_INTRIN_AVX2_FUNC_PTR || ZEND_INTRIN_SSSE3_FUNC_PTR BASIC_MINIT_SUBMODULE(base64_intrin) #endif diff --git a/ext/standard/config.m4 b/ext/standard/config.m4 index 04b9d0aea1d6a..1cb0af79f68e0 100644 --- a/ext/standard/config.m4 +++ b/ext/standard/config.m4 @@ -449,7 +449,7 @@ PHP_NEW_EXTENSION(standard, array.c base64.c basic_functions.c browscap.c crc32. http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \ var_unserializer.c ftok.c sha1.c user_filters.c uuencode.c \ filters.c proc_open.c streamsfuncs.c http.c password.c \ - random.c net.c hrtime.c,,, + random.c net.c hrtime.c crc32_x86.c,,, -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1) PHP_ADD_MAKEFILE_FRAGMENT diff --git a/ext/standard/config.w32 b/ext/standard/config.w32 index a5737ea8538b8..d23bfd9db2617 100644 --- a/ext/standard/config.w32 +++ b/ext/standard/config.w32 @@ -25,7 +25,7 @@ ADD_FLAG("LIBS_STANDARD", "iphlpapi.lib"); EXTENSION("standard", "array.c base64.c basic_functions.c browscap.c \ crc32.c crypt.c crypt_freesec.c crypt_blowfish.c crypt_sha256.c \ - crypt_sha512.c php_crypt_r.c \ + crypt_sha512.c php_crypt_r.c crc32_x86.c \ datetime.c dir.c dl.c dns.c dns_win32.c exec.c \ file.c filestat.c formatted_print.c fsock.c head.c html.c image.c \ info.c iptc.c lcg.c link.c mail.c math.c md5.c metaphone.c microtime.c \ diff --git a/ext/standard/crc32.c b/ext/standard/crc32.c index 6ab5c317bfc72..40d9404053e28 100644 --- a/ext/standard/crc32.c +++ b/ext/standard/crc32.c @@ -17,6 +17,7 @@ #include "php.h" #include "basic_functions.h" #include "crc32.h" +#include "crc32_x86.h" #if HAVE_AARCH64_CRC32 # include @@ -74,7 +75,7 @@ PHP_FUNCTION(crc32) char *p; size_t nr; uint32_t crcinit = 0; - register uint32_t crc; + uint32_t crc; ZEND_PARSE_PARAMETERS_START(1, 1) Z_PARAM_STRING(p, nr) @@ -89,6 +90,12 @@ PHP_FUNCTION(crc32) } #endif +#if ZEND_INTRIN_SSE4_2_PCLMUL_NATIVE || ZEND_INTRIN_SSE4_2_PCLMUL_RESOLVER + size_t nr_simd = crc32_x86_simd_update(X86_CRC32B, &crc, (const unsigned char *)p, nr); + nr -= nr_simd; + p += nr_simd; +#endif + for (; nr--; ++p) { crc = ((crc >> 8) & 0x00FFFFFF) ^ crc32tab[(crc ^ (*p)) & 0xFF ]; } diff --git a/ext/standard/crc32_x86.c b/ext/standard/crc32_x86.c new file mode 100644 index 0000000000000..296eadeb9490b --- /dev/null +++ b/ext/standard/crc32_x86.c @@ -0,0 +1,349 @@ +/* + +----------------------------------------------------------------------+ + | Copyright (c) The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | https://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Frank Du | + +----------------------------------------------------------------------+ + | Compute the crc32 of the buffer. Based on: | + | "Fast CRC Computation for Generic Polynomials Using PCLMULQDQ" | + | V. Gopal, E. Ozturk, et al., 2009, http://intel.ly/2ySEwL0 | +*/ + +#include "crc32_x86.h" + +#if ZEND_INTRIN_SSE4_2_PCLMUL_NATIVE || ZEND_INTRIN_SSE4_2_PCLMUL_RESOLVER +# include +# include +#endif + +#if ZEND_INTRIN_SSE4_2_PCLMUL_RESOLVER +# include "Zend/zend_cpuinfo.h" +#endif + +#if ZEND_INTRIN_SSE4_2_PCLMUL_NATIVE || ZEND_INTRIN_SSE4_2_PCLMUL_RESOLVER + +typedef struct _crc32_pclmul_bit_consts { + uint64_t k1k2[2]; + uint64_t k3k4[2]; + uint64_t k5k6[2]; + uint64_t uPx[2]; +} crc32_pclmul_consts; + +static const crc32_pclmul_consts crc32_pclmul_consts_maps[X86_CRC32_MAX] = { + { /* X86_CRC32, polynomial: 0x04C11DB7 */ + {0x00e6228b11, 0x008833794c}, /* endianness swap */ + {0x00e8a45605, 0x00c5b9cd4c}, /* endianness swap */ + {0x00490d678d, 0x00f200aa66}, /* endianness swap */ + {0x0104d101df, 0x0104c11db7} + }, + { /* X86_CRC32B, polynomial: 0x04C11DB7 with reversed ordering */ + {0x0154442bd4, 0x01c6e41596}, + {0x01751997d0, 0x00ccaa009e}, + {0x0163cd6124, 0x01db710640}, + {0x01f7011641, 0x01db710641}, + }, + { /* X86_CRC32C, polynomial: 0x1EDC6F41 with reversed ordering */ + {0x00740eef02, 0x009e4addf8}, + {0x00f20c0dfe, 0x014cd00bd6}, + {0x00dd45aab8, 0x0000000000}, + {0x00dea713f1, 0x0105ec76f0} + } +}; + +static uint8_t pclmul_shuf_mask_table[16] = { + 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, + 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, +}; + +/* Folding of 128-bit data chunks */ +#define CRC32_FOLDING_BLOCK_SIZE (16) + +/* PCLMUL version of non-relfected crc32 */ +ZEND_INTRIN_SSE4_2_PCLMUL_FUNC_DECL(size_t crc32_pclmul_batch(uint32_t *crc, const unsigned char *p, size_t nr, const crc32_pclmul_consts *consts)); +size_t crc32_pclmul_batch(uint32_t *crc, const unsigned char *p, size_t nr, const crc32_pclmul_consts *consts) +{ + size_t nr_in = nr; + __m128i x0, x1, x2, k, shuf_mask; + + if (nr < CRC32_FOLDING_BLOCK_SIZE) { + return 0; + } + + shuf_mask = _mm_loadu_si128((__m128i *)(pclmul_shuf_mask_table)); + x0 = _mm_cvtsi32_si128(*crc); + x1 = _mm_loadu_si128((__m128i *)(p + 0x00)); + x0 = _mm_slli_si128(x0, 12); + x1 = _mm_shuffle_epi8(x1, shuf_mask); /* endianness swap */ + x0 = _mm_xor_si128(x1, x0); + p += CRC32_FOLDING_BLOCK_SIZE; + nr -= CRC32_FOLDING_BLOCK_SIZE; + + if (nr >= (CRC32_FOLDING_BLOCK_SIZE * 3)) { + __m128i x3, x4; + + x1 = _mm_loadu_si128((__m128i *)(p + 0x00)); + x1 = _mm_shuffle_epi8(x1, shuf_mask); /* endianness swap */ + x2 = _mm_loadu_si128((__m128i *)(p + 0x10)); + x2 = _mm_shuffle_epi8(x2, shuf_mask); /* endianness swap */ + x3 = _mm_loadu_si128((__m128i *)(p + 0x20)); + x3 = _mm_shuffle_epi8(x3, shuf_mask); /* endianness swap */ + p += CRC32_FOLDING_BLOCK_SIZE * 3; + nr -= CRC32_FOLDING_BLOCK_SIZE * 3; + + k = _mm_loadu_si128((__m128i *)consts->k1k2); + /* parallel folding by 4 */ + while (nr >= (CRC32_FOLDING_BLOCK_SIZE * 4)) { + __m128i x5, x6, x7, x8, x9, x10, x11; + x4 = _mm_clmulepi64_si128(x0, k, 0x00); + x5 = _mm_clmulepi64_si128(x1, k, 0x00); + x6 = _mm_clmulepi64_si128(x2, k, 0x00); + x7 = _mm_clmulepi64_si128(x3, k, 0x00); + x0 = _mm_clmulepi64_si128(x0, k, 0x11); + x1 = _mm_clmulepi64_si128(x1, k, 0x11); + x2 = _mm_clmulepi64_si128(x2, k, 0x11); + x3 = _mm_clmulepi64_si128(x3, k, 0x11); + x8 = _mm_loadu_si128((__m128i *)(p + 0x00)); + x8 = _mm_shuffle_epi8(x8, shuf_mask); /* endianness swap */ + x9 = _mm_loadu_si128((__m128i *)(p + 0x10)); + x9 = _mm_shuffle_epi8(x9, shuf_mask); /* endianness swap */ + x10 = _mm_loadu_si128((__m128i *)(p + 0x20)); + x10 = _mm_shuffle_epi8(x10, shuf_mask); /* endianness swap */ + x11 = _mm_loadu_si128((__m128i *)(p + 0x30)); + x11 = _mm_shuffle_epi8(x11, shuf_mask); /* endianness swap */ + x0 = _mm_xor_si128(x0, x4); + x1 = _mm_xor_si128(x1, x5); + x2 = _mm_xor_si128(x2, x6); + x3 = _mm_xor_si128(x3, x7); + x0 = _mm_xor_si128(x0, x8); + x1 = _mm_xor_si128(x1, x9); + x2 = _mm_xor_si128(x2, x10); + x3 = _mm_xor_si128(x3, x11); + + p += CRC32_FOLDING_BLOCK_SIZE * 4; + nr -= CRC32_FOLDING_BLOCK_SIZE * 4; + } + + k = _mm_loadu_si128((__m128i *)consts->k3k4); + /* fold 4 to 1, [x1, x2, x3] -> x0 */ + x4 = _mm_clmulepi64_si128(x0, k, 0x00); + x0 = _mm_clmulepi64_si128(x0, k, 0x11); + x0 = _mm_xor_si128(x0, x1); + x0 = _mm_xor_si128(x0, x4); + x4 = _mm_clmulepi64_si128(x0, k, 0x00); + x0 = _mm_clmulepi64_si128(x0, k, 0x11); + x0 = _mm_xor_si128(x0, x2); + x0 = _mm_xor_si128(x0, x4); + x4 = _mm_clmulepi64_si128(x0, k, 0x00); + x0 = _mm_clmulepi64_si128(x0, k, 0x11); + x0 = _mm_xor_si128(x0, x3); + x0 = _mm_xor_si128(x0, x4); + } + + k = _mm_loadu_si128((__m128i *)consts->k3k4); + /* folding by 1 */ + while (nr >= CRC32_FOLDING_BLOCK_SIZE) { + /* load next to x2, fold to x0, x1 */ + x2 = _mm_loadu_si128((__m128i *)(p + 0x00)); + x2 = _mm_shuffle_epi8(x2, shuf_mask); /* endianness swap */ + x1 = _mm_clmulepi64_si128(x0, k, 0x00); + x0 = _mm_clmulepi64_si128(x0, k, 0x11); + x0 = _mm_xor_si128(x0, x2); + x0 = _mm_xor_si128(x0, x1); + p += CRC32_FOLDING_BLOCK_SIZE; + nr -= CRC32_FOLDING_BLOCK_SIZE; + } + + /* reduce 128-bits(final fold) to 96-bits */ + k = _mm_loadu_si128((__m128i*)consts->k5k6); + x1 = _mm_clmulepi64_si128(x0, k, 0x11); + x0 = _mm_slli_si128(x0, 8); + x0 = _mm_srli_si128(x0, 4); + x0 = _mm_xor_si128(x0, x1); + /* reduce 96-bits to 64-bits */ + x1 = _mm_clmulepi64_si128(x0, k, 0x01); + x0 = _mm_xor_si128(x0, x1); + + /* barrett reduction */ + k = _mm_loadu_si128((__m128i*)consts->uPx); + x1 = _mm_move_epi64(x0); + x1 = _mm_srli_si128(x1, 4); + x1 = _mm_clmulepi64_si128(x1, k, 0x00); + x1 = _mm_srli_si128(x1, 4); + x1 = _mm_clmulepi64_si128(x1, k, 0x10); + x0 = _mm_xor_si128(x1, x0); + *crc = _mm_extract_epi32(x0, 0); + return (nr_in - nr); /* the nr processed */ +} + +/* PCLMUL version of relfected crc32 */ +ZEND_INTRIN_SSE4_2_PCLMUL_FUNC_DECL(size_t crc32_pclmul_reflected_batch(uint32_t *crc, const unsigned char *p, size_t nr, const crc32_pclmul_consts *consts)); +size_t crc32_pclmul_reflected_batch(uint32_t *crc, const unsigned char *p, size_t nr, const crc32_pclmul_consts *consts) +{ + size_t nr_in = nr; + __m128i x0, x1, x2, k; + + if (nr < CRC32_FOLDING_BLOCK_SIZE) { + return 0; + } + + x0 = _mm_loadu_si128((__m128i *)(p + 0x00)); + x0 = _mm_xor_si128(x0, _mm_cvtsi32_si128(*crc)); + p += CRC32_FOLDING_BLOCK_SIZE; + nr -= CRC32_FOLDING_BLOCK_SIZE; + if (nr >= (CRC32_FOLDING_BLOCK_SIZE * 3)) { + __m128i x3, x4; + + x1 = _mm_loadu_si128((__m128i *)(p + 0x00)); + x2 = _mm_loadu_si128((__m128i *)(p + 0x10)); + x3 = _mm_loadu_si128((__m128i *)(p + 0x20)); + p += CRC32_FOLDING_BLOCK_SIZE * 3; + nr -= CRC32_FOLDING_BLOCK_SIZE * 3; + + k = _mm_loadu_si128((__m128i *)consts->k1k2); + /* parallel folding by 4 */ + while (nr >= (CRC32_FOLDING_BLOCK_SIZE * 4)) { + __m128i x5, x6, x7, x8, x9, x10, x11; + x4 = _mm_clmulepi64_si128(x0, k, 0x00); + x5 = _mm_clmulepi64_si128(x1, k, 0x00); + x6 = _mm_clmulepi64_si128(x2, k, 0x00); + x7 = _mm_clmulepi64_si128(x3, k, 0x00); + x0 = _mm_clmulepi64_si128(x0, k, 0x11); + x1 = _mm_clmulepi64_si128(x1, k, 0x11); + x2 = _mm_clmulepi64_si128(x2, k, 0x11); + x3 = _mm_clmulepi64_si128(x3, k, 0x11); + x8 = _mm_loadu_si128((__m128i *)(p + 0x00)); + x9 = _mm_loadu_si128((__m128i *)(p + 0x10)); + x10 = _mm_loadu_si128((__m128i *)(p + 0x20)); + x11 = _mm_loadu_si128((__m128i *)(p + 0x30)); + x0 = _mm_xor_si128(x0, x4); + x1 = _mm_xor_si128(x1, x5); + x2 = _mm_xor_si128(x2, x6); + x3 = _mm_xor_si128(x3, x7); + x0 = _mm_xor_si128(x0, x8); + x1 = _mm_xor_si128(x1, x9); + x2 = _mm_xor_si128(x2, x10); + x3 = _mm_xor_si128(x3, x11); + + p += CRC32_FOLDING_BLOCK_SIZE * 4; + nr -= CRC32_FOLDING_BLOCK_SIZE * 4; + } + + k = _mm_loadu_si128((__m128i *)consts->k3k4); + /* fold 4 to 1, [x1, x2, x3] -> x0 */ + x4 = _mm_clmulepi64_si128(x0, k, 0x00); + x0 = _mm_clmulepi64_si128(x0, k, 0x11); + x0 = _mm_xor_si128(x0, x1); + x0 = _mm_xor_si128(x0, x4); + x4 = _mm_clmulepi64_si128(x0, k, 0x00); + x0 = _mm_clmulepi64_si128(x0, k, 0x11); + x0 = _mm_xor_si128(x0, x2); + x0 = _mm_xor_si128(x0, x4); + x4 = _mm_clmulepi64_si128(x0, k, 0x00); + x0 = _mm_clmulepi64_si128(x0, k, 0x11); + x0 = _mm_xor_si128(x0, x3); + x0 = _mm_xor_si128(x0, x4); + } + + k = _mm_loadu_si128((__m128i *)consts->k3k4); + /* folding by 1 */ + while (nr >= CRC32_FOLDING_BLOCK_SIZE) { + /* load next to x2, fold to x0, x1 */ + x2 = _mm_loadu_si128((__m128i *)(p + 0x00)); + x1 = _mm_clmulepi64_si128(x0, k, 0x00); + x0 = _mm_clmulepi64_si128(x0, k, 0x11); + x0 = _mm_xor_si128(x0, x2); + x0 = _mm_xor_si128(x0, x1); + p += CRC32_FOLDING_BLOCK_SIZE; + nr -= CRC32_FOLDING_BLOCK_SIZE; + } + + /* reduce 128-bits(final fold) to 96-bits */ + x1 = _mm_clmulepi64_si128(x0, k, 0x10); + x0 = _mm_srli_si128(x0, 8); + x0 = _mm_xor_si128(x0, x1); + /* reduce 96-bits to 64-bits */ + x1 = _mm_shuffle_epi32(x0, 0xfc); + x0 = _mm_shuffle_epi32(x0, 0xf9); + k = _mm_loadu_si128((__m128i*)consts->k5k6); + x1 = _mm_clmulepi64_si128(x1, k, 0x00); + x0 = _mm_xor_si128(x0, x1); + + /* barrett reduction */ + x1 = _mm_shuffle_epi32(x0, 0xf3); + x0 = _mm_slli_si128(x0, 4); + k = _mm_loadu_si128((__m128i*)consts->uPx); + x1 = _mm_clmulepi64_si128(x1, k, 0x00); + x1 = _mm_clmulepi64_si128(x1, k, 0x10); + x0 = _mm_xor_si128(x1, x0); + *crc = _mm_extract_epi32(x0, 2); + return (nr_in - nr); /* the nr processed */ +} + +# if ZEND_INTRIN_SSE4_2_PCLMUL_NATIVE +size_t crc32_x86_simd_update(X86_CRC32_TYPE type, uint32_t *crc, const unsigned char *p, size_t nr) +# else /* ZEND_INTRIN_SSE4_2_PCLMUL_RESOLVER */ +size_t crc32_sse42_pclmul_update(X86_CRC32_TYPE type, uint32_t *crc, const unsigned char *p, size_t nr) +# endif +{ + if (type > X86_CRC32_MAX) { + return 0; + } + const crc32_pclmul_consts *consts = &crc32_pclmul_consts_maps[type]; + + switch (type) { + case X86_CRC32: + return crc32_pclmul_batch(crc, p, nr, consts); + case X86_CRC32B: + case X86_CRC32C: + return crc32_pclmul_reflected_batch(crc, p, nr, consts); + default: + return 0; + } +} +#endif + +#if ZEND_INTRIN_SSE4_2_PCLMUL_RESOLVER +static size_t crc32_x86_simd_update_default(X86_CRC32_TYPE type, uint32_t *crc, const unsigned char *p, size_t nr) +{ + return 0; +} + +# if ZEND_INTRIN_SSE4_2_PCLMUL_FUNC_PROTO +size_t crc32_x86_simd_update(X86_CRC32_TYPE type, uint32_t *crc, const unsigned char *p, size_t nr) __attribute__((ifunc("resolve_crc32_x86_simd_update"))); + +typedef size_t (*crc32_x86_simd_func_t)(X86_CRC32_TYPE type, uint32_t *crc, const unsigned char *p, size_t nr); + +ZEND_NO_SANITIZE_ADDRESS +ZEND_ATTRIBUTE_UNUSED /* clang mistakenly warns about this */ +static crc32_x86_simd_func_t resolve_crc32_x86_simd_update() { + if (zend_cpu_supports_sse42() && zend_cpu_supports_pclmul()) { + return crc32_sse42_pclmul_update; + } + return crc32_x86_simd_update_default; +} +# else /* ZEND_INTRIN_SSE4_2_PCLMUL_FUNC_PTR */ +static size_t (*crc32_x86_simd_ptr)(X86_CRC32_TYPE type, uint32_t *crc, const unsigned char *p, size_t nr) = crc32_x86_simd_update_default; + +size_t crc32_x86_simd_update(X86_CRC32_TYPE type, uint32_t *crc, const unsigned char *p, size_t nr) { + return crc32_x86_simd_ptr(type, crc, p, nr); +} + +/* {{{ PHP_MINIT_FUNCTION */ +PHP_MINIT_FUNCTION(crc32_x86_intrin) +{ + if (zend_cpu_supports(ZEND_CPU_FEATURE_SSE42) && zend_cpu_supports(ZEND_CPU_FEATURE_PCLMULQDQ)) { + crc32_x86_simd_ptr = crc32_sse42_pclmul_update; + } + return SUCCESS; +} +/* }}} */ +# endif +#endif diff --git a/ext/standard/crc32_x86.h b/ext/standard/crc32_x86.h new file mode 100644 index 0000000000000..6420030dbf5dc --- /dev/null +++ b/ext/standard/crc32_x86.h @@ -0,0 +1,52 @@ +/* + +----------------------------------------------------------------------+ + | Copyright (c) The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | https://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Frank Du | + +----------------------------------------------------------------------+ +*/ + +#ifndef _CRC32_X86_HEADER_H_ +#define _CRC32_X86_HEADER_H_ + +#include "php.h" + +typedef enum { + /* polynomial: 0x04C11DB7, used by bzip */ + X86_CRC32 = 0, + /* + polynomial: 0x04C11DB7 with reversed ordering, + used by ethernet (IEEE 802.3), gzip, zip, png, etc + */ + X86_CRC32B, + /* + polynomial: 0x1EDC6F41 with reversed ordering, + used by iSCSI, SCTP, Btrfs, ext4, etc + */ + X86_CRC32C, + X86_CRC32_MAX, +} X86_CRC32_TYPE; + +#if ZEND_INTRIN_SSE4_2_PCLMUL_FUNC_PTR +PHP_MINIT_FUNCTION(crc32_x86_intrin); +#endif + +#if ZEND_INTRIN_SSE4_2_PCLMUL_NATIVE || ZEND_INTRIN_SSE4_2_PCLMUL_RESOLVER +/* Return the size processed by SIMD routine */ +size_t crc32_x86_simd_update(X86_CRC32_TYPE type, uint32_t *crc, const unsigned char *p, size_t nr); +#else +static inline size_t crc32_x86_simd_update(X86_CRC32_TYPE type, uint32_t *crc, const unsigned char *p, size_t nr) +{ + return 0; +} +#endif + +#endif diff --git a/ext/standard/tests/strings/crc32.phpt b/ext/standard/tests/strings/crc32.phpt index 2fa8be59d8746..da86d067bf66d 100644 --- a/ext/standard/tests/strings/crc32.phpt +++ b/ext/standard/tests/strings/crc32.phpt @@ -6,9 +6,37 @@ $input = array("foo", "bar", "baz", "grldsajkopallkjasd"); foreach($input AS $i) { printf("%u\n", crc32($i)); } +printf("%u\n", crc32("1234567890123456")); +printf("%u\n", crc32("1234567890123456abc")); +printf("%u\n", crc32("12345678901234561234567890123456")); +printf("%u\n", crc32("12345678901234561234567890123456abc")); +printf("%u\n", crc32("123456789012345612345678901234561234567890123456")); +printf("%u\n", crc32("123456789012345612345678901234561234567890123456abc")); +printf("%u\n", crc32("1234567890123456123456789012345612345678901234561234567890123456")); +printf("%u\n", crc32("1234567890123456123456789012345612345678901234561234567890123456abc")); +printf("%u\n", crc32("12345678901234561234567890123456123456789012345612345678901234561234567890123456")); +printf("%u\n", crc32("12345678901234561234567890123456123456789012345612345678901234561234567890123456abc")); +printf("%u\n", crc32("12345678901234561234567890123456123456789012345612345678901234561234567890123456123456789012345612345678901234561234567890123456")); +printf("%u\n", crc32("12345678901234561234567890123456123456789012345612345678901234561234567890123456123456789012345612345678901234561234567890123456abc")); +printf("%u\n", crc32("123456789012345612345678901234561234567890123456123456789012345612345678901234561234567890123456123456789012345612345678901234561234567890123456")); +printf("%u\n", crc32("123456789012345612345678901234561234567890123456123456789012345612345678901234561234567890123456123456789012345612345678901234561234567890123456abc")); ?> --EXPECT-- 2356372769 1996459178 2015626392 824412087 +509595063 +1890929711 +156217630 +941689929 +1939457775 +2213121284 +522627406 +3806880586 +105010221 +1135881371 +640556525 +3081003972 +3751918510 +1076024698 From 0d157cf526d65ac7ad7f1981de05adf65a10f956 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Wed, 2 Sep 2020 17:31:48 +0300 Subject: [PATCH 10/87] Micro-optimization --- Zend/zend_vm_def.h | 22 ++++++++++------------ Zend/zend_vm_execute.h | 26 ++++++++++++-------------- 2 files changed, 22 insertions(+), 26 deletions(-) diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index af6d41db8640f..b083ad627bab1 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -6637,6 +6637,7 @@ ZEND_VM_C_LABEL(fe_fetch_r_exit): ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value); ZEND_VM_CONTINUE(); } + pos++; value = &p->val; value_type = Z_TYPE_INFO_P(value); if (EXPECTED(value_type != IS_UNDEF)) { @@ -6650,10 +6651,9 @@ ZEND_VM_C_LABEL(fe_fetch_r_exit): break; } } - pos++; p++; } - Z_FE_POS_P(array) = pos + 1; + Z_FE_POS_P(array) = pos; if (RETURN_VALUE_USED(opline)) { if (!p->key) { ZVAL_LONG(EX_VAR(opline->result.var), p->h); @@ -6676,7 +6676,7 @@ ZEND_VM_C_LABEL(fe_fetch_r_exit): /* reached end of iteration */ ZEND_VM_C_GOTO(fe_fetch_r_exit); } - + pos++; value = &p->val; value_type = Z_TYPE_INFO_P(value); if (EXPECTED(value_type != IS_UNDEF)) { @@ -6693,9 +6693,9 @@ ZEND_VM_C_LABEL(fe_fetch_r_exit): break; } } - pos++; p++; } + EG(ht_iterators)[Z_FE_ITER_P(array)].pos = pos; if (RETURN_VALUE_USED(opline)) { if (UNEXPECTED(!p->key)) { ZVAL_LONG(EX_VAR(opline->result.var), p->h); @@ -6709,7 +6709,6 @@ ZEND_VM_C_LABEL(fe_fetch_r_exit): ZVAL_STRINGL(EX_VAR(opline->result.var), prop_name, prop_name_len); } } - EG(ht_iterators)[Z_FE_ITER_P(array)].pos = pos + 1; } else { if (EXPECTED(++iter->index > 0)) { /* This could cause an endless loop if index becomes zero again. @@ -6790,6 +6789,7 @@ ZEND_VM_HANDLER(126, ZEND_FE_FETCH_RW, VAR, ANY, JMP_ADDR) /* reached end of iteration */ ZEND_VM_C_GOTO(fe_fetch_w_exit); } + pos++; value = &p->val; value_type = Z_TYPE_INFO_P(value); if (EXPECTED(value_type != IS_UNDEF)) { @@ -6803,9 +6803,9 @@ ZEND_VM_HANDLER(126, ZEND_FE_FETCH_RW, VAR, ANY, JMP_ADDR) break; } } - pos++; p++; } + EG(ht_iterators)[Z_FE_ITER_P(EX_VAR(opline->op1.var))].pos = pos; if (RETURN_VALUE_USED(opline)) { if (!p->key) { ZVAL_LONG(EX_VAR(opline->result.var), p->h); @@ -6813,7 +6813,6 @@ ZEND_VM_HANDLER(126, ZEND_FE_FETCH_RW, VAR, ANY, JMP_ADDR) ZVAL_STR_COPY(EX_VAR(opline->result.var), p->key); } } - EG(ht_iterators)[Z_FE_ITER_P(EX_VAR(opline->op1.var))].pos = pos + 1; } else if (EXPECTED(Z_TYPE_P(array) == IS_OBJECT)) { zend_object_iterator *iter; @@ -6828,7 +6827,7 @@ ZEND_VM_HANDLER(126, ZEND_FE_FETCH_RW, VAR, ANY, JMP_ADDR) /* reached end of iteration */ ZEND_VM_C_GOTO(fe_fetch_w_exit); } - + pos++; value = &p->val; value_type = Z_TYPE_INFO_P(value); if (EXPECTED(value_type != IS_UNDEF)) { @@ -6854,9 +6853,9 @@ ZEND_VM_HANDLER(126, ZEND_FE_FETCH_RW, VAR, ANY, JMP_ADDR) break; } } - pos++; p++; } + EG(ht_iterators)[Z_FE_ITER_P(EX_VAR(opline->op1.var))].pos = pos; if (RETURN_VALUE_USED(opline)) { if (UNEXPECTED(!p->key)) { ZVAL_LONG(EX_VAR(opline->result.var), p->h); @@ -6870,7 +6869,6 @@ ZEND_VM_HANDLER(126, ZEND_FE_FETCH_RW, VAR, ANY, JMP_ADDR) ZVAL_STRINGL(EX_VAR(opline->result.var), prop_name, prop_name_len); } } - EG(ht_iterators)[Z_FE_ITER_P(EX_VAR(opline->op1.var))].pos = pos + 1; } else { if (++iter->index > 0) { /* This could cause an endless loop if index becomes zero again. @@ -9605,6 +9603,7 @@ ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_FE_FETCH_R, op->op2_type == IS_CV && (op1_inf ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value); ZEND_VM_CONTINUE(); } + pos++; value = &p->val; value_type = Z_TYPE_INFO_P(value); if (EXPECTED(value_type != IS_UNDEF)) { @@ -9618,10 +9617,9 @@ ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_FE_FETCH_R, op->op2_type == IS_CV && (op1_inf break; } } - pos++; p++; } - Z_FE_POS_P(array) = pos + 1; + Z_FE_POS_P(array) = pos; if (RETURN_VALUE_USED(opline)) { if (!p->key) { ZVAL_LONG(EX_VAR(opline->result.var), p->h); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 14d9670ee4649..bacac7d0517df 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -22186,6 +22186,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_FETCH_R_SPEC_VAR_HANDLER(ZE ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value); ZEND_VM_CONTINUE(); } + pos++; value = &p->val; value_type = Z_TYPE_INFO_P(value); if (EXPECTED(value_type != IS_UNDEF)) { @@ -22199,10 +22200,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_FETCH_R_SPEC_VAR_HANDLER(ZE break; } } - pos++; p++; } - Z_FE_POS_P(array) = pos + 1; + Z_FE_POS_P(array) = pos; if (RETURN_VALUE_USED(opline)) { if (!p->key) { ZVAL_LONG(EX_VAR(opline->result.var), p->h); @@ -22225,7 +22225,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_FETCH_R_SPEC_VAR_HANDLER(ZE /* reached end of iteration */ goto fe_fetch_r_exit; } - + pos++; value = &p->val; value_type = Z_TYPE_INFO_P(value); if (EXPECTED(value_type != IS_UNDEF)) { @@ -22242,9 +22242,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_FETCH_R_SPEC_VAR_HANDLER(ZE break; } } - pos++; p++; } + EG(ht_iterators)[Z_FE_ITER_P(array)].pos = pos; if (RETURN_VALUE_USED(opline)) { if (UNEXPECTED(!p->key)) { ZVAL_LONG(EX_VAR(opline->result.var), p->h); @@ -22258,7 +22258,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_FETCH_R_SPEC_VAR_HANDLER(ZE ZVAL_STRINGL(EX_VAR(opline->result.var), prop_name, prop_name_len); } } - EG(ht_iterators)[Z_FE_ITER_P(array)].pos = pos + 1; } else { if (EXPECTED(++iter->index > 0)) { /* This could cause an endless loop if index becomes zero again. @@ -22339,6 +22338,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_FETCH_RW_SPEC_VAR_HANDLER(Z /* reached end of iteration */ goto fe_fetch_w_exit; } + pos++; value = &p->val; value_type = Z_TYPE_INFO_P(value); if (EXPECTED(value_type != IS_UNDEF)) { @@ -22352,9 +22352,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_FETCH_RW_SPEC_VAR_HANDLER(Z break; } } - pos++; p++; } + EG(ht_iterators)[Z_FE_ITER_P(EX_VAR(opline->op1.var))].pos = pos; if (RETURN_VALUE_USED(opline)) { if (!p->key) { ZVAL_LONG(EX_VAR(opline->result.var), p->h); @@ -22362,7 +22362,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_FETCH_RW_SPEC_VAR_HANDLER(Z ZVAL_STR_COPY(EX_VAR(opline->result.var), p->key); } } - EG(ht_iterators)[Z_FE_ITER_P(EX_VAR(opline->op1.var))].pos = pos + 1; } else if (EXPECTED(Z_TYPE_P(array) == IS_OBJECT)) { zend_object_iterator *iter; @@ -22377,7 +22376,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_FETCH_RW_SPEC_VAR_HANDLER(Z /* reached end of iteration */ goto fe_fetch_w_exit; } - + pos++; value = &p->val; value_type = Z_TYPE_INFO_P(value); if (EXPECTED(value_type != IS_UNDEF)) { @@ -22403,9 +22402,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_FETCH_RW_SPEC_VAR_HANDLER(Z break; } } - pos++; p++; } + EG(ht_iterators)[Z_FE_ITER_P(EX_VAR(opline->op1.var))].pos = pos; if (RETURN_VALUE_USED(opline)) { if (UNEXPECTED(!p->key)) { ZVAL_LONG(EX_VAR(opline->result.var), p->h); @@ -22419,7 +22418,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_FETCH_RW_SPEC_VAR_HANDLER(Z ZVAL_STRINGL(EX_VAR(opline->result.var), prop_name, prop_name_len); } } - EG(ht_iterators)[Z_FE_ITER_P(EX_VAR(opline->op1.var))].pos = pos + 1; } else { if (++iter->index > 0) { /* This could cause an endless loop if index becomes zero again. @@ -31382,6 +31380,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_FETCH_R_SIMPLE_ ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value); ZEND_VM_CONTINUE(); } + pos++; value = &p->val; value_type = Z_TYPE_INFO_P(value); if (EXPECTED(value_type != IS_UNDEF)) { @@ -31395,10 +31394,9 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_FETCH_R_SIMPLE_ break; } } - pos++; p++; } - Z_FE_POS_P(array) = pos + 1; + Z_FE_POS_P(array) = pos; if (0) { if (!p->key) { ZVAL_LONG(EX_VAR(opline->result.var), p->h); @@ -31434,6 +31432,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_FETCH_R_SIMPLE_ ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value); ZEND_VM_CONTINUE(); } + pos++; value = &p->val; value_type = Z_TYPE_INFO_P(value); if (EXPECTED(value_type != IS_UNDEF)) { @@ -31447,10 +31446,9 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FE_FETCH_R_SIMPLE_ break; } } - pos++; p++; } - Z_FE_POS_P(array) = pos + 1; + Z_FE_POS_P(array) = pos; if (1) { if (!p->key) { ZVAL_LONG(EX_VAR(opline->result.var), p->h); From 54dbd3eccc867f456f257ce11556b50fcbee2ccf Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Wed, 2 Sep 2020 16:43:00 +0200 Subject: [PATCH 11/87] Fix binary-safety of parse_url php_parse_url() is intended to support strings that are not zero terminated. We can't use strcspn in the implementation. As we have two uses of strcspn, add a helper. --- .../tests/url/parse_url_basic_001.phpt | 5 ++++ .../tests/url/parse_url_basic_002.phpt | 1 + .../tests/url/parse_url_basic_003.phpt | 1 + .../tests/url/parse_url_basic_004.phpt | 1 + .../tests/url/parse_url_basic_005.phpt | 1 + .../tests/url/parse_url_basic_006.phpt | 1 + .../tests/url/parse_url_basic_007.phpt | 1 + .../tests/url/parse_url_basic_008.phpt | 1 + .../tests/url/parse_url_basic_009.phpt | 1 + .../tests/url/parse_url_unterminated.phpt | 5 ++++ ext/standard/tests/url/urls.inc | 1 + ext/standard/url.c | 27 ++++++++++--------- 12 files changed, 33 insertions(+), 13 deletions(-) diff --git a/ext/standard/tests/url/parse_url_basic_001.phpt b/ext/standard/tests/url/parse_url_basic_001.phpt index 7340d2432349c..51bae9fe1ca44 100644 --- a/ext/standard/tests/url/parse_url_basic_001.phpt +++ b/ext/standard/tests/url/parse_url_basic_001.phpt @@ -854,6 +854,11 @@ echo "Done"; string(19) "filter={"id":"123"}" } +--> %:x: array(1) { + ["path"]=> + string(3) "%:x" +} + --> http:///blah.com: bool(false) --> http://:80: bool(false) diff --git a/ext/standard/tests/url/parse_url_basic_002.phpt b/ext/standard/tests/url/parse_url_basic_002.phpt index 5f8b6bf145d87..309c038794c45 100644 --- a/ext/standard/tests/url/parse_url_basic_002.phpt +++ b/ext/standard/tests/url/parse_url_basic_002.phpt @@ -112,6 +112,7 @@ echo "Done"; --> : NULL --> / : NULL --> /rest/Users?filter={"id":"123"} : NULL +--> %:x : NULL --> http:///blah.com : bool(false) --> http://:80 : bool(false) --> http://user@:80 : bool(false) diff --git a/ext/standard/tests/url/parse_url_basic_003.phpt b/ext/standard/tests/url/parse_url_basic_003.phpt index bced2757deb61..9649bdadb1238 100644 --- a/ext/standard/tests/url/parse_url_basic_003.phpt +++ b/ext/standard/tests/url/parse_url_basic_003.phpt @@ -111,6 +111,7 @@ echo "Done"; --> : NULL --> / : NULL --> /rest/Users?filter={"id":"123"} : NULL +--> %:x : NULL --> http:///blah.com : bool(false) --> http://:80 : bool(false) --> http://user@:80 : bool(false) diff --git a/ext/standard/tests/url/parse_url_basic_004.phpt b/ext/standard/tests/url/parse_url_basic_004.phpt index f705d408d3693..75aacdf847ada 100644 --- a/ext/standard/tests/url/parse_url_basic_004.phpt +++ b/ext/standard/tests/url/parse_url_basic_004.phpt @@ -111,6 +111,7 @@ echo "Done"; --> : NULL --> / : NULL --> /rest/Users?filter={"id":"123"} : NULL +--> %:x : NULL --> http:///blah.com : bool(false) --> http://:80 : bool(false) --> http://user@:80 : bool(false) diff --git a/ext/standard/tests/url/parse_url_basic_005.phpt b/ext/standard/tests/url/parse_url_basic_005.phpt index dafb784860cb7..1463e0a29ae04 100644 --- a/ext/standard/tests/url/parse_url_basic_005.phpt +++ b/ext/standard/tests/url/parse_url_basic_005.phpt @@ -111,6 +111,7 @@ echo "Done"; --> : NULL --> / : NULL --> /rest/Users?filter={"id":"123"} : NULL +--> %:x : NULL --> http:///blah.com : bool(false) --> http://:80 : bool(false) --> http://user@:80 : bool(false) diff --git a/ext/standard/tests/url/parse_url_basic_006.phpt b/ext/standard/tests/url/parse_url_basic_006.phpt index d881c9527e9bd..78eee265ce4df 100644 --- a/ext/standard/tests/url/parse_url_basic_006.phpt +++ b/ext/standard/tests/url/parse_url_basic_006.phpt @@ -111,6 +111,7 @@ echo "Done"; --> : NULL --> / : NULL --> /rest/Users?filter={"id":"123"} : NULL +--> %:x : NULL --> http:///blah.com : bool(false) --> http://:80 : bool(false) --> http://user@:80 : bool(false) diff --git a/ext/standard/tests/url/parse_url_basic_007.phpt b/ext/standard/tests/url/parse_url_basic_007.phpt index fc5593ea3b44c..85a420c88c910 100644 --- a/ext/standard/tests/url/parse_url_basic_007.phpt +++ b/ext/standard/tests/url/parse_url_basic_007.phpt @@ -111,6 +111,7 @@ echo "Done"; --> : string(0) "" --> / : string(1) "/" --> /rest/Users?filter={"id":"123"} : string(11) "/rest/Users" +--> %:x : string(3) "%:x" --> http:///blah.com : bool(false) --> http://:80 : bool(false) --> http://user@:80 : bool(false) diff --git a/ext/standard/tests/url/parse_url_basic_008.phpt b/ext/standard/tests/url/parse_url_basic_008.phpt index 753432107bffc..75952b2ecd732 100644 --- a/ext/standard/tests/url/parse_url_basic_008.phpt +++ b/ext/standard/tests/url/parse_url_basic_008.phpt @@ -111,6 +111,7 @@ echo "Done"; --> : NULL --> / : NULL --> /rest/Users?filter={"id":"123"} : string(19) "filter={"id":"123"}" +--> %:x : NULL --> http:///blah.com : bool(false) --> http://:80 : bool(false) --> http://user@:80 : bool(false) diff --git a/ext/standard/tests/url/parse_url_basic_009.phpt b/ext/standard/tests/url/parse_url_basic_009.phpt index b5d32b2053a91..ab9232a9a7dd0 100644 --- a/ext/standard/tests/url/parse_url_basic_009.phpt +++ b/ext/standard/tests/url/parse_url_basic_009.phpt @@ -111,6 +111,7 @@ echo "Done"; --> : NULL --> / : NULL --> /rest/Users?filter={"id":"123"} : NULL +--> %:x : NULL --> http:///blah.com : bool(false) --> http://:80 : bool(false) --> http://user@:80 : bool(false) diff --git a/ext/standard/tests/url/parse_url_unterminated.phpt b/ext/standard/tests/url/parse_url_unterminated.phpt index c83e458085a37..6a0cf02745354 100644 --- a/ext/standard/tests/url/parse_url_unterminated.phpt +++ b/ext/standard/tests/url/parse_url_unterminated.phpt @@ -856,6 +856,11 @@ echo "Done"; string(19) "filter={"id":"123"}" } +--> %:x: array(1) { + ["path"]=> + string(3) "%:x" +} + --> http:///blah.com: bool(false) --> http://:80: bool(false) diff --git a/ext/standard/tests/url/urls.inc b/ext/standard/tests/url/urls.inc index b60af2205ec63..199f22caea1d3 100644 --- a/ext/standard/tests/url/urls.inc +++ b/ext/standard/tests/url/urls.inc @@ -91,6 +91,7 @@ $urls = array( '', '/', '/rest/Users?filter={"id":"123"}', +'%:x', // Severely malformed URLs that do not parse: 'http:///blah.com', diff --git a/ext/standard/url.c b/ext/standard/url.c index 20254de0c543c..7763759bc1d0b 100644 --- a/ext/standard/url.c +++ b/ext/standard/url.c @@ -91,6 +91,17 @@ PHPAPI php_url *php_url_parse(char const *str) return php_url_parse_ex(str, strlen(str)); } +static const char *binary_strcspn(const char *s, const char *e, const char *chars) { + while (*chars) { + const char *p = memchr(s, *chars, e - s); + if (p) { + e = p; + } + chars++; + } + return e; +} + /* {{{ php_url_parse */ PHPAPI php_url *php_url_parse_ex(char const *str, size_t length) @@ -109,7 +120,7 @@ PHPAPI php_url *php_url_parse_ex(char const *str, size_t length) while (p < e) { /* scheme = 1*[ lowalpha | digit | "+" | "-" | "." ] */ if (!isalpha(*p) && !isdigit(*p) && *p != '+' && *p != '.' && *p != '-') { - if (e + 1 < ue && e < s + strcspn(s, "?#")) { + if (e + 1 < ue && e < binary_strcspn(s, ue, "?#")) { goto parse_port; } else if (s + 1 < ue && *s == '/' && *(s + 1) == '/') { /* relative-scheme URL */ s += 2; @@ -209,18 +220,8 @@ PHPAPI php_url *php_url_parse_ex(char const *str, size_t length) goto just_path; } - parse_host: - /* Binary-safe strcspn(s, "/?#") */ - e = ue; - if ((p = memchr(s, '/', e - s))) { - e = p; - } - if ((p = memchr(s, '?', e - s))) { - e = p; - } - if ((p = memchr(s, '#', e - s))) { - e = p; - } +parse_host: + e = binary_strcspn(s, ue, "/?#"); /* check for login and password */ if ((p = zend_memrchr(s, '@', (e-s)))) { From 05cd31ef6422d6947b9a1e8de3a39611f6458210 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Wed, 2 Sep 2020 17:05:18 +0200 Subject: [PATCH 12/87] Extend function blacklist in execute fuzzer Add pfsockopen and stream_socket_server. --- sapi/fuzzer/fuzzer-sapi.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sapi/fuzzer/fuzzer-sapi.c b/sapi/fuzzer/fuzzer-sapi.c index e3ac0a3821fd9..3ef0f5fe4ae06 100644 --- a/sapi/fuzzer/fuzzer-sapi.c +++ b/sapi/fuzzer/fuzzer-sapi.c @@ -49,7 +49,9 @@ const char HARDCODED_INI[] = ",shell_exec,exec,system,proc_open,popen,passthru,pcntl_exec" ",chgrp,chmod,chown,copy,file_put_contents,lchgrp,lchown,link,mkdir" ",move_uploaded_file,rename,rmdir,symlink,tempname,touch,unlink,fopen" - ",fsockopen,stream_socket_pair,stream_socket_client" + /* Networking code likes to wait and wait. */ + ",fsockopen,pfsockopen" + ",stream_socket_pair,stream_socket_client,stream_socket_server" /* crypt() can be very slow. */ ",crypt" /* openlog() has a known memory-management issue. */ From 3d1e7d37ebd80698c11923dcf049e75dbe9422d3 Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Wed, 2 Sep 2020 16:57:27 +0200 Subject: [PATCH 13/87] hash: Fix warning in the bench script --- ext/hash/bench.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ext/hash/bench.php b/ext/hash/bench.php index 60c038ca99d44..436390f7d517a 100755 --- a/ext/hash/bench.php +++ b/ext/hash/bench.php @@ -74,6 +74,9 @@ $data = file_get_contents(__FILE__); $time = array(); +foreach (hash_algos() as $algo) { + $time[$algo] = 0; +} for ($j = 0; $j < 10; $j++) { foreach (hash_algos() as $algo) { From 1d84a58736541b61fc9d569580715940e32d55c9 Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Wed, 2 Sep 2020 16:58:44 +0200 Subject: [PATCH 14/87] libmagic: Move the allocation on the stack --- ext/fileinfo/libmagic/softmagic.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ext/fileinfo/libmagic/softmagic.c b/ext/fileinfo/libmagic/softmagic.c index a99e60c5634ca..e71e6cf8324a1 100644 --- a/ext/fileinfo/libmagic/softmagic.c +++ b/ext/fileinfo/libmagic/softmagic.c @@ -479,11 +479,12 @@ check_fmt(struct magic_set *ms, const char *fmt) pcre_cache_entry *pce; int rv = -1; zend_string *pattern; + ALLOCA_FLAG(use_heap) if (strchr(fmt, '%') == NULL) return 0; - pattern = zend_string_init("~%[-0-9\\.]*s~", sizeof("~%[-0-9\\.]*s~") - 1, 0); + ZSTR_ALLOCA_INIT(pattern, "~%[-0-9\\.]*s~", sizeof("~%[-0-9\\.]*s~") - 1, use_heap); if ((pce = pcre_get_compiled_regex_cache_ex(pattern, 0)) == NULL) { rv = -1; } else { @@ -494,7 +495,7 @@ check_fmt(struct magic_set *ms, const char *fmt) php_pcre_free_match_data(match_data); } } - zend_string_release(pattern); + ZSTR_ALLOCA_FREE(pattern, use_heap); return rv; } From 8c31001bf190b511d737e4e915bf5d4678cfed7c Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Wed, 2 Sep 2020 17:04:57 +0200 Subject: [PATCH 15/87] libmagic: Constify arg --- ext/fileinfo/libmagic/file.h | 2 +- ext/fileinfo/libmagic/softmagic.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/fileinfo/libmagic/file.h b/ext/fileinfo/libmagic/file.h index 42a82b8351f6f..ea19faf7d4405 100644 --- a/ext/fileinfo/libmagic/file.h +++ b/ext/fileinfo/libmagic/file.h @@ -525,7 +525,7 @@ protected void buffer_init(struct buffer *, int, const zend_stat_t *, protected void buffer_fini(struct buffer *); protected int buffer_fill(const struct buffer *); -public zend_string* convert_libmagic_pattern(char *val, size_t len, uint32_t options); +public zend_string* convert_libmagic_pattern(const char *val, size_t len, uint32_t options); typedef struct { char *buf; diff --git a/ext/fileinfo/libmagic/softmagic.c b/ext/fileinfo/libmagic/softmagic.c index e71e6cf8324a1..ef60033bbce2e 100644 --- a/ext/fileinfo/libmagic/softmagic.c +++ b/ext/fileinfo/libmagic/softmagic.c @@ -1977,7 +1977,7 @@ file_strncmp16(const char *a, const char *b, size_t len, size_t maxlen, return file_strncmp(a, b, len, maxlen, flags); } -public zend_string* convert_libmagic_pattern(char *val, size_t len, uint32_t options) +public zend_string* convert_libmagic_pattern(const char *val, size_t len, uint32_t options) { int i, j; zend_string *t; From f3f57193553fad35b6bba778d5ce1eabfe824f3f Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Wed, 2 Sep 2020 20:10:02 +0300 Subject: [PATCH 16/87] JIT for FE_FETCH_R --- ext/opcache/jit/zend_jit.c | 10 +++ ext/opcache/jit/zend_jit_trace.c | 34 ++++++++ ext/opcache/jit/zend_jit_x86.dasc | 130 ++++++++++++++++++++++++++++++ 3 files changed, 174 insertions(+) diff --git a/ext/opcache/jit/zend_jit.c b/ext/opcache/jit/zend_jit.c index 7997110c82ffc..98bcdc46d9236 100644 --- a/ext/opcache/jit/zend_jit.c +++ b/ext/opcache/jit/zend_jit.c @@ -2951,6 +2951,16 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op goto jit_failure; } goto done; + case ZEND_FE_FETCH_R: + op1_info = OP1_INFO(); + if ((op1_info & MAY_BE_ANY) != MAY_BE_ARRAY) { + break; + } + if (!zend_jit_fe_fetch(&dasm_state, opline, op_array, ssa, ssa_op, + op1_info, ssa->cfg.blocks[b].successors[0], opline->opcode, NULL)) { + goto jit_failure; + } + goto done; case ZEND_VERIFY_RETURN_TYPE: if (opline->op1_type == IS_UNUSED) { /* Always throws */ diff --git a/ext/opcache/jit/zend_jit_trace.c b/ext/opcache/jit/zend_jit_trace.c index c3c7dbab225f8..66183d97cd048 100644 --- a/ext/opcache/jit/zend_jit_trace.c +++ b/ext/opcache/jit/zend_jit_trace.c @@ -1445,6 +1445,7 @@ static zend_ssa *zend_jit_trace_build_tssa(zend_jit_trace_rec *trace_buffer, uin case ZEND_ECHO: case ZEND_STRLEN: case ZEND_QM_ASSIGN: + case ZEND_FE_FETCH_R: ADD_OP1_TRACE_GUARD(); break; case ZEND_VERIFY_RETURN_TYPE: @@ -4540,6 +4541,39 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par goto jit_failure; } goto done; + case ZEND_FE_FETCH_R: + op1_info = OP1_INFO(); + CHECK_OP1_TRACE_TYPE(); + if ((op1_info & MAY_BE_ANY) != MAY_BE_ARRAY) { + break; + } + if ((p+1)->op == ZEND_JIT_TRACE_VM || (p+1)->op == ZEND_JIT_TRACE_END) { + const zend_op *exit_opline = ZEND_OFFSET_TO_OPLINE(opline, opline->extended_value); + uint32_t exit_point; + + if ((p+1)->opline == exit_opline) { + /* taken branch (exit from loop) */ + exit_opline = opline; + smart_branch_opcode = ZEND_NOP; + } else if ((p+1)->opline == opline + 1) { + /* not taken branch (loop) */ + smart_branch_opcode = ZEND_JMP; + } else { + ZEND_UNREACHABLE(); + } + exit_point = zend_jit_trace_get_exit_point(exit_opline, 0); + exit_addr = zend_jit_trace_get_exit_addr(exit_point); + if (!exit_addr) { + goto jit_failure; + } + } else { + ZEND_UNREACHABLE(); + } + if (!zend_jit_fe_fetch(&dasm_state, opline, op_array, ssa, ssa_op, + op1_info, -1, smart_branch_opcode, exit_addr)) { + goto jit_failure; + } + goto done; case ZEND_INIT_METHOD_CALL: case ZEND_INIT_DYNAMIC_CALL: if (!zend_jit_trace_handler(&dasm_state, op_array, opline, zend_may_throw(opline, ssa_op, op_array, ssa), p + 1)) { diff --git a/ext/opcache/jit/zend_jit_x86.dasc b/ext/opcache/jit/zend_jit_x86.dasc index 09cea053544ff..f19777ab3c4a2 100644 --- a/ext/opcache/jit/zend_jit_x86.dasc +++ b/ext/opcache/jit/zend_jit_x86.dasc @@ -12530,6 +12530,136 @@ static int zend_jit_isset_isempty_cv(dasm_State **Dst, const zend_op *opline, ui return 1; } +static int zend_jit_fe_fetch(dasm_State **Dst, const zend_op *opline, const zend_op_array *op_array, const zend_ssa *ssa, const zend_ssa_op *ssa_op, uint32_t op1_info, unsigned int target_label, zend_uchar exit_opcode, const void *exit_addr) +{ + zend_jit_addr op1_addr = OP1_ADDR(); + + | // array = EX_VAR(opline->op1.var); + | // fe_ht = Z_ARRVAL_P(array); + | GET_ZVAL_PTR FCARG2a, op1_addr + | // pos = Z_FE_POS_P(array); + | mov FCARG1d, dword [FP + opline->op1.var + offsetof(zval, u2.fe_pos)] + | // p = fe_ht->arData + pos; + |.if X64 + | movsxd r0, FCARG1d + | shl r0, 5 + |.else + | imul r0, FCARG1a, sizeof(Bucket) + |.endif + | add r0, aword [FCARG2a + offsetof(zend_array, arData)] + |1: + | // if (UNEXPECTED(pos >= fe_ht->nNumUsed)) { + | cmp dword [FCARG2a + offsetof(zend_array, nNumUsed)], FCARG1d + | // ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value); + | // ZEND_VM_CONTINUE(); + if (exit_addr) { + if (exit_opcode == ZEND_JMP) { + | jbe &exit_addr + } else { + | jbe >3 + } + } else { + | jbe =>target_label + } + | // pos++; + | add FCARG1d, 1 + | // value_type = Z_TYPE_INFO_P(value); + | // if (EXPECTED(value_type != IS_UNDEF)) { + | IF_Z_TYPE r0, IS_UNDEF, >2 + if (!exit_addr || exit_opcode == ZEND_JMP) { + | IF_NOT_Z_TYPE r0, IS_INDIRECT, >3 + } else { + | IF_NOT_Z_TYPE r0, IS_INDIRECT, &exit_addr + } + | // value = Z_INDIRECT_P(value); + | GET_Z_PTR FCARG2a, r0 + | // value_type = Z_TYPE_INFO_P(value); + | // if (EXPECTED(value_type != IS_UNDEF)) { + if (!exit_addr || exit_opcode == ZEND_JMP) { + | IF_NOT_Z_TYPE FCARG2a, IS_UNDEF, >4 + } else { + | IF_NOT_Z_TYPE r0, IS_UNDEF, &exit_addr + } + | GET_ZVAL_PTR FCARG2a, op1_addr // reload + |2: + | // p++; + | add r0, sizeof(Bucket) + | jmp <1 + |3: + + if (!exit_addr || exit_opcode == ZEND_JMP) { + zend_jit_addr val_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FCARG2a, 0); + zend_jit_addr var_addr = OP2_ADDR(); + uint32_t val_info; + + | mov FCARG2a, r0 + |4: + | // Z_FE_POS_P(array) = pos + 1; + | mov dword [FP + opline->op1.var + offsetof(zval, u2.fe_pos)], FCARG1d + + if (RETURN_VALUE_USED(opline)) { + zend_jit_addr res_addr = RES_ADDR(); + + if ((op1_info & MAY_BE_ARRAY_KEY_LONG) + && (op1_info & MAY_BE_ARRAY_KEY_STRING)) { + | // if (!p->key) { + | cmp aword [r0 + offsetof(Bucket, key)], 0 + | jz >2 + } + if (op1_info & MAY_BE_ARRAY_KEY_STRING) { + | // ZVAL_STR_COPY(EX_VAR(opline->result.var), p->key); + | mov FCARG1a, aword [r0 + offsetof(Bucket, key)] + | SET_ZVAL_PTR res_addr, FCARG1a + | test dword [FCARG1a + offsetof(zend_refcounted, gc.u.type_info)], IS_STR_INTERNED + | jz >1 + | SET_ZVAL_TYPE_INFO res_addr, IS_STRING + | jmp >3 + |1: + | GC_ADDREF FCARG1a + | SET_ZVAL_TYPE_INFO res_addr, IS_STRING_EX + + if (op1_info & MAY_BE_ARRAY_KEY_LONG) { + | jmp >3 + |2: + } + } + if (op1_info & MAY_BE_ARRAY_KEY_LONG) { + | // ZVAL_LONG(EX_VAR(opline->result.var), p->h); + | mov FCARG1a, aword [r0 + offsetof(Bucket, h)] + | SET_ZVAL_LVAL res_addr, FCARG1a + | SET_ZVAL_TYPE_INFO res_addr, IS_LONG + } + |3: + } + + val_info = ((op1_info & MAY_BE_ARRAY_OF_ANY) >> MAY_BE_ARRAY_SHIFT); + if (val_info & MAY_BE_ARRAY) { + val_info |= MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_ANY | MAY_BE_ARRAY_OF_REF; + } + if (op1_info & MAY_BE_ARRAY_OF_REF) { + val_info |= MAY_BE_REF | MAY_BE_RC1 | MAY_BE_RCN | MAY_BE_ANY | + MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_ANY | MAY_BE_ARRAY_OF_REF; + } else if (val_info & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE)) { + val_info |= MAY_BE_RC1 | MAY_BE_RCN; + } + + if (opline->op2_type == IS_CV) { + | // zend_assign_to_variable(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES()); + if (!zend_jit_assign_to_variable(Dst, opline, var_addr, var_addr, OP2_INFO(), -1, IS_CV, opline->op2, val_addr, val_info, 0, 1)) { + return 0; + } + } else { + | // ZVAL_COPY(res, value); + | ZVAL_COPY_VALUE var_addr, -1, val_addr, val_info, ZREG_R0, ZREG_FCARG1a + if (val_info & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_REF)) { + | TRY_ADDREF op1_info, ah, FCARG1a + } + } + } + + return 1; +} + static zend_bool zend_jit_noref_guard(dasm_State **Dst, const zend_op *opline, zend_jit_addr var_addr) { int32_t exit_point = zend_jit_trace_get_exit_point(opline, 0); From f2b40775af7165d0f343fe6351e0d468403c111b Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Wed, 2 Sep 2020 20:04:00 +0200 Subject: [PATCH 17/87] Revert "libmagic: Move the allocation on the stack" This reverts commit 1d84a58736541b61fc9d569580715940e32d55c9. Signed-off-by: Anatol Belski --- ext/fileinfo/libmagic/softmagic.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/ext/fileinfo/libmagic/softmagic.c b/ext/fileinfo/libmagic/softmagic.c index ef60033bbce2e..c7a386984bc79 100644 --- a/ext/fileinfo/libmagic/softmagic.c +++ b/ext/fileinfo/libmagic/softmagic.c @@ -479,12 +479,11 @@ check_fmt(struct magic_set *ms, const char *fmt) pcre_cache_entry *pce; int rv = -1; zend_string *pattern; - ALLOCA_FLAG(use_heap) if (strchr(fmt, '%') == NULL) return 0; - ZSTR_ALLOCA_INIT(pattern, "~%[-0-9\\.]*s~", sizeof("~%[-0-9\\.]*s~") - 1, use_heap); + pattern = zend_string_init("~%[-0-9\\.]*s~", sizeof("~%[-0-9\\.]*s~") - 1, 0); if ((pce = pcre_get_compiled_regex_cache_ex(pattern, 0)) == NULL) { rv = -1; } else { @@ -495,7 +494,7 @@ check_fmt(struct magic_set *ms, const char *fmt) php_pcre_free_match_data(match_data); } } - ZSTR_ALLOCA_FREE(pattern, use_heap); + zend_string_release(pattern); return rv; } From 8b37c1e993f17345312a76a239b77ae137d3f8e8 Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Sat, 15 Aug 2020 10:39:00 +0200 Subject: [PATCH 18/87] Change Attribute Syntax from @@ to #[] --- Zend/tests/attributes/001_placement.phpt | 26 +++---- Zend/tests/attributes/002_rfcexample.phpt | 4 +- Zend/tests/attributes/003_ast_nodes.phpt | 12 ++-- .../tests/attributes/004_name_resolution.phpt | 10 +-- Zend/tests/attributes/005_objects.phpt | 20 +++--- Zend/tests/attributes/006_filter.phpt | 16 ++--- .../attributes/008_wrong_attribution.phpt | 2 +- .../009_doctrine_annotations_example.phpt | 24 +++---- .../010_unsupported_const_expression.phpt | 2 +- Zend/tests/attributes/011_inheritance.phpt | 10 +-- Zend/tests/attributes/012_ast_export.phpt | 38 +++++----- Zend/tests/attributes/013_class_scope.phpt | 16 ++--- .../attributes/014_class_const_group.phpt | 2 +- Zend/tests/attributes/015_property_group.phpt | 2 +- .../016_custom_attribute_validation.phpt | 4 +- Zend/tests/attributes/017_closure_scope.phpt | 2 +- .../018_fatal_error_in_argument.phpt | 2 +- .../019_variable_attribute_name.phpt | 2 +- .../020_userland_attribute_validation.phpt | 12 ++-- ...021_attribute_flags_type_is_validated.phpt | 2 +- ...22_attribute_flags_value_is_validated.phpt | 2 +- .../023_ast_node_in_validation.phpt | 2 +- .../024_internal_target_validation.phpt | 2 +- .../025_internal_repeatable_validation.phpt | 4 +- Zend/tests/attributes/026_unpack_in_args.phpt | 2 +- .../attributes/027_trailing_comma_args.phpt | 4 +- Zend/tests/attributes/028_grouped.phpt | 55 +++++++++++++++ Zend/tests/bug79897.phpt | 4 +- Zend/tests/ctor_promotion_attributes.phpt | 2 +- Zend/tests/named_params/attributes.phpt | 6 +- .../attributes_duplicate_named_param.phpt | 2 +- .../named_params/attributes_named_flags.phpt | 4 +- .../attributes_named_flags_incorrect.phpt | 4 +- .../attributes_positional_after_named.phpt | 4 +- .../globalNonSimpleVariableError.phpt | 2 +- Zend/zend_ast.c | 20 ++++-- Zend/zend_ast.h | 1 + Zend/zend_compile.c | 70 ++++++++++--------- Zend/zend_language_parser.y | 13 +++- Zend/zend_language_scanner.l | 3 +- ext/tokenizer/tests/attributes.phpt | 4 +- ext/zend_test/test.c | 2 +- 42 files changed, 251 insertions(+), 169 deletions(-) create mode 100644 Zend/tests/attributes/028_grouped.phpt diff --git a/Zend/tests/attributes/001_placement.phpt b/Zend/tests/attributes/001_placement.phpt index 9bf9c4d2f761f..7de2210460e52 100644 --- a/Zend/tests/attributes/001_placement.phpt +++ b/Zend/tests/attributes/001_placement.phpt @@ -3,27 +3,27 @@ Attributes can be placed on all supported elements. --FILE-- 1; +$f3 = #[A1(10)] fn () => 1; $ref = new \ReflectionClass(Foo::class); @@ -43,11 +43,11 @@ $sources = [ foreach ($sources as $r) { $attr = $r->getAttributes(); var_dump(get_class($r), count($attr)); - + foreach ($attr as $a) { var_dump($a->getName(), $a->getArguments()); } - + echo "\n"; } diff --git a/Zend/tests/attributes/002_rfcexample.phpt b/Zend/tests/attributes/002_rfcexample.phpt index bc608c3eed0d9..8a0abf7878953 100644 --- a/Zend/tests/attributes/002_rfcexample.phpt +++ b/Zend/tests/attributes/002_rfcexample.phpt @@ -6,7 +6,7 @@ Attributes: Example from Attributes RFC namespace My\Attributes { use Attribute; - @@Attribute + #[Attribute] class SingleArgument { public $argumentValue; @@ -19,7 +19,7 @@ namespace My\Attributes { namespace { use My\Attributes\SingleArgument; - @@SingleArgument("Hello World") + #[SingleArgument("Hello World")] class Foo { } diff --git a/Zend/tests/attributes/003_ast_nodes.phpt b/Zend/tests/attributes/003_ast_nodes.phpt index 21125bde13a04..0177804dcc85a 100644 --- a/Zend/tests/attributes/003_ast_nodes.phpt +++ b/Zend/tests/attributes/003_ast_nodes.phpt @@ -5,7 +5,7 @@ Attributes can deal with AST nodes. define('V1', strtoupper(php_sapi_name())); -@@A1([V1 => V1]) +#[A1([V1 => V1])] class C1 { public const BAR = 'bar'; @@ -20,7 +20,7 @@ var_dump(count($args), $args[0][V1] === V1); echo "\n"; -@@A1(V1, 1 + 2, C1::class) +#[A1(V1, 1 + 2, C1::class)] class C2 { } $ref = new \ReflectionClass(C2::class); @@ -35,7 +35,7 @@ var_dump($args[2] === C1::class); echo "\n"; -@@A1(self::FOO, C1::BAR) +#[A1(self::FOO, C1::BAR)] class C3 { private const FOO = 'foo'; @@ -52,20 +52,20 @@ var_dump($args[1] === C1::BAR); echo "\n"; -@@ExampleWithShift(4 >> 1) +#[ExampleWithShift(4 >> 1)] class C4 {} $ref = new \ReflectionClass(C4::class); var_dump($ref->getAttributes()[0]->getArguments()); echo "\n"; -@@Attribute +#[Attribute] class C5 { public function __construct() { } } -$ref = new \ReflectionFunction(@@C5(MissingClass::SOME_CONST) function () { }); +$ref = new \ReflectionFunction(#[C5(MissingClass::SOME_CONST)] function () { }); $attr = $ref->getAttributes(); var_dump(count($attr)); diff --git a/Zend/tests/attributes/004_name_resolution.phpt b/Zend/tests/attributes/004_name_resolution.phpt index 3c0e1190ffec9..6f266908b5c08 100644 --- a/Zend/tests/attributes/004_name_resolution.phpt +++ b/Zend/tests/attributes/004_name_resolution.phpt @@ -25,11 +25,11 @@ namespace Foo { use Doctrine\ORM\Mapping as ORM; use Doctrine\ORM\Attributes; - @@Entity("imported class") - @@ORM\Entity("imported namespace") - @@\Doctrine\ORM\Mapping\Entity("absolute from namespace") - @@\Entity("import absolute from global") - @@Attributes\Table() + #[Entity("imported class")] + #[ORM\Entity("imported namespace")] + #[\Doctrine\ORM\Mapping\Entity("absolute from namespace")] + #[\Entity("import absolute from global")] + #[Attributes\Table()] function foo() { } } diff --git a/Zend/tests/attributes/005_objects.phpt b/Zend/tests/attributes/005_objects.phpt index 83f523182b1b5..206d89fa10ab7 100644 --- a/Zend/tests/attributes/005_objects.phpt +++ b/Zend/tests/attributes/005_objects.phpt @@ -3,7 +3,7 @@ Attributes can be converted into objects. --FILE-- getAttributes() as $attr) { $obj = $attr->newInstance(); @@ -26,7 +26,7 @@ foreach ($ref->getAttributes() as $attr) { echo "\n"; -$ref = new \ReflectionFunction(@@A1 function () { }); +$ref = new \ReflectionFunction(#[A1] function () { }); try { $ref->getAttributes()[0]->newInstance(); @@ -36,7 +36,7 @@ try { echo "\n"; -$ref = new \ReflectionFunction(@@A1([]) function () { }); +$ref = new \ReflectionFunction(#[A1([])] function () { }); try { $ref->getAttributes()[0]->newInstance(); @@ -46,7 +46,7 @@ try { echo "\n"; -$ref = new \ReflectionFunction(@@A2 function () { }); +$ref = new \ReflectionFunction(#[A2] function () { }); try { $ref->getAttributes()[0]->newInstance(); @@ -56,13 +56,13 @@ try { echo "\n"; -@@Attribute +#[Attribute] class A3 { private function __construct() { } } -$ref = new \ReflectionFunction(@@A3 function () { }); +$ref = new \ReflectionFunction(#[A3] function () { }); try { $ref->getAttributes()[0]->newInstance(); @@ -72,10 +72,10 @@ try { echo "\n"; -@@Attribute +#[Attribute] class A4 { } -$ref = new \ReflectionFunction(@@A4(1) function () { }); +$ref = new \ReflectionFunction(#[A4(1)] function () { }); try { $ref->getAttributes()[0]->newInstance(); @@ -87,7 +87,7 @@ echo "\n"; class A5 { } -$ref = new \ReflectionFunction(@@A5 function () { }); +$ref = new \ReflectionFunction(#[A5] function () { }); try { $ref->getAttributes()[0]->newInstance(); diff --git a/Zend/tests/attributes/006_filter.phpt b/Zend/tests/attributes/006_filter.phpt index 69ee146b49f03..8da1ec9bde1e1 100644 --- a/Zend/tests/attributes/006_filter.phpt +++ b/Zend/tests/attributes/006_filter.phpt @@ -3,17 +3,17 @@ Attributes can be filtered by name and base type. --FILE-- getAttributes(A3::class); var_dump(count($attr)); -$ref = new \ReflectionFunction(@@A1 @@A2 function () { }); +$ref = new \ReflectionFunction(#[A1] #[A2] function () { }); $attr = $ref->getAttributes(A2::class); var_dump(count($attr), $attr[0]->getName()); -$ref = new \ReflectionFunction(@@A1 @@A2 @@A2 function () { }); +$ref = new \ReflectionFunction(#[A1] #[A2] #[A2] function () { }); $attr = $ref->getAttributes(A2::class); var_dump(count($attr), $attr[0]->getName(), $attr[1]->getName()); @@ -25,27 +25,27 @@ class A1 implements Base { } class A2 implements Base { } class A3 extends A2 { } -$ref = new \ReflectionFunction(@@A1 @@A2 @@A5 function () { }); +$ref = new \ReflectionFunction(#[A1] #[A2] #[A5] function () { }); $attr = $ref->getAttributes(\stdClass::class, \ReflectionAttribute::IS_INSTANCEOF); var_dump(count($attr)); print_r(array_map(fn ($a) => $a->getName(), $attr)); -$ref = new \ReflectionFunction(@@A1 @@A2 function () { }); +$ref = new \ReflectionFunction(#[A1] #[A2] function () { }); $attr = $ref->getAttributes(A1::class, \ReflectionAttribute::IS_INSTANCEOF); var_dump(count($attr)); print_r(array_map(fn ($a) => $a->getName(), $attr)); -$ref = new \ReflectionFunction(@@A1 @@A2 function () { }); +$ref = new \ReflectionFunction(#[A1] #[A2] function () { }); $attr = $ref->getAttributes(Base::class, \ReflectionAttribute::IS_INSTANCEOF); var_dump(count($attr)); print_r(array_map(fn ($a) => $a->getName(), $attr)); -$ref = new \ReflectionFunction(@@A1 @@A2 @@A3 function () { }); +$ref = new \ReflectionFunction(#[A1] #[A2] #[A3] function () { }); $attr = $ref->getAttributes(A2::class, \ReflectionAttribute::IS_INSTANCEOF); var_dump(count($attr)); print_r(array_map(fn ($a) => $a->getName(), $attr)); -$ref = new \ReflectionFunction(@@A1 @@A2 @@A3 function () { }); +$ref = new \ReflectionFunction(#[A1] #[A2] #[A3] function () { }); $attr = $ref->getAttributes(Base::class, \ReflectionAttribute::IS_INSTANCEOF); var_dump(count($attr)); print_r(array_map(fn ($a) => $a->getName(), $attr)); diff --git a/Zend/tests/attributes/008_wrong_attribution.phpt b/Zend/tests/attributes/008_wrong_attribution.phpt index 5a3ec54a6fd1c..af61bcf105037 100644 --- a/Zend/tests/attributes/008_wrong_attribution.phpt +++ b/Zend/tests/attributes/008_wrong_attribution.phpt @@ -3,7 +3,7 @@ Attributes: Prevent Attribute on non classes --FILE-- --EXPECTF-- diff --git a/Zend/tests/attributes/009_doctrine_annotations_example.phpt b/Zend/tests/attributes/009_doctrine_annotations_example.phpt index 51cb315d487c9..1f2aa647f0a06 100644 --- a/Zend/tests/attributes/009_doctrine_annotations_example.phpt +++ b/Zend/tests/attributes/009_doctrine_annotations_example.phpt @@ -25,22 +25,22 @@ namespace { use Doctrine\ORM\Attributes as ORM; use Symfony\Component\Validator\Constraints as Assert; -@@ORM\Entity +#[ORM\Entity] /** @ORM\Entity */ class User { /** @ORM\Id @ORM\Column(type="integer"*) @ORM\GeneratedValue */ - @@ORM\Id - @@ORM\Column("integer") - @@ORM\GeneratedValue + #[ORM\Id] + #[ORM\Column("integer")] + #[ORM\GeneratedValue] private $id; /** * @ORM\Column(type="string", unique=true) * @Assert\Email(message="The email '{{ value }}' is not a valid email.") */ - @@ORM\Column("string", ORM\Column::UNIQUE) - @@Assert\Email(array("message" => "The email '{{ value }}' is not a valid email.")) + #[ORM\Column("string", ORM\Column::UNIQUE)] + #[Assert\Email(array("message" => "The email '{{ value }}' is not a valid email."))] private $email; /** @@ -52,8 +52,8 @@ class User * maxMessage = "You cannot be taller than {{ limit }}cm to enter" * ) */ - @@Assert\Range(["min" => 120, "max" => 180, "minMessage" => "You must be at least {{ limit }}cm tall to enter"]) - @@ORM\Column(ORM\Column::T_INTEGER) + #[Assert\Range(["min" => 120, "max" => 180, "minMessage" => "You must be at least {{ limit }}cm tall to enter"])] + #[ORM\Column(ORM\Column::T_INTEGER)] protected $height; /** @@ -63,10 +63,10 @@ class User * inverseJoinColumns={@ORM\JoinColumn(name="phonenumber_id", referencedColumnName="id", unique=true)} * ) */ - @@ORM\ManyToMany(Phonenumber::class) - @@ORM\JoinTable("users_phonenumbers") - @@ORM\JoinColumn("user_id", "id") - @@ORM\InverseJoinColumn("phonenumber_id", "id", ORM\JoinColumn::UNIQUE) + #[ORM\ManyToMany(Phonenumber::class)] + #[ORM\JoinTable("users_phonenumbers")] + #[ORM\JoinColumn("user_id", "id")] + #[ORM\InverseJoinColumn("phonenumber_id", "id", ORM\JoinColumn::UNIQUE)] private $phonenumbers; } diff --git a/Zend/tests/attributes/010_unsupported_const_expression.phpt b/Zend/tests/attributes/010_unsupported_const_expression.phpt index fb30e2c486bd5..498898379da83 100644 --- a/Zend/tests/attributes/010_unsupported_const_expression.phpt +++ b/Zend/tests/attributes/010_unsupported_const_expression.phpt @@ -3,7 +3,7 @@ Attribute arguments support only const expressions. --FILE-- diff --git a/Zend/tests/attributes/011_inheritance.phpt b/Zend/tests/attributes/011_inheritance.phpt index 25c943dea30e9..36ee3fa47addf 100644 --- a/Zend/tests/attributes/011_inheritance.phpt +++ b/Zend/tests/attributes/011_inheritance.phpt @@ -3,10 +3,10 @@ Attributes comply with inheritance rules. --FILE-- 1)); +assert(0 && ($a = #[A1(1, 2, 1 + 2)] fn () => 1)); -assert(0 && ($a = new @@A1 class() { - @@A1@@A2 const FOO = 'foo'; - @@A2 public $x; - @@A3 function a() { } +assert(0 && ($a = new #[A1] class() { + #[A1]#[A2] const FOO = 'foo'; + #[A2] public $x; + #[A3] function a() { } })); assert(0 && ($a = function () { - @@A1 class Test1 { } - @@A2 interface Test2 { } - @@A3 trait Test3 { } + #[A1] class Test1 { } + #[A2] interface Test2 { } + #[A3] trait Test3 { } })); ?> --EXPECTF-- -Warning: assert(): assert(0 && ($a = @@A1 @@A2 function ($a, @@A3(1) $b) { +Warning: assert(): assert(0 && ($a = #[A1] #[A2] function ($a, #[A3(1)] $b) { })) failed in %s on line %d -Warning: assert(): assert(0 && ($a = @@A1(1, 2, 1 + 2) fn() => 1)) failed in %s on line %d +Warning: assert(): assert(0 && ($a = #[A1(1, 2, 1 + 2)] fn() => 1)) failed in %s on line %d -Warning: assert(): assert(0 && ($a = new @@A1 class { - @@A1 - @@A2 +Warning: assert(): assert(0 && ($a = new #[A1] class { + #[A1] + #[A2] public const FOO = 'foo'; - @@A2 + #[A2] public $x; - @@A3 + #[A3] public function a() { } })) failed in %s on line %d Warning: assert(): assert(0 && ($a = function () { - @@A1 + #[A1] class Test1 { } - @@A2 + #[A2] interface Test2 { } - @@A3 + #[A3] trait Test3 { } diff --git a/Zend/tests/attributes/013_class_scope.phpt b/Zend/tests/attributes/013_class_scope.phpt index be6c7a60da4f4..61dd9f594c708 100644 --- a/Zend/tests/attributes/013_class_scope.phpt +++ b/Zend/tests/attributes/013_class_scope.phpt @@ -3,17 +3,17 @@ Attributes make use of class scope. --FILE-- --EXPECTF-- -Fatal error: Only classes can be marked with @@ZendTestAttribute in %s +Fatal error: Only classes can be marked with #[ZendTestAttribute] in %s diff --git a/Zend/tests/attributes/017_closure_scope.phpt b/Zend/tests/attributes/017_closure_scope.phpt index 936a8ec338a74..af7de8e2e828b 100644 --- a/Zend/tests/attributes/017_closure_scope.phpt +++ b/Zend/tests/attributes/017_closure_scope.phpt @@ -14,7 +14,7 @@ class C1 public static function foo() { - return @@A1(self::class, self::FOO) function (@@A1(self::class, self::FOO) $p) { }; + return #[A1(self::class, self::FOO)] function (#[A1(self::class, self::FOO)] $p) { }; } } diff --git a/Zend/tests/attributes/018_fatal_error_in_argument.phpt b/Zend/tests/attributes/018_fatal_error_in_argument.phpt index db2719d85a92c..fd031f5c2c2ee 100644 --- a/Zend/tests/attributes/018_fatal_error_in_argument.phpt +++ b/Zend/tests/attributes/018_fatal_error_in_argument.phpt @@ -3,7 +3,7 @@ Don't free uninitialized memory if a fatal error occurs in an attribute argument --FILE-- b::c) +#[Attr(a->b::c)] function test() {} ?> diff --git a/Zend/tests/attributes/019_variable_attribute_name.phpt b/Zend/tests/attributes/019_variable_attribute_name.phpt index 9b8a3c22116df..fe96459bb30f4 100644 --- a/Zend/tests/attributes/019_variable_attribute_name.phpt +++ b/Zend/tests/attributes/019_variable_attribute_name.phpt @@ -3,7 +3,7 @@ Attribute name cannot be a variable --FILE-- diff --git a/Zend/tests/attributes/020_userland_attribute_validation.phpt b/Zend/tests/attributes/020_userland_attribute_validation.phpt index 1025b5008e202..14a10c39b288b 100644 --- a/Zend/tests/attributes/020_userland_attribute_validation.phpt +++ b/Zend/tests/attributes/020_userland_attribute_validation.phpt @@ -3,17 +3,17 @@ Attributes expose and verify target and repeatable data. --FILE-- getAttributes()[0]; var_dump($attr->getName(), $attr->getTarget() == Attribute::TARGET_FUNCTION, $attr->isRepeated()); var_dump(get_class($attr->newInstance())); echo "\n"; -$ref = new \ReflectionObject(new @@A1 class() { }); +$ref = new \ReflectionObject(new #[A1] class() { }); $attr = $ref->getAttributes()[0]; var_dump($attr->getName(), $attr->getTarget() == Attribute::TARGET_CLASS, $attr->isRepeated()); @@ -25,7 +25,7 @@ try { echo "\n"; -$ref = new \ReflectionFunction(@@A1 @@A1 function () { }); +$ref = new \ReflectionFunction(#[A1] #[A1] function () { }); $attr = $ref->getAttributes()[0]; var_dump($attr->getName(), $attr->getTarget() == Attribute::TARGET_FUNCTION, $attr->isRepeated()); @@ -37,10 +37,10 @@ try { echo "\n"; -@@Attribute(Attribute::TARGET_CLASS | Attribute::IS_REPEATABLE) +#[Attribute(Attribute::TARGET_CLASS | Attribute::IS_REPEATABLE)] class A2 { } -$ref = new \ReflectionObject(new @@A2 @@A2 class() { }); +$ref = new \ReflectionObject(new #[A2] #[A2] class() { }); $attr = $ref->getAttributes()[0]; var_dump($attr->getName(), $attr->getTarget() == Attribute::TARGET_CLASS, $attr->isRepeated()); var_dump(get_class($attr->newInstance())); diff --git a/Zend/tests/attributes/021_attribute_flags_type_is_validated.phpt b/Zend/tests/attributes/021_attribute_flags_type_is_validated.phpt index 0f0b915ebe762..7c1bfd2da72bf 100644 --- a/Zend/tests/attributes/021_attribute_flags_type_is_validated.phpt +++ b/Zend/tests/attributes/021_attribute_flags_type_is_validated.phpt @@ -3,7 +3,7 @@ Attribute flags type is validated. --FILE-- diff --git a/Zend/tests/attributes/022_attribute_flags_value_is_validated.phpt b/Zend/tests/attributes/022_attribute_flags_value_is_validated.phpt index 28ad550385d4f..72433a9f13930 100644 --- a/Zend/tests/attributes/022_attribute_flags_value_is_validated.phpt +++ b/Zend/tests/attributes/022_attribute_flags_value_is_validated.phpt @@ -3,7 +3,7 @@ Attribute flags value is validated. --FILE-- diff --git a/Zend/tests/attributes/023_ast_node_in_validation.phpt b/Zend/tests/attributes/023_ast_node_in_validation.phpt index ce44527f62fd5..332d83fe86f61 100644 --- a/Zend/tests/attributes/023_ast_node_in_validation.phpt +++ b/Zend/tests/attributes/023_ast_node_in_validation.phpt @@ -3,7 +3,7 @@ Attribute flags value is validated. --FILE-- diff --git a/Zend/tests/attributes/024_internal_target_validation.phpt b/Zend/tests/attributes/024_internal_target_validation.phpt index 49a5ae68c8b14..e941cf6132ae5 100644 --- a/Zend/tests/attributes/024_internal_target_validation.phpt +++ b/Zend/tests/attributes/024_internal_target_validation.phpt @@ -3,7 +3,7 @@ Internal attribute targets are validated. --FILE-- diff --git a/Zend/tests/attributes/025_internal_repeatable_validation.phpt b/Zend/tests/attributes/025_internal_repeatable_validation.phpt index b3c83e810f2af..671a15fba31f0 100644 --- a/Zend/tests/attributes/025_internal_repeatable_validation.phpt +++ b/Zend/tests/attributes/025_internal_repeatable_validation.phpt @@ -3,8 +3,8 @@ Internal attribute targets are validated. --FILE-- diff --git a/Zend/tests/attributes/026_unpack_in_args.phpt b/Zend/tests/attributes/026_unpack_in_args.phpt index 37f8fb5679aba..d7528b5114cb1 100644 --- a/Zend/tests/attributes/026_unpack_in_args.phpt +++ b/Zend/tests/attributes/026_unpack_in_args.phpt @@ -3,7 +3,7 @@ Cannot use unpacking in attribute argument list --FILE-- diff --git a/Zend/tests/attributes/027_trailing_comma_args.phpt b/Zend/tests/attributes/027_trailing_comma_args.phpt index 5ac47e08a8586..226025f359c2c 100644 --- a/Zend/tests/attributes/027_trailing_comma_args.phpt +++ b/Zend/tests/attributes/027_trailing_comma_args.phpt @@ -3,12 +3,12 @@ Trailing comma in attribute argument list --FILE-- getAttributes(); + var_dump(get_class($ref), count($attr)); + + foreach ($attr as $a) { + printf("%s(%s)\n", $a->getName(), implode(", ", $a->getArguments())); + } + + echo "\n"; +} +?> +--EXPECT-- +string(15) "ReflectionClass" +int(3) +A1(1) +A1(2) +A2(3) + +string(18) "ReflectionFunction" +int(3) +A1(1) +A1(2) +A2(3) + +string(18) "ReflectionFunction" +int(3) +A1() +A1() +A2() diff --git a/Zend/tests/bug79897.phpt b/Zend/tests/bug79897.phpt index ed79318c766e4..19869538a4652 100644 --- a/Zend/tests/bug79897.phpt +++ b/Zend/tests/bug79897.phpt @@ -3,7 +3,7 @@ bug79897: Promoted constructor params with attribs cause crash --FILE-- getAttributes()[0]; diff --git a/Zend/tests/named_params/attributes_duplicate_named_param.phpt b/Zend/tests/named_params/attributes_duplicate_named_param.phpt index bcd9f9b71792b..3c4203a6c7fd1 100644 --- a/Zend/tests/named_params/attributes_duplicate_named_param.phpt +++ b/Zend/tests/named_params/attributes_duplicate_named_param.phpt @@ -3,7 +3,7 @@ Named params in attributes: Duplicate named parameter error --FILE-- diff --git a/Zend/tests/named_params/attributes_named_flags.phpt b/Zend/tests/named_params/attributes_named_flags.phpt index f553aa5308900..fcb08755e3767 100644 --- a/Zend/tests/named_params/attributes_named_flags.phpt +++ b/Zend/tests/named_params/attributes_named_flags.phpt @@ -3,11 +3,11 @@ Named flags parameter for Attribute attribute --FILE-- getAttributes()[0]->newInstance(); diff --git a/Zend/tests/named_params/attributes_named_flags_incorrect.phpt b/Zend/tests/named_params/attributes_named_flags_incorrect.phpt index 6f5b226157b1b..2ad231602f5f1 100644 --- a/Zend/tests/named_params/attributes_named_flags_incorrect.phpt +++ b/Zend/tests/named_params/attributes_named_flags_incorrect.phpt @@ -4,11 +4,11 @@ Named flags parameter for Attribute attribute (incorrect parameter name) getAttributes()[0]->newInstance(); diff --git a/Zend/tests/named_params/attributes_positional_after_named.phpt b/Zend/tests/named_params/attributes_positional_after_named.phpt index 61cee4dc1f2c5..2301635b68964 100644 --- a/Zend/tests/named_params/attributes_positional_after_named.phpt +++ b/Zend/tests/named_params/attributes_positional_after_named.phpt @@ -3,10 +3,10 @@ Named params in attributes: Positional after named error --FILE-- diff --git a/Zend/tests/varSyntax/globalNonSimpleVariableError.phpt b/Zend/tests/varSyntax/globalNonSimpleVariableError.phpt index 6162cbc993ff8..f41840cbb3649 100644 --- a/Zend/tests/varSyntax/globalNonSimpleVariableError.phpt +++ b/Zend/tests/varSyntax/globalNonSimpleVariableError.phpt @@ -7,4 +7,4 @@ global $$foo->bar; ?> --EXPECTF-- -Parse error: syntax error, unexpected token "->", expecting ";" or "," in %s on line %d +Parse error: syntax error, unexpected token "->", expecting "," or ";" in %s on line %d diff --git a/Zend/zend_ast.c b/Zend/zend_ast.c index f746b408a1f84..7932bf597471f 100644 --- a/Zend/zend_ast.c +++ b/Zend/zend_ast.c @@ -1349,19 +1349,20 @@ static ZEND_COLD void zend_ast_export_class_no_header(smart_str *str, zend_ast_d smart_str_appends(str, "}"); } -static ZEND_COLD void zend_ast_export_attributes(smart_str *str, zend_ast *ast, int indent, zend_bool newlines) { +static ZEND_COLD void zend_ast_export_attribute_group(smart_str *str, zend_ast *ast, int indent) { zend_ast_list *list = zend_ast_get_list(ast); - uint32_t i; + uint32_t i, j; for (i = 0; i < list->children; i++) { zend_ast *attr = list->child[i]; - smart_str_appends(str, "@@"); + if (i) { + smart_str_appends(str, ", "); + } zend_ast_export_ns_name(str, attr->child[0], 0, indent); if (attr->child[1]) { zend_ast_list *args = zend_ast_get_list(attr->child[1]); - uint32_t j; smart_str_appendc(str, '('); for (j = 0; j < args->children; j++) { @@ -1372,6 +1373,17 @@ static ZEND_COLD void zend_ast_export_attributes(smart_str *str, zend_ast *ast, } smart_str_appendc(str, ')'); } + } +} + +static ZEND_COLD void zend_ast_export_attributes(smart_str *str, zend_ast *ast, int indent, zend_bool newlines) { + zend_ast_list *list = zend_ast_get_list(ast); + uint32_t i; + + for (i = 0; i < list->children; i++) { + smart_str_appends(str, "#["); + zend_ast_export_attribute_group(str, list->child[i], indent); + smart_str_appends(str, "]"); if (newlines) { smart_str_appendc(str, '\n'); diff --git a/Zend/zend_ast.h b/Zend/zend_ast.h index 2d72759c392a4..eb02e9bea0c38 100644 --- a/Zend/zend_ast.h +++ b/Zend/zend_ast.h @@ -63,6 +63,7 @@ enum _zend_ast_kind { ZEND_AST_USE, ZEND_AST_TYPE_UNION, ZEND_AST_ATTRIBUTE_LIST, + ZEND_AST_ATTRIBUTE_GROUP, ZEND_AST_MATCH_ARM_LIST, /* 0 child nodes */ diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 8d76148fc2a33..c403a1f54e3a1 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -6214,51 +6214,57 @@ static void zend_compile_attributes(HashTable **attributes, zend_ast *ast, uint3 zend_internal_attribute *config; zend_ast_list *list = zend_ast_get_list(ast); - uint32_t i, j; + uint32_t g, i, j; ZEND_ASSERT(ast->kind == ZEND_AST_ATTRIBUTE_LIST); - for (i = 0; i < list->children; i++) { - ZEND_ASSERT(list->child[i]->kind == ZEND_AST_ATTRIBUTE); + for (g = 0; g < list->children; g++) { + zend_ast_list *group = zend_ast_get_list(list->child[g]); - zend_ast *el = list->child[i]; - zend_string *name = zend_resolve_class_name_ast(el->child[0]); - zend_ast_list *args = el->child[1] ? zend_ast_get_list(el->child[1]) : NULL; + ZEND_ASSERT(group->kind == ZEND_AST_ATTRIBUTE_GROUP); - attr = zend_add_attribute(attributes, 0, offset, name, args ? args->children : 0); - zend_string_release(name); + for (i = 0; i < group->children; i++) { + ZEND_ASSERT(group->child[i]->kind == ZEND_AST_ATTRIBUTE); - /* Populate arguments */ - if (args) { - ZEND_ASSERT(args->kind == ZEND_AST_ARG_LIST); + zend_ast *el = group->child[i]; + zend_string *name = zend_resolve_class_name_ast(el->child[0]); + zend_ast_list *args = el->child[1] ? zend_ast_get_list(el->child[1]) : NULL; - zend_bool uses_named_args = 0; - for (j = 0; j < args->children; j++) { - zend_ast *arg_ast = args->child[j]; + attr = zend_add_attribute(attributes, 0, offset, name, args ? args->children : 0); + zend_string_release(name); - if (arg_ast->kind == ZEND_AST_UNPACK) { - zend_error_noreturn(E_COMPILE_ERROR, - "Cannot use unpacking in attribute argument list"); - } + /* Populate arguments */ + if (args) { + ZEND_ASSERT(args->kind == ZEND_AST_ARG_LIST); - if (arg_ast->kind == ZEND_AST_NAMED_ARG) { - attr->args[j].name = zend_string_copy(zend_ast_get_str(arg_ast->child[0])); - arg_ast = arg_ast->child[1]; - uses_named_args = 1; + zend_bool uses_named_args = 0; + for (j = 0; j < args->children; j++) { + zend_ast *arg_ast = args->child[j]; - for (uint32_t k = 0; k < j; k++) { - if (attr->args[k].name && - zend_string_equals(attr->args[k].name, attr->args[j].name)) { - zend_error_noreturn(E_COMPILE_ERROR, "Duplicate named parameter $%s", - ZSTR_VAL(attr->args[j].name)); + if (arg_ast->kind == ZEND_AST_UNPACK) { + zend_error_noreturn(E_COMPILE_ERROR, + "Cannot use unpacking in attribute argument list"); + } + + if (arg_ast->kind == ZEND_AST_NAMED_ARG) { + attr->args[j].name = zend_string_copy(zend_ast_get_str(arg_ast->child[0])); + arg_ast = arg_ast->child[1]; + uses_named_args = 1; + + for (uint32_t k = 0; k < j; k++) { + if (attr->args[k].name && + zend_string_equals(attr->args[k].name, attr->args[j].name)) { + zend_error_noreturn(E_COMPILE_ERROR, "Duplicate named parameter $%s", + ZSTR_VAL(attr->args[j].name)); + } } + } else if (uses_named_args) { + zend_error_noreturn(E_COMPILE_ERROR, + "Cannot use positional argument after named argument"); } - } else if (uses_named_args) { - zend_error_noreturn(E_COMPILE_ERROR, - "Cannot use positional argument after named argument"); - } - zend_const_expr_to_zval(&attr->args[j].value, arg_ast); + zend_const_expr_to_zval(&attr->args[j].value, arg_ast); + } } } } diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y index 1a566e352d2d9..ed800c46f867e 100644 --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@ -178,7 +178,7 @@ static YYSIZE_T zend_yytnamerr(char*, const char*); %token T_NS_C "'__NAMESPACE__'" %token END 0 "end of file" -%token T_ATTRIBUTE "'@@'" +%token T_ATTRIBUTE "'#['" %token T_PLUS_EQUAL "'+='" %token T_MINUS_EQUAL "'-='" %token T_MUL_EQUAL "'*='" @@ -266,7 +266,7 @@ static YYSIZE_T zend_yytnamerr(char*, const char*); %type identifier type_expr_without_static union_type_without_static %type inline_function union_type %type attributed_statement attributed_class_statement attributed_parameter -%type attribute_decl attribute attributes namespace_declaration_name +%type attribute_decl attribute attributes attribute_group namespace_declaration_name %type match match_arm_list non_empty_match_arm_list match_arm match_arm_cond_list %type returns_ref function fn is_reference is_variadic variable_modifiers @@ -345,8 +345,15 @@ attribute_decl: { $$ = zend_ast_create(ZEND_AST_ATTRIBUTE, $1, $2); } ; +attribute_group: + attribute_decl + { $$ = zend_ast_create_list(1, ZEND_AST_ATTRIBUTE_GROUP, $1); } + | attribute_group ',' attribute_decl + { $$ = zend_ast_list_add($1, $3); } +; + attribute: - T_ATTRIBUTE attribute_decl { $$ = $2; } + T_ATTRIBUTE attribute_group possible_comma ']' { $$ = $2; } ; attributes: diff --git a/Zend/zend_language_scanner.l b/Zend/zend_language_scanner.l index ee88282fd5176..b00e4e3edb61a 100644 --- a/Zend/zend_language_scanner.l +++ b/Zend/zend_language_scanner.l @@ -1411,7 +1411,8 @@ NEWLINE ("\r"|"\n"|"\r\n") RETURN_TOKEN_WITH_IDENT(T_RETURN); } -"@@" { +"#[" { + enter_nesting('['); RETURN_TOKEN(T_ATTRIBUTE); } diff --git a/ext/tokenizer/tests/attributes.phpt b/ext/tokenizer/tests/attributes.phpt index 8795a4c5dcddf..f4211ca769a17 100644 --- a/ext/tokenizer/tests/attributes.phpt +++ b/ext/tokenizer/tests/attributes.phpt @@ -3,7 +3,7 @@ Attributes are exposed as tokens. --FILE-- Date: Wed, 2 Sep 2020 20:32:52 +0200 Subject: [PATCH 19/87] Update NEWS, UPGRADING --- NEWS | 3 +++ UPGRADING | 9 +++++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/NEWS b/NEWS index 590ddd3226768..045e7b72f0009 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,9 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? ????, PHP 8.0.0rc1 +- Core: + . Implement #[Attr] Attribute syntax as per final vote in RFC + https://wiki.php.net/rfc/shorter_attribute_syntax_change 03 Sep 2020, PHP 8.0.0beta3 diff --git a/UPGRADING b/UPGRADING index 2412b60865f5e..d18bc98eeb0e5 100644 --- a/UPGRADING +++ b/UPGRADING @@ -81,10 +81,10 @@ PHP 8.0 UPGRADE NOTES Additionally, care should be taken that error messages are not displayed in production environments, which can result in information leaks. Please ensure that display_errors=Off is used in conjunction with error logging. - . Adding more than one @ operator to an expression is no longer supported, - since this syntax is now used for attributes (previously extra @ operators - had no effect). - RFC: https://wiki.php.net/rfc/shorter_attribute_syntax + . Following the hash comment operator # immediately with an opening bracket + is not supported as a comment anymore since this syntax is now used for + attributes. + RFC: https://wiki.php.net/rfc/shorter_attribute_syntax_change . Inheritance errors due to incompatible method signatures (LSP violations) will now always generate a fatal error. Previously a warning was generated in some cases. @@ -687,6 +687,7 @@ PHP 8.0 UPGRADE NOTES RFC: https://wiki.php.net/rfc/attributes_v2 RFC: https://wiki.php.net/rfc/attribute_amendments RFC: https://wiki.php.net/rfc/shorter_attribute_syntax + RFC: https://wiki.php.net/rfc/shorter_attribute_syntax_change . Added support for constructor property promotion (declaring properties in the constructor signature). RFC: https://wiki.php.net/rfc/constructor_promotion From 73dcfb6faa0a2ee9781de9a9af937b8752c265b6 Mon Sep 17 00:00:00 2001 From: Alex Dowad Date: Thu, 30 Jul 2020 22:08:25 +0200 Subject: [PATCH 20/87] Fix typos in mbstring tests Man, I can be pedantic sometimes. Tiny little things like misspelled words just hurt me inside. So while it's not really a big deal, I couldn't leave these typos alone... --- ext/mbstring/tests/bug46806.phpt | 2 +- ext/mbstring/tests/bug77428.phpt | 2 +- ext/mbstring/tests/casemapping.phpt | 2 +- ext/mbstring/tests/mb_convert_encoding.phpt | 4 ++-- ext/mbstring/tests/mb_convert_variables.phpt | 12 ++++++------ ext/mbstring/tests/mb_detect_encoding.phpt | 4 ++-- ext/mbstring/tests/mb_encode_mimeheader_basic3.phpt | 4 ++-- 7 files changed, 15 insertions(+), 15 deletions(-) diff --git a/ext/mbstring/tests/bug46806.phpt b/ext/mbstring/tests/bug46806.phpt index ea00035c0f92c..5165705a9f768 100644 --- a/ext/mbstring/tests/bug46806.phpt +++ b/ext/mbstring/tests/bug46806.phpt @@ -1,5 +1,5 @@ --TEST-- -Bug #46806 (mb_wtrimwidth cutting to early) +Bug #46806 (mb_strimwidth cutting too early) --CREDITS-- Sebastian Schürmann sebs@php.net diff --git a/ext/mbstring/tests/bug77428.phpt b/ext/mbstring/tests/bug77428.phpt index d387f34b771fa..82a2574b1ab10 100644 --- a/ext/mbstring/tests/bug77428.phpt +++ b/ext/mbstring/tests/bug77428.phpt @@ -10,7 +10,7 @@ if (!function_exists('mb_ereg_replace')) die('skip mb_ereg_replace() not availab // This behavior is broken, but kept for BC reasons var_dump(mb_ereg_replace('(%)', '\\\1', 'a%c')); -// For clarify, the above line is equivalent to: +// For clarity, the above line is equivalent to: var_dump(mb_ereg_replace('(%)', '\\\\1', 'a%c')); ?> diff --git a/ext/mbstring/tests/casemapping.phpt b/ext/mbstring/tests/casemapping.phpt index 3e2838392bf54..df5e07bdfed0d 100644 --- a/ext/mbstring/tests/casemapping.phpt +++ b/ext/mbstring/tests/casemapping.phpt @@ -23,7 +23,7 @@ toCases("ff"); toCases("İ"); // Make sure that case-conversion in Turkish still works correctly. -// Using the language-agnostic Unicode case mappins would result in +// Using the language-agnostic Unicode case mappings would result in // characters that are illegal under ISO-8859-9. mb_internal_encoding('ISO-8859-9'); diff --git a/ext/mbstring/tests/mb_convert_encoding.phpt b/ext/mbstring/tests/mb_convert_encoding.phpt index 31d8db5f4a1e6..40b1dfed882b3 100644 --- a/ext/mbstring/tests/mb_convert_encoding.phpt +++ b/ext/mbstring/tests/mb_convert_encoding.phpt @@ -16,8 +16,8 @@ $jis = base64_decode('GyRCRnxLXDhsJUYlLSU5JUgkRyQ5ISMbKEIwMTIzNBskQiM1IzYjNyM4Iz // EUC-JP string $euc_jp = 'ܸƥȤǤ01234'; -// Test with sigle "form encoding" -// Note: For some reason it complains, results are differ. Not reserched. +// Test with single "form encoding" +// Note: For some reason it complains, results are different. Not researched. echo "== BASIC TEST ==\n"; $s = $sjis; $s = mb_convert_encoding($s, 'EUC-JP', 'SJIS'); diff --git a/ext/mbstring/tests/mb_convert_variables.phpt b/ext/mbstring/tests/mb_convert_variables.phpt index 830c6a7cd0dc5..bf8b59f3503f6 100644 --- a/ext/mbstring/tests/mb_convert_variables.phpt +++ b/ext/mbstring/tests/mb_convert_variables.phpt @@ -19,8 +19,8 @@ $jis = base64_decode('GyRCRnxLXDhsJUYlLSU5JUgkRyQ5ISMbKEIwMTIzNBskQiM1IzYjNyM4Iz // EUC-JP string $euc_jp = 'ܸƥȤǤ01234'; -// Test for single scaler -echo "== SCALER TEST ==\n"; +// Test for single scalar +echo "== SCALAR TEST ==\n"; $s = $sjis; $encoding = mb_convert_variables('EUC-JP', 'SJIS', $s); print("$encoding\n"); // SJIS @@ -116,8 +116,8 @@ print("$encoding\n"); // EUC-JP print("{$oo->s1}{$oo->s2}{$oo->s3}\n"); // Converted to EUC-JP -// Test for scaler, array and object -echo "== SCALER, ARRAY AND OBJECT TEST ==\n"; +// Test for scalar, array and object +echo "== SCALAR, ARRAY AND OBJECT TEST ==\n"; $s1 = $euc_jp; $s2 = $euc_jp; @@ -134,7 +134,7 @@ print("{$oo->s1}{$oo->s2}{$oo->s3}\n"); // Converted to EUC-JP ?> --EXPECT-- -== SCALER TEST == +== SCALAR TEST == SJIS ܸƥȤǤ01234 JIS @@ -155,7 +155,7 @@ EUC-JP ܸƥȤǤ01234ܸƥȤǤ01234ܸƥȤǤ01234 EUC-JP ܸƥȤǤ01234ܸƥȤǤ01234ܸƥȤǤ01234 -== SCALER, ARRAY AND OBJECT TEST == +== SCALAR, ARRAY AND OBJECT TEST == EUC-JP ܸƥȤǤ01234ܸƥȤǤ01234ܸƥȤǤ01234 ܸƥȤǤ01234ܸƥȤǤ01234ܸƥȤǤ01234 diff --git a/ext/mbstring/tests/mb_detect_encoding.phpt b/ext/mbstring/tests/mb_detect_encoding.phpt index 22f64fcfa56e0..2134f3c8b578a 100644 --- a/ext/mbstring/tests/mb_detect_encoding.phpt +++ b/ext/mbstring/tests/mb_detect_encoding.phpt @@ -15,8 +15,8 @@ $jis = base64_decode('GyRCRnxLXDhsJUYlLSU5JUgkRyQ5ISMbKEIwMTIzNBskQiM1IzYjNyM4Iz // EUC-JP string $euc_jp = 'ܸƥȤǤ01234'; -// Test with sigle "form encoding" -// Note: For some reason it complains, results are differ. Not reserched. +// Test with single "form encoding" +// Note: For some reason it complains, results are different. Not researched. echo "== BASIC TEST ==\n"; $s = $sjis; $s = mb_detect_encoding($s, 'SJIS'); diff --git a/ext/mbstring/tests/mb_encode_mimeheader_basic3.phpt b/ext/mbstring/tests/mb_encode_mimeheader_basic3.phpt index 655a5b059c3d6..9495305c799e9 100644 --- a/ext/mbstring/tests/mb_encode_mimeheader_basic3.phpt +++ b/ext/mbstring/tests/mb_encode_mimeheader_basic3.phpt @@ -11,7 +11,7 @@ function_exists('mb_encode_mimeheader') or die("skip mb_encode_mimeheader() is n * Test mb_encode_header() with different strings */ -echo "*** Testing mb_encode_mimeheader() : basic2 ***\n"; +echo "*** Testing mb_encode_mimeheader() : basic3 ***\n"; //All strings are the same when displayed in their respective encodings $sjis_string = base64_decode('k/qWe4zqg2WDTINYg2eCxYK3gUIwMTIzNIJUglWCVoJXgliBQg=='); @@ -35,7 +35,7 @@ foreach ($inputs as $lang => $input) { echo "Done"; ?> --EXPECT-- -*** Testing mb_encode_mimeheader() : basic2 *** +*** Testing mb_encode_mimeheader() : basic3 *** Language: SJIS -- Base 64: -- From e64c386b6256aac05c9b9fd64b86361109d07a9b Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Wed, 2 Sep 2020 21:25:00 +0200 Subject: [PATCH 21/87] libmagic: Update patch [ci skip] Signed-off-by: Anatol Belski --- ext/fileinfo/libmagic.patch | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ext/fileinfo/libmagic.patch b/ext/fileinfo/libmagic.patch index 9e32576d461ca..54ee11378dbca 100644 --- a/ext/fileinfo/libmagic.patch +++ b/ext/fileinfo/libmagic.patch @@ -1702,7 +1702,7 @@ diff -ur libmagic.orig/encoding.c libmagic/encoding.c return 0; diff -ur libmagic.orig/file.h libmagic/file.h --- libmagic.orig/file.h 2020-06-15 02:01:01.000000000 +0200 -+++ libmagic/file.h 2020-08-29 11:56:12.303522747 +0200 ++++ libmagic/file.h 2020-09-02 17:35:51.709611515 +0200 @@ -33,17 +33,13 @@ #ifndef __file_h__ #define __file_h__ @@ -1900,7 +1900,7 @@ diff -ur libmagic.orig/file.h libmagic/file.h - int); -protected void file_regfree(file_regex_t *); -protected void file_regerror(file_regex_t *, int, struct magic_set *); -+public zend_string* convert_libmagic_pattern(char *val, size_t len, uint32_t options); ++public zend_string* convert_libmagic_pattern(const char *val, size_t len, uint32_t options); typedef struct { char *buf; @@ -3333,7 +3333,7 @@ diff -ur libmagic.orig/readcdf.c libmagic/readcdf.c if (i != -1) diff -ur libmagic.orig/softmagic.c libmagic/softmagic.c --- libmagic.orig/softmagic.c 2020-06-15 02:01:01.000000000 +0200 -+++ libmagic/softmagic.c 2020-08-29 11:56:13.219516523 +0200 ++++ libmagic/softmagic.c 2020-09-02 20:04:00.794667114 +0200 @@ -43,6 +43,10 @@ #include #include "der.h" @@ -3495,7 +3495,7 @@ diff -ur libmagic.orig/softmagic.c libmagic/softmagic.c return file_strncmp(a, b, len, maxlen, flags); } -+public zend_string* convert_libmagic_pattern(char *val, size_t len, uint32_t options) ++public zend_string* convert_libmagic_pattern(const char *val, size_t len, uint32_t options) +{ + int i, j; + zend_string *t; From 508f8285e2981a51b898676adf43098f9357f9be Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Wed, 2 Sep 2020 23:16:58 +0300 Subject: [PATCH 22/87] Reorder switch cases for consistency between zend_jit() and zend_jit_trace() --- ext/opcache/jit/zend_jit.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/ext/opcache/jit/zend_jit.c b/ext/opcache/jit/zend_jit.c index 98bcdc46d9236..ea5bbfb33993a 100644 --- a/ext/opcache/jit/zend_jit.c +++ b/ext/opcache/jit/zend_jit.c @@ -2951,16 +2951,6 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op goto jit_failure; } goto done; - case ZEND_FE_FETCH_R: - op1_info = OP1_INFO(); - if ((op1_info & MAY_BE_ANY) != MAY_BE_ARRAY) { - break; - } - if (!zend_jit_fe_fetch(&dasm_state, opline, op_array, ssa, ssa_op, - op1_info, ssa->cfg.blocks[b].successors[0], opline->opcode, NULL)) { - goto jit_failure; - } - goto done; case ZEND_VERIFY_RETURN_TYPE: if (opline->op1_type == IS_UNUSED) { /* Always throws */ @@ -2982,6 +2972,16 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op goto jit_failure; } goto done; + case ZEND_FE_FETCH_R: + op1_info = OP1_INFO(); + if ((op1_info & MAY_BE_ANY) != MAY_BE_ARRAY) { + break; + } + if (!zend_jit_fe_fetch(&dasm_state, opline, op_array, ssa, ssa_op, + op1_info, ssa->cfg.blocks[b].successors[0], opline->opcode, NULL)) { + goto jit_failure; + } + goto done; default: break; } From 91edb907676805bc4fad3ebc758dd6d797c92a63 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Thu, 3 Sep 2020 00:51:43 +0300 Subject: [PATCH 23/87] JIT for FETCH_CONSTANT --- ext/opcache/jit/zend_jit.c | 5 ++++ ext/opcache/jit/zend_jit_disasm_x86.c | 1 + ext/opcache/jit/zend_jit_internal.h | 4 +-- ext/opcache/jit/zend_jit_trace.c | 5 ++++ ext/opcache/jit/zend_jit_vm_helpers.c | 4 +-- ext/opcache/jit/zend_jit_x86.dasc | 41 +++++++++++++++++++++++++-- 6 files changed, 53 insertions(+), 7 deletions(-) diff --git a/ext/opcache/jit/zend_jit.c b/ext/opcache/jit/zend_jit.c index ea5bbfb33993a..56260c9105fee 100644 --- a/ext/opcache/jit/zend_jit.c +++ b/ext/opcache/jit/zend_jit.c @@ -2982,6 +2982,11 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op goto jit_failure; } goto done; + case ZEND_FETCH_CONSTANT: + if (!zend_jit_fetch_constant(&dasm_state, opline)) { + goto jit_failure; + } + goto done; default: break; } diff --git a/ext/opcache/jit/zend_jit_disasm_x86.c b/ext/opcache/jit/zend_jit_disasm_x86.c index ce8eec6ebf2fe..bd737fa669732 100644 --- a/ext/opcache/jit/zend_jit_disasm_x86.c +++ b/ext/opcache/jit/zend_jit_disasm_x86.c @@ -459,6 +459,7 @@ static int zend_jit_disasm_init(void) REGISTER_HELPER(zend_runtime_jit); REGISTER_HELPER(zend_jit_hot_func); REGISTER_HELPER(zend_jit_check_constant); + REGISTER_HELPER(zend_jit_get_constant); REGISTER_HELPER(zend_jit_array_free); REGISTER_HELPER(zend_jit_zval_array_dup); REGISTER_HELPER(zend_jit_add_arrays_helper); diff --git a/ext/opcache/jit/zend_jit_internal.h b/ext/opcache/jit/zend_jit_internal.h index 1f4b36cb62797..bcbafad147986 100644 --- a/ext/opcache/jit/zend_jit_internal.h +++ b/ext/opcache/jit/zend_jit_internal.h @@ -130,8 +130,8 @@ ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_jit_loop_counter_helper(ZEND_OPCODE_H void ZEND_FASTCALL zend_jit_copy_extra_args_helper(EXECUTE_DATA_D); zend_bool ZEND_FASTCALL zend_jit_deprecated_helper(OPLINE_D); -void ZEND_FASTCALL zend_jit_get_constant(const zval *key, uint32_t flags); -int ZEND_FASTCALL zend_jit_check_constant(const zval *key); +int ZEND_FASTCALL zend_jit_get_constant(const zval *key, uint32_t flags); +int ZEND_FASTCALL zend_jit_check_constant(const zval *key); /* Tracer */ #define zend_jit_opline_hash(opline) \ diff --git a/ext/opcache/jit/zend_jit_trace.c b/ext/opcache/jit/zend_jit_trace.c index 66183d97cd048..7d3c7be1aa53d 100644 --- a/ext/opcache/jit/zend_jit_trace.c +++ b/ext/opcache/jit/zend_jit_trace.c @@ -4574,6 +4574,11 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par goto jit_failure; } goto done; + case ZEND_FETCH_CONSTANT: + if (!zend_jit_fetch_constant(&dasm_state, opline)) { + goto jit_failure; + } + goto done; case ZEND_INIT_METHOD_CALL: case ZEND_INIT_DYNAMIC_CALL: if (!zend_jit_trace_handler(&dasm_state, op_array, opline, zend_may_throw(opline, ssa_op, op_array, ssa), p + 1)) { diff --git a/ext/opcache/jit/zend_jit_vm_helpers.c b/ext/opcache/jit/zend_jit_vm_helpers.c index 729c64073d5e8..09a99811846f3 100644 --- a/ext/opcache/jit/zend_jit_vm_helpers.c +++ b/ext/opcache/jit/zend_jit_vm_helpers.c @@ -278,9 +278,9 @@ static zend_always_inline int _zend_quick_get_constant( return SUCCESS; } -void ZEND_FASTCALL zend_jit_get_constant(const zval *key, uint32_t flags) +int ZEND_FASTCALL zend_jit_get_constant(const zval *key, uint32_t flags) { - _zend_quick_get_constant(key, flags, 0); + return _zend_quick_get_constant(key, flags, 0); } int ZEND_FASTCALL zend_jit_check_constant(const zval *key) diff --git a/ext/opcache/jit/zend_jit_x86.dasc b/ext/opcache/jit/zend_jit_x86.dasc index f19777ab3c4a2..a863fed69e885 100644 --- a/ext/opcache/jit/zend_jit_x86.dasc +++ b/ext/opcache/jit/zend_jit_x86.dasc @@ -12651,15 +12651,50 @@ static int zend_jit_fe_fetch(dasm_State **Dst, const zend_op *opline, const zend } else { | // ZVAL_COPY(res, value); | ZVAL_COPY_VALUE var_addr, -1, val_addr, val_info, ZREG_R0, ZREG_FCARG1a - if (val_info & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_REF)) { - | TRY_ADDREF op1_info, ah, FCARG1a - } + | TRY_ADDREF val_info, ah, FCARG1a } } return 1; } +static int zend_jit_fetch_constant(dasm_State **Dst, const zend_op *opline) +{ + zval *zv = RT_CONSTANT(opline, opline->op2) + 1; + zend_jit_addr res_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FP, opline->result.var); + zend_jit_addr const_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FCARG1a, 0); + + | // c = CACHED_PTR(opline->extended_value); + | mov FCARG1a, EX->run_time_cache + | mov FCARG1a, aword [FCARG1a + opline->extended_value] + | // if (c != NULL) + | test FCARG1a, FCARG1a + | jz >9 + | // if (!IS_SPECIAL_CACHE_VAL(c)) + | test FCARG1a, CACHE_SPECIAL + | jnz >9 + | // ZVAL_COPY_OR_DUP(EX_VAR(opline->result.var), &c->value); (no dup) + | ZVAL_COPY_VALUE res_addr, MAY_BE_ANY, const_addr, MAY_BE_ANY, ZREG_R0, ZREG_FCARG2a + | TRY_ADDREF MAY_BE_ANY, ah, FCARG2a + |8: + + |.cold_code + |9: + | // SAVE_OPLINE(); + | SAVE_VALID_OPLINE opline, r0 + | // zend_quick_get_constant(RT_CONSTANT(opline, opline->op2) + 1, opline->op1.num OPLINE_CC EXECUTE_DATA_CC); + | LOAD_ADDR FCARG1a, zv + | mov FCARG2a, opline->op1.num + | EXT_CALL zend_jit_get_constant, r0 + | // ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + | test r0, r0 + | jz <8 + | jmp ->exception_handler + |.code + + return 1; +} + static zend_bool zend_jit_noref_guard(dasm_State **Dst, const zend_op *opline, zend_jit_addr var_addr) { int32_t exit_point = zend_jit_trace_get_exit_point(opline, 0); From 573ad182d21df2457a0a2f6fd3c075e1f0bfca44 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Thu, 3 Sep 2020 09:45:54 +0200 Subject: [PATCH 24/87] Handle memory limit error during string reallocation correctly Do not decrement the refcount before allocating the new string, as the allocation operation may bail out and cause a use-after-free lateron. We can only decrement the refcount once the allocation has succeeded. Fixes oss-fuzz #25384. --- Zend/zend_string.h | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/Zend/zend_string.h b/Zend/zend_string.h index c95578d4a5247..396b63b26653f 100644 --- a/Zend/zend_string.h +++ b/Zend/zend_string.h @@ -186,12 +186,13 @@ static zend_always_inline zend_string *zend_string_realloc(zend_string *s, size_ ZSTR_LEN(ret) = len; zend_string_forget_hash_val(ret); return ret; - } else { - GC_DELREF(s); } } ret = zend_string_alloc(len, persistent); memcpy(ZSTR_VAL(ret), ZSTR_VAL(s), MIN(len, ZSTR_LEN(s)) + 1); + if (!ZSTR_IS_INTERNED(s)) { + GC_DELREF(s); + } return ret; } @@ -206,12 +207,13 @@ static zend_always_inline zend_string *zend_string_extend(zend_string *s, size_t ZSTR_LEN(ret) = len; zend_string_forget_hash_val(ret); return ret; - } else { - GC_DELREF(s); } } ret = zend_string_alloc(len, persistent); memcpy(ZSTR_VAL(ret), ZSTR_VAL(s), ZSTR_LEN(s) + 1); + if (!ZSTR_IS_INTERNED(s)) { + GC_DELREF(s); + } return ret; } @@ -226,12 +228,13 @@ static zend_always_inline zend_string *zend_string_truncate(zend_string *s, size ZSTR_LEN(ret) = len; zend_string_forget_hash_val(ret); return ret; - } else { - GC_DELREF(s); } } ret = zend_string_alloc(len, persistent); memcpy(ZSTR_VAL(ret), ZSTR_VAL(s), len + 1); + if (!ZSTR_IS_INTERNED(s)) { + GC_DELREF(s); + } return ret; } @@ -245,12 +248,13 @@ static zend_always_inline zend_string *zend_string_safe_realloc(zend_string *s, ZSTR_LEN(ret) = (n * m) + l; zend_string_forget_hash_val(ret); return ret; - } else { - GC_DELREF(s); } } ret = zend_string_safe_alloc(n, m, l, persistent); memcpy(ZSTR_VAL(ret), ZSTR_VAL(s), MIN((n * m) + l, ZSTR_LEN(s)) + 1); + if (!ZSTR_IS_INTERNED(s)) { + GC_DELREF(s); + } return ret; } From 6b521a98d457ae4265f38a65861c723220256110 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Thu, 3 Sep 2020 10:49:58 +0300 Subject: [PATCH 25/87] Fixed support for deprecated constants (Zend/tests/const_deprecation.phpt failure) --- ext/opcache/jit/zend_jit_vm_helpers.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/ext/opcache/jit/zend_jit_vm_helpers.c b/ext/opcache/jit/zend_jit_vm_helpers.c index 09a99811846f3..88a4eeb3690a4 100644 --- a/ext/opcache/jit/zend_jit_vm_helpers.c +++ b/ext/opcache/jit/zend_jit_vm_helpers.c @@ -272,6 +272,13 @@ static zend_always_inline int _zend_quick_get_constant( if (!check_defined_only) { ZVAL_COPY_OR_DUP(EX_VAR(opline->result.var), &c->value); + if (ZEND_CONSTANT_FLAGS(c) & CONST_DEPRECATED) { + zend_error(E_DEPRECATED, "Constant %s is deprecated", ZSTR_VAL(c->name)); + if (EG(exception)) { + return FAILURE; + } + return SUCCESS; + } } CACHE_PTR(opline->extended_value, c); From 3b853c97f3e74d4bb3dbdcfe847e1441a2e9dcb5 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Thu, 3 Sep 2020 10:29:18 +0200 Subject: [PATCH 26/87] Fixed bug #80045 Applying the obvious fix ... however, I think we may need to rething how we handle trampoline fcc for "f" zpp. It might make sense to use fcc->function_handler == NULL for that case and force it to be fetched in zend_call_function instead (it will be reset to that after the call anyway). Otherwise we will keep chasing these leaks, as it's the only instance where it's necessary to free a zpp result. --- NEWS | 2 ++ Zend/tests/bug80045.phpt | 22 ++++++++++++++++++++++ Zend/zend_builtin_functions.c | 2 ++ 3 files changed, 26 insertions(+) create mode 100644 Zend/tests/bug80045.phpt diff --git a/NEWS b/NEWS index 045e7b72f0009..34a8805503f2b 100644 --- a/NEWS +++ b/NEWS @@ -5,6 +5,8 @@ PHP NEWS - Core: . Implement #[Attr] Attribute syntax as per final vote in RFC https://wiki.php.net/rfc/shorter_attribute_syntax_change + . Fixed bug #80045 (memleak after two set_exception_handler calls with + __call). (Nikita) 03 Sep 2020, PHP 8.0.0beta3 diff --git a/Zend/tests/bug80045.phpt b/Zend/tests/bug80045.phpt new file mode 100644 index 0000000000000..b53b8b0c2ac07 --- /dev/null +++ b/Zend/tests/bug80045.phpt @@ -0,0 +1,22 @@ +--TEST-- +Bug #80045: memleak after two set_exception_handler calls with __call +--FILE-- + +===DONE=== +--EXPECT-- +===DONE=== diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c index c3a2a1b63f331..906f0666edcff 100644 --- a/Zend/zend_builtin_functions.c +++ b/Zend/zend_builtin_functions.c @@ -1198,6 +1198,7 @@ ZEND_FUNCTION(set_error_handler) ZVAL_COPY(&EG(user_error_handler), &(fci.function_name)); EG(user_error_handler_error_reporting) = (int)error_type; + zend_release_fcall_info_cache(&fcc); } /* }}} */ @@ -1253,6 +1254,7 @@ ZEND_FUNCTION(set_exception_handler) } ZVAL_COPY(&EG(user_exception_handler), &(fci.function_name)); + zend_release_fcall_info_cache(&fcc); } /* }}} */ From c70a938f2871373875e8782205c824b11697bd51 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Thu, 3 Sep 2020 10:26:05 +0200 Subject: [PATCH 27/87] Skip test if A: drive exists Otherwise the test case will fail for a very different reason. --- ext/phar/tests/bug71625.phpt | 1 + 1 file changed, 1 insertion(+) diff --git a/ext/phar/tests/bug71625.phpt b/ext/phar/tests/bug71625.phpt index afdf56e8ad6eb..97b5ea8c74220 100644 --- a/ext/phar/tests/bug71625.phpt +++ b/ext/phar/tests/bug71625.phpt @@ -9,6 +9,7 @@ if (!extension_loaded("phar") || !extension_loaded("zlib")) die("skip"); if(substr(PHP_OS, 0, 3) != 'WIN' ) { die('skip windows only test'); } +if (file_exists('A:')) die('skip drive A: exists'); ?> --FILE-- From 67e9b3be396a861d3c0a00881ae6092dc8a349bd Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Thu, 3 Sep 2020 12:06:06 +0300 Subject: [PATCH 28/87] JIT for FE_FETCH_R --- ext/opcache/jit/zend_jit.c | 13 ++++++++++-- ext/opcache/jit/zend_jit_trace.c | 15 ++++++++++++-- ext/opcache/jit/zend_jit_x86.dasc | 34 +++++++++++++++++++++++++++---- 3 files changed, 54 insertions(+), 8 deletions(-) diff --git a/ext/opcache/jit/zend_jit.c b/ext/opcache/jit/zend_jit.c index 56260c9105fee..7900130bb6e80 100644 --- a/ext/opcache/jit/zend_jit.c +++ b/ext/opcache/jit/zend_jit.c @@ -2972,13 +2972,22 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op goto jit_failure; } goto done; + case ZEND_FE_RESET_R: + op1_info = OP1_INFO(); + if ((op1_info & (MAY_BE_ANY|MAY_BE_REF)) != MAY_BE_ARRAY) { + break; + } + if (!zend_jit_fe_reset(&dasm_state, opline, op1_info)) { + goto jit_failure; + } + goto done; case ZEND_FE_FETCH_R: op1_info = OP1_INFO(); if ((op1_info & MAY_BE_ANY) != MAY_BE_ARRAY) { break; } - if (!zend_jit_fe_fetch(&dasm_state, opline, op_array, ssa, ssa_op, - op1_info, ssa->cfg.blocks[b].successors[0], opline->opcode, NULL)) { + if (!zend_jit_fe_fetch(&dasm_state, opline, op1_info, OP2_INFO(), + ssa->cfg.blocks[b].successors[0], opline->opcode, NULL)) { goto jit_failure; } goto done; diff --git a/ext/opcache/jit/zend_jit_trace.c b/ext/opcache/jit/zend_jit_trace.c index 7d3c7be1aa53d..5834cbe0e55a6 100644 --- a/ext/opcache/jit/zend_jit_trace.c +++ b/ext/opcache/jit/zend_jit_trace.c @@ -1445,6 +1445,7 @@ static zend_ssa *zend_jit_trace_build_tssa(zend_jit_trace_rec *trace_buffer, uin case ZEND_ECHO: case ZEND_STRLEN: case ZEND_QM_ASSIGN: + case ZEND_FE_RESET_R: case ZEND_FE_FETCH_R: ADD_OP1_TRACE_GUARD(); break; @@ -4541,6 +4542,16 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par goto jit_failure; } goto done; + case ZEND_FE_RESET_R: + op1_info = OP1_INFO(); + CHECK_OP1_TRACE_TYPE(); + if ((op1_info & (MAY_BE_ANY|MAY_BE_REF)) != MAY_BE_ARRAY) { + break; + } + if (!zend_jit_fe_reset(&dasm_state, opline, op1_info)) { + goto jit_failure; + } + goto done; case ZEND_FE_FETCH_R: op1_info = OP1_INFO(); CHECK_OP1_TRACE_TYPE(); @@ -4569,8 +4580,8 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par } else { ZEND_UNREACHABLE(); } - if (!zend_jit_fe_fetch(&dasm_state, opline, op_array, ssa, ssa_op, - op1_info, -1, smart_branch_opcode, exit_addr)) { + if (!zend_jit_fe_fetch(&dasm_state, opline, op1_info, OP2_INFO(), + -1, smart_branch_opcode, exit_addr)) { goto jit_failure; } goto done; diff --git a/ext/opcache/jit/zend_jit_x86.dasc b/ext/opcache/jit/zend_jit_x86.dasc index a863fed69e885..74449877ac5fb 100644 --- a/ext/opcache/jit/zend_jit_x86.dasc +++ b/ext/opcache/jit/zend_jit_x86.dasc @@ -12530,9 +12530,35 @@ static int zend_jit_isset_isempty_cv(dasm_State **Dst, const zend_op *opline, ui return 1; } -static int zend_jit_fe_fetch(dasm_State **Dst, const zend_op *opline, const zend_op_array *op_array, const zend_ssa *ssa, const zend_ssa_op *ssa_op, uint32_t op1_info, unsigned int target_label, zend_uchar exit_opcode, const void *exit_addr) +static int zend_jit_fe_reset(dasm_State **Dst, const zend_op *opline, uint32_t op1_info) { - zend_jit_addr op1_addr = OP1_ADDR(); + zend_jit_addr res_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FP, opline->result.var); + + if (opline->op1_type == IS_CONST) { + zval *zv = RT_CONSTANT(opline, opline->op1); + + | ZVAL_COPY_CONST res_addr, MAY_BE_ANY, MAY_BE_ANY, zv, ZREG_R0 + if (Z_REFCOUNTED_P(zv)) { + | ADDREF_CONST zv, r0 + } + } else { + zend_jit_addr op1_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FP, opline->op1.var); + + | // ZVAL_COPY(res, value); + | ZVAL_COPY_VALUE res_addr, -1, op1_addr, op1_info, ZREG_R0, ZREG_FCARG1a + if (opline->op1_type == IS_CV) { + | TRY_ADDREF op1_info, ah, FCARG1a + } + } + | // Z_FE_POS_P(res) = 0; + | mov dword [FP + opline->result.var + offsetof(zval, u2.fe_pos)], 0 + + return 1; +} + +static int zend_jit_fe_fetch(dasm_State **Dst, const zend_op *opline, uint32_t op1_info, uint32_t op2_info, unsigned int target_label, zend_uchar exit_opcode, const void *exit_addr) +{ + zend_jit_addr op1_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FP, opline->op1.var); | // array = EX_VAR(opline->op1.var); | // fe_ht = Z_ARRVAL_P(array); @@ -12589,7 +12615,7 @@ static int zend_jit_fe_fetch(dasm_State **Dst, const zend_op *opline, const zend if (!exit_addr || exit_opcode == ZEND_JMP) { zend_jit_addr val_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FCARG2a, 0); - zend_jit_addr var_addr = OP2_ADDR(); + zend_jit_addr var_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FP, opline->op2.var); uint32_t val_info; | mov FCARG2a, r0 @@ -12645,7 +12671,7 @@ static int zend_jit_fe_fetch(dasm_State **Dst, const zend_op *opline, const zend if (opline->op2_type == IS_CV) { | // zend_assign_to_variable(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES()); - if (!zend_jit_assign_to_variable(Dst, opline, var_addr, var_addr, OP2_INFO(), -1, IS_CV, opline->op2, val_addr, val_info, 0, 1)) { + if (!zend_jit_assign_to_variable(Dst, opline, var_addr, var_addr, op2_info, -1, IS_CV, opline->op2, val_addr, val_info, 0, 1)) { return 0; } } else { From 04e77d2dea03955b987bc6e253ea236c2c7a12aa Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Thu, 3 Sep 2020 11:16:50 +0200 Subject: [PATCH 29/87] Fixed bug #80046 We already protect against optimizing away loop frees in DFA pass, but not in block pass. --- NEWS | 1 + Zend/tests/bug80046.phpt | 22 ++++++++++++++++++++++ ext/opcache/Optimizer/block_pass.c | 14 +++++++++++--- ext/opcache/Optimizer/zend_cfg.c | 3 +-- 4 files changed, 35 insertions(+), 5 deletions(-) create mode 100644 Zend/tests/bug80046.phpt diff --git a/NEWS b/NEWS index e2cb05e949509..9eaa1b1c58d2f 100644 --- a/NEWS +++ b/NEWS @@ -19,6 +19,7 @@ PHP NEWS - OPcache: . Fixed bug #80002 (calc free space for new interned string is wrong). (t-matsuno) + . Fixed bug #80046 (FREE for SWITCH_STRING optimized away). (Nikita) - PDO: . Fixed bug #80027 (Terrible performance using $query->fetch on queries with diff --git a/Zend/tests/bug80046.phpt b/Zend/tests/bug80046.phpt new file mode 100644 index 0000000000000..87a493c20308c --- /dev/null +++ b/Zend/tests/bug80046.phpt @@ -0,0 +1,22 @@ +--TEST-- +Bug #80046: FREE for SWITCH_STRING optimized away +--FILE-- +getMessage(), "\n"; +} + +?> +--EXPECT-- +Default diff --git a/ext/opcache/Optimizer/block_pass.c b/ext/opcache/Optimizer/block_pass.c index 3327ec86df4b0..17b89c4d53eff 100644 --- a/ext/opcache/Optimizer/block_pass.c +++ b/ext/opcache/Optimizer/block_pass.c @@ -921,7 +921,15 @@ static void assemble_code_blocks(zend_cfg *cfg, zend_op_array *op_array, zend_op if (b->len == 0) { continue; } - if (b->flags & ZEND_BB_REACHABLE) { + if (b->flags & (ZEND_BB_REACHABLE|ZEND_BB_UNREACHABLE_FREE)) { + if (b->flags & ZEND_BB_UNREACHABLE_FREE) { + /* Only keep the FREE for the loop var */ + ZEND_ASSERT(op_array->opcodes[b->start].opcode == ZEND_FREE + || op_array->opcodes[b->start].opcode == ZEND_FE_FREE); + len += b->len = 1; + continue; + } + opline = op_array->opcodes + b->start + b->len - 1; if (opline->opcode == ZEND_JMP) { zend_basic_block *next = b + 1; @@ -959,7 +967,7 @@ static void assemble_code_blocks(zend_cfg *cfg, zend_op_array *op_array, zend_op /* Copy code of reachable blocks into a single buffer */ for (b = blocks; b < end; b++) { - if (b->flags & ZEND_BB_REACHABLE) { + if (b->flags & (ZEND_BB_REACHABLE|ZEND_BB_UNREACHABLE_FREE)) { memcpy(opline, op_array->opcodes + b->start, b->len * sizeof(zend_op)); b->start = opline - new_opcodes; opline += b->len; @@ -1083,7 +1091,7 @@ static void assemble_code_blocks(zend_cfg *cfg, zend_op_array *op_array, zend_op /* rebuild map (just for printing) */ memset(cfg->map, -1, sizeof(int) * op_array->last); for (n = 0; n < cfg->blocks_count; n++) { - if (cfg->blocks[n].flags & ZEND_BB_REACHABLE) { + if (cfg->blocks[n].flags & (ZEND_BB_REACHABLE|ZEND_BB_UNREACHABLE_FREE)) { cfg->map[cfg->blocks[n].start] = n; } } diff --git a/ext/opcache/Optimizer/zend_cfg.c b/ext/opcache/Optimizer/zend_cfg.c index 66c15be3113ac..76c829bb3e2f9 100644 --- a/ext/opcache/Optimizer/zend_cfg.c +++ b/ext/opcache/Optimizer/zend_cfg.c @@ -575,9 +575,8 @@ int zend_build_cfg(zend_arena **arena, const zend_op_array *op_array, uint32_t b } /* Build CFG, Step 4, Mark Reachable Basic Blocks */ - zend_mark_reachable_blocks(op_array, cfg, 0); - cfg->flags |= flags; + zend_mark_reachable_blocks(op_array, cfg, 0); return SUCCESS; } From 8516434a56d279b4f5fbe9497b0dd6365350383c Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Thu, 3 Sep 2020 11:16:50 +0200 Subject: [PATCH 30/87] Fixed bug #80046 We already protect against optimizing away loop frees in DFA pass, but not in block pass. --- NEWS | 1 + Zend/tests/bug80046.phpt | 22 ++++++++++++++++++++++ ext/opcache/Optimizer/block_pass.c | 14 +++++++++++--- ext/opcache/Optimizer/zend_cfg.c | 3 +-- 4 files changed, 35 insertions(+), 5 deletions(-) create mode 100644 Zend/tests/bug80046.phpt diff --git a/NEWS b/NEWS index e2cb05e949509..9eaa1b1c58d2f 100644 --- a/NEWS +++ b/NEWS @@ -19,6 +19,7 @@ PHP NEWS - OPcache: . Fixed bug #80002 (calc free space for new interned string is wrong). (t-matsuno) + . Fixed bug #80046 (FREE for SWITCH_STRING optimized away). (Nikita) - PDO: . Fixed bug #80027 (Terrible performance using $query->fetch on queries with diff --git a/Zend/tests/bug80046.phpt b/Zend/tests/bug80046.phpt new file mode 100644 index 0000000000000..87a493c20308c --- /dev/null +++ b/Zend/tests/bug80046.phpt @@ -0,0 +1,22 @@ +--TEST-- +Bug #80046: FREE for SWITCH_STRING optimized away +--FILE-- +getMessage(), "\n"; +} + +?> +--EXPECT-- +Default diff --git a/ext/opcache/Optimizer/block_pass.c b/ext/opcache/Optimizer/block_pass.c index 3327ec86df4b0..17b89c4d53eff 100644 --- a/ext/opcache/Optimizer/block_pass.c +++ b/ext/opcache/Optimizer/block_pass.c @@ -921,7 +921,15 @@ static void assemble_code_blocks(zend_cfg *cfg, zend_op_array *op_array, zend_op if (b->len == 0) { continue; } - if (b->flags & ZEND_BB_REACHABLE) { + if (b->flags & (ZEND_BB_REACHABLE|ZEND_BB_UNREACHABLE_FREE)) { + if (b->flags & ZEND_BB_UNREACHABLE_FREE) { + /* Only keep the FREE for the loop var */ + ZEND_ASSERT(op_array->opcodes[b->start].opcode == ZEND_FREE + || op_array->opcodes[b->start].opcode == ZEND_FE_FREE); + len += b->len = 1; + continue; + } + opline = op_array->opcodes + b->start + b->len - 1; if (opline->opcode == ZEND_JMP) { zend_basic_block *next = b + 1; @@ -959,7 +967,7 @@ static void assemble_code_blocks(zend_cfg *cfg, zend_op_array *op_array, zend_op /* Copy code of reachable blocks into a single buffer */ for (b = blocks; b < end; b++) { - if (b->flags & ZEND_BB_REACHABLE) { + if (b->flags & (ZEND_BB_REACHABLE|ZEND_BB_UNREACHABLE_FREE)) { memcpy(opline, op_array->opcodes + b->start, b->len * sizeof(zend_op)); b->start = opline - new_opcodes; opline += b->len; @@ -1083,7 +1091,7 @@ static void assemble_code_blocks(zend_cfg *cfg, zend_op_array *op_array, zend_op /* rebuild map (just for printing) */ memset(cfg->map, -1, sizeof(int) * op_array->last); for (n = 0; n < cfg->blocks_count; n++) { - if (cfg->blocks[n].flags & ZEND_BB_REACHABLE) { + if (cfg->blocks[n].flags & (ZEND_BB_REACHABLE|ZEND_BB_UNREACHABLE_FREE)) { cfg->map[cfg->blocks[n].start] = n; } } diff --git a/ext/opcache/Optimizer/zend_cfg.c b/ext/opcache/Optimizer/zend_cfg.c index 66c15be3113ac..76c829bb3e2f9 100644 --- a/ext/opcache/Optimizer/zend_cfg.c +++ b/ext/opcache/Optimizer/zend_cfg.c @@ -575,9 +575,8 @@ int zend_build_cfg(zend_arena **arena, const zend_op_array *op_array, uint32_t b } /* Build CFG, Step 4, Mark Reachable Basic Blocks */ - zend_mark_reachable_blocks(op_array, cfg, 0); - cfg->flags |= flags; + zend_mark_reachable_blocks(op_array, cfg, 0); return SUCCESS; } From c4016ecd446ef26bb3dc77735b6e441e151ea985 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Thu, 3 Sep 2020 11:30:58 +0200 Subject: [PATCH 31/87] Remove CG(filenames_table) This doesn't seem to serve any purpose anymore. --- Zend/zend_compile.c | 13 ------------- Zend/zend_globals.h | 2 -- 2 files changed, 15 deletions(-) diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index c403a1f54e3a1..a60ceb1c8431d 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -412,7 +412,6 @@ void init_compiler(void) /* {{{ */ memset(&CG(context), 0, sizeof(CG(context))); zend_init_compiler_data_structures(); zend_init_rsrc_list(); - zend_hash_init(&CG(filenames_table), 8, NULL, ZVAL_PTR_DTOR, 0); zend_llist_init(&CG(open_files), sizeof(zend_file_handle), (void (*)(void *)) file_handle_dtor, 0); CG(unclean_shutdown) = 0; @@ -426,7 +425,6 @@ void shutdown_compiler(void) /* {{{ */ zend_stack_destroy(&CG(loop_var_stack)); zend_stack_destroy(&CG(delayed_oplines_stack)); zend_stack_destroy(&CG(short_circuiting_opnums)); - zend_hash_destroy(&CG(filenames_table)); zend_arena_destroy(CG(arena)); if (CG(delayed_variance_obligations)) { @@ -444,18 +442,7 @@ void shutdown_compiler(void) /* {{{ */ ZEND_API zend_string *zend_set_compiled_filename(zend_string *new_compiled_filename) /* {{{ */ { - zval *p, rv; - - if ((p = zend_hash_find(&CG(filenames_table), new_compiled_filename))) { - ZEND_ASSERT(Z_TYPE_P(p) == IS_STRING); - CG(compiled_filename) = Z_STR_P(p); - return Z_STR_P(p); - } - new_compiled_filename = zend_new_interned_string(zend_string_copy(new_compiled_filename)); - ZVAL_STR(&rv, new_compiled_filename); - zend_hash_add_new(&CG(filenames_table), new_compiled_filename, &rv); - CG(compiled_filename) = new_compiled_filename; return new_compiled_filename; } diff --git a/Zend/zend_globals.h b/Zend/zend_globals.h index 652e0ef1e1329..e0e8ac770065e 100644 --- a/Zend/zend_globals.h +++ b/Zend/zend_globals.h @@ -77,8 +77,6 @@ struct _zend_compiler_globals { HashTable *function_table; /* function symbol table */ HashTable *class_table; /* class table */ - HashTable filenames_table; - HashTable *auto_globals; /* Refer to zend_yytnamerr() in zend_language_parser.y for meaning of values */ From 7620ea15807a84e76cb1cb2f9d5234ea787aae2e Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Thu, 3 Sep 2020 11:56:55 +0200 Subject: [PATCH 32/87] Don't intern compiled_filename For php-ast interning the file name is an effective memory leak, see php-ast#134. I don't think there's any reason to do this. At some point this was needed due to bugs in the interned string mechanism that caused issues if the string was later interned, e.g. through a __FILE__ reference. These issues have since been resolved. In conjunction with the filenames_table removal in c4016ecd446ef26bb3dc77735b6e441e151ea985 this means that filenames now need to be refcounted like normal strings. In particular the filename reference in op_arrays and CEs are refcounted. --- Zend/zend_compile.c | 9 ++++++--- Zend/zend_language_scanner.l | 3 ++- Zend/zend_opcode.c | 4 +++- ext/opcache/ZendAccelerator.c | 9 +++------ ext/opcache/zend_persist.c | 6 ++---- 5 files changed, 16 insertions(+), 15 deletions(-) diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index a60ceb1c8431d..21db0a3f7d299 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -442,14 +442,17 @@ void shutdown_compiler(void) /* {{{ */ ZEND_API zend_string *zend_set_compiled_filename(zend_string *new_compiled_filename) /* {{{ */ { - new_compiled_filename = zend_new_interned_string(zend_string_copy(new_compiled_filename)); - CG(compiled_filename) = new_compiled_filename; + CG(compiled_filename) = zend_string_copy(new_compiled_filename); return new_compiled_filename; } /* }}} */ ZEND_API void zend_restore_compiled_filename(zend_string *original_compiled_filename) /* {{{ */ { + if (CG(compiled_filename)) { + zend_string_release(CG(compiled_filename)); + CG(compiled_filename) = NULL; + } CG(compiled_filename) = original_compiled_filename; } /* }}} */ @@ -7345,7 +7348,7 @@ void zend_compile_class_decl(znode *result, zend_ast *ast, zend_bool toplevel) / } ce->ce_flags |= decl->flags; - ce->info.user.filename = zend_get_compiled_filename(); + ce->info.user.filename = zend_string_copy(zend_get_compiled_filename()); ce->info.user.line_start = decl->start_lineno; ce->info.user.line_end = decl->end_lineno; diff --git a/Zend/zend_language_scanner.l b/Zend/zend_language_scanner.l index b00e4e3edb61a..c6537c664b02a 100644 --- a/Zend/zend_language_scanner.l +++ b/Zend/zend_language_scanner.l @@ -233,8 +233,9 @@ ZEND_API void zend_save_lexical_state(zend_lex_state *lex_state) lex_state->in = SCNG(yy_in); lex_state->yy_state = YYSTATE; - lex_state->filename = zend_get_compiled_filename(); + lex_state->filename = CG(compiled_filename); lex_state->lineno = CG(zend_lineno); + CG(compiled_filename) = NULL; lex_state->script_org = SCNG(script_org); lex_state->script_org_size = SCNG(script_org_size); diff --git a/Zend/zend_opcode.c b/Zend/zend_opcode.c index a9236faf6a68c..6681ef7b68485 100644 --- a/Zend/zend_opcode.c +++ b/Zend/zend_opcode.c @@ -61,7 +61,7 @@ void init_op_array(zend_op_array *op_array, zend_uchar type, int initial_ops_siz op_array->T = 0; op_array->function_name = NULL; - op_array->filename = zend_get_compiled_filename(); + op_array->filename = zend_string_copy(zend_get_compiled_filename()); op_array->doc_comment = NULL; op_array->attributes = NULL; @@ -354,6 +354,7 @@ ZEND_API void destroy_zend_class(zval *zv) } efree(ce->interfaces); } + zend_string_release_ex(ce->info.user.filename, 0); if (ce->info.user.doc_comment) { zend_string_release_ex(ce->info.user.doc_comment, 0); } @@ -496,6 +497,7 @@ ZEND_API void destroy_op_array(zend_op_array *op_array) } efree(op_array->opcodes); + zend_string_release_ex(op_array->filename, 0); if (op_array->doc_comment) { zend_string_release_ex(op_array->doc_comment, 0); } diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c index 725b33d913126..8683dc106f24a 100644 --- a/ext/opcache/ZendAccelerator.c +++ b/ext/opcache/ZendAccelerator.c @@ -4528,7 +4528,6 @@ static int accel_preload(const char *config, zend_bool in_child) if (ret == SUCCESS) { zend_persistent_script *script; - zend_string *filename; int ping_auto_globals_mask; int i; zend_class_entry *ce; @@ -4668,7 +4667,7 @@ static int accel_preload(const char *config, zend_bool in_child) script->ping_auto_globals_mask = ping_auto_globals_mask; /* Store all functions and classes in a single pseudo-file */ - filename = zend_string_init("$PRELOAD$", sizeof("$PRELOAD$") - 1, 0); + CG(compiled_filename) = zend_string_init("$PRELOAD$", sizeof("$PRELOAD$") - 1, 0); #if ZEND_USE_ABS_CONST_ADDR init_op_array(&script->script.main_op_array, ZEND_USER_FUNCTION, 1); #else @@ -4690,8 +4689,8 @@ static int accel_preload(const char *config, zend_bool in_child) ZEND_PASS_TWO_UPDATE_CONSTANT(&script->script.main_op_array, script->script.main_op_array.opcodes, script->script.main_op_array.opcodes[0].op1); zend_vm_set_opcode_handler(script->script.main_op_array.opcodes); - script->script.main_op_array.filename = filename; - script->script.filename = zend_string_copy(filename); + script->script.filename = CG(compiled_filename); + CG(compiled_filename) = NULL; script->script.first_early_binding_opline = (uint32_t)-1; @@ -4728,8 +4727,6 @@ static int accel_preload(const char *config, zend_bool in_child) SHM_PROTECT(); HANDLE_UNBLOCK_INTERRUPTIONS(); - zend_string_release(filename); - ZEND_ASSERT(ZCSG(preload_script)->arena_size == 0); preload_load(); diff --git a/ext/opcache/zend_persist.c b/ext/opcache/zend_persist.c index ed923a03cc9de..415aa76093f7e 100644 --- a/ext/opcache/zend_persist.c +++ b/ext/opcache/zend_persist.c @@ -565,8 +565,7 @@ static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_sc } if (op_array->filename) { - /* do not free! PHP has centralized filename storage, compiler will free it */ - zend_accel_memdup_string(op_array->filename); + zend_accel_store_string(op_array->filename); } if (op_array->arg_info) { @@ -864,8 +863,7 @@ static void zend_persist_class_entry(zval *zv) HT_FLAGS(&ce->constants_table) &= (HASH_FLAG_UNINITIALIZED | HASH_FLAG_STATIC_KEYS); if (ce->info.user.filename) { - /* do not free! PHP has centralized filename storage, compiler will free it */ - zend_accel_memdup_string(ce->info.user.filename); + zend_accel_store_string(ce->info.user.filename); } if (ce->info.user.doc_comment) { if (ZCG(accel_directives).save_comments) { From 9464576f2902c3f2bbef7478cbeefb42dda6cca0 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Thu, 3 Sep 2020 12:59:30 +0200 Subject: [PATCH 33/87] Fix leaks in sapi tests Make sure to always free compiled_filename on shutdown. --- Zend/zend_compile.c | 1 + 1 file changed, 1 insertion(+) diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 21db0a3f7d299..36715c7bb5879 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -437,6 +437,7 @@ void shutdown_compiler(void) /* {{{ */ FREE_HASHTABLE(CG(delayed_autoloads)); CG(delayed_autoloads) = NULL; } + zend_restore_compiled_filename(NULL); } /* }}} */ From 7b3ac296a5242f9ded4d2dc7cf2c6349e583caf8 Mon Sep 17 00:00:00 2001 From: George Peter Banyard Date: Thu, 3 Sep 2020 13:05:50 +0200 Subject: [PATCH 34/87] Fix mismatch between macro and struct definition --- UPGRADING.INTERNALS | 2 +- Zend/zend_modules.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/UPGRADING.INTERNALS b/UPGRADING.INTERNALS index 301faf16cdcff..462850993ada9 100644 --- a/UPGRADING.INTERNALS +++ b/UPGRADING.INTERNALS @@ -309,7 +309,7 @@ PHP 8.0 INTERNALS UPGRADE NOTES - zend_multibyte_set_filter() - zend_lex_tstring() - _zend_module_entry module_startup_func, module_shutdown_func, - request_startup_func, and request_shutdown_func function pointers + request_startup_func, request_shutdown_func, and post_deactivate_func function pointers - (*zend_encoding_list_parser) typedef - (*zend_encoding_internal_encoding_setter) typedef - zend_multibyte_set_functions() diff --git a/Zend/zend_modules.h b/Zend/zend_modules.h index cb64324d38bc7..ccd77f9eb68fe 100644 --- a/Zend/zend_modules.h +++ b/Zend/zend_modules.h @@ -91,7 +91,7 @@ struct _zend_module_entry { #endif void (*globals_ctor)(void *global); void (*globals_dtor)(void *global); - int (*post_deactivate_func)(void); + zend_result (*post_deactivate_func)(void); int module_started; unsigned char type; void *handle; From 430b3ac7df59aa42b52995be1c704394fa29ad3d Mon Sep 17 00:00:00 2001 From: George Peter Banyard Date: Thu, 3 Sep 2020 14:15:18 +0200 Subject: [PATCH 35/87] Refactor parts of SPL Dir/SplFileObject This fixes a way it was possible to trigger an Internel Error by disabling function (via the INI setting) when SPL was acting as a proxy to the function call. Fix flock_compat layer as it needs to used in SPL now. Use macro to check if object is initialized Closes GH-6014 --- ext/spl/config.m4 | 1 + ext/spl/spl_directory.c | 225 +++++++----------- ...bject_fstat_with_basic_fstat_disabled.phpt | 64 +++++ ext/standard/file.c | 33 +-- ext/standard/file.h | 1 + ext/standard/flock_compat.c | 11 - ext/standard/flock_compat.h | 11 + 7 files changed, 185 insertions(+), 161 deletions(-) create mode 100644 ext/spl/tests/SplFileObject_fstat_with_basic_fstat_disabled.phpt diff --git a/ext/spl/config.m4 b/ext/spl/config.m4 index 8e0d31f3e2e35..6e6973646db84 100644 --- a/ext/spl/config.m4 +++ b/ext/spl/config.m4 @@ -1,3 +1,4 @@ PHP_NEW_EXTENSION(spl, php_spl.c spl_functions.c spl_engine.c spl_iterators.c spl_array.c spl_directory.c spl_exceptions.c spl_observer.c spl_dllist.c spl_heap.c spl_fixedarray.c, no,, -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1) PHP_INSTALL_HEADERS([ext/spl], [php_spl.h spl_array.h spl_directory.h spl_engine.h spl_exceptions.h spl_functions.h spl_iterators.h spl_observer.h spl_dllist.h spl_heap.h spl_fixedarray.h]) PHP_ADD_EXTENSION_DEP(spl, pcre, true) +PHP_ADD_EXTENSION_DEP(spl, standard, true) diff --git a/ext/spl/spl_directory.c b/ext/spl/spl_directory.c index 0836e18bc4534..e7bc262da5236 100644 --- a/ext/spl/spl_directory.c +++ b/ext/spl/spl_directory.c @@ -20,10 +20,11 @@ #include "php.h" #include "php_ini.h" -#include "ext/standard/info.h" #include "ext/standard/file.h" +#include "ext/standard/php_filestat.h" +#include "ext/standard/flock_compat.h" +#include "ext/standard/scanf.h" #include "ext/standard/php_string.h" -#include "zend_compile.h" #include "zend_exceptions.h" #include "zend_interfaces.h" @@ -35,12 +36,6 @@ #include "spl_directory_arginfo.h" #include "spl_exceptions.h" -#include "php.h" -#include "fopen_wrappers.h" - -#include "ext/standard/basic_functions.h" -#include "ext/standard/php_filestat.h" - #define SPL_HAS_FLAG(flags, test_flag) ((flags & test_flag) ? 1 : 0) /* declare the class handlers */ @@ -57,6 +52,13 @@ PHPAPI zend_class_entry *spl_ce_GlobIterator; PHPAPI zend_class_entry *spl_ce_SplFileObject; PHPAPI zend_class_entry *spl_ce_SplTempFileObject; +// TODO Use standard Error +#define CHECK_SPL_FILE_OBJECT_IS_INITIALIZED(spl_filesystem_object_pointer) \ + if (!(spl_filesystem_object_pointer)->u.file.stream) { \ + zend_throw_exception_ex(spl_ce_RuntimeException, 0, "Object not initialized"); \ + RETURN_THROWS(); \ + } + static void spl_filesystem_file_free_line(spl_filesystem_object *intern) /* {{{ */ { if (intern->u.file.current_line) { @@ -1901,64 +1903,6 @@ static int spl_filesystem_file_read(spl_filesystem_object *intern, int silent) / return SUCCESS; } /* }}} */ -static int spl_filesystem_file_call(spl_filesystem_object *intern, zend_function *func_ptr, int pass_num_args, zval *return_value, zval *arg2) /* {{{ */ -{ - zend_fcall_info fci; - zend_fcall_info_cache fcic; - zval *zresource_ptr = &intern->u.file.zresource, *params; - int result; - int num_args = pass_num_args + (arg2 ? 2 : 1); - - if (Z_ISUNDEF_P(zresource_ptr)) { - zend_throw_exception_ex(spl_ce_RuntimeException, 0, "Object not initialized"); - return FAILURE; - } - - params = (zval*)safe_emalloc(num_args, sizeof(zval), 0); - params[0] = *zresource_ptr; - - if (arg2) { - params[1] = *arg2; - } - - if (zend_get_parameters_array_ex(pass_num_args, params + (arg2 ? 2 : 1)) != SUCCESS) { - efree(params); - WRONG_PARAM_COUNT_WITH_RETVAL(FAILURE); - } - - fci.size = sizeof(fci); - fci.object = NULL; - fci.retval = return_value; - fci.param_count = num_args; - fci.params = params; - fci.named_params = NULL; - ZVAL_STR(&fci.function_name, func_ptr->common.function_name); - - fcic.function_handler = func_ptr; - fcic.called_scope = NULL; - fcic.object = NULL; - - result = zend_call_function(&fci, &fcic); - - if (result == FAILURE || Z_ISUNDEF_P(return_value)) { - RETVAL_FALSE; - } - - efree(params); - return result; -} /* }}} */ - -#define FileFunctionCall(func_name, pass_num_args, arg2) /* {{{ */ \ -{ \ - zend_function *func_ptr; \ - func_ptr = (zend_function *)zend_hash_str_find_ptr(EG(function_table), #func_name, sizeof(#func_name) - 1); \ - if (func_ptr == NULL) { \ - zend_throw_exception_ex(spl_ce_RuntimeException, 0, "Internal error, function %s() not found. Please report", #func_name); \ - return; \ - } \ - spl_filesystem_file_call(intern, func_ptr, pass_num_args, return_value, arg2); \ -} /* }}} */ - static int spl_filesystem_file_read_csv(spl_filesystem_object *intern, char delimiter, char enclosure, int escape, zval *return_value) /* {{{ */ { int ret = SUCCESS; @@ -2075,7 +2019,7 @@ static int spl_filesystem_file_read_line(zval * this_ptr, spl_filesystem_object static void spl_filesystem_file_rewind(zval * this_ptr, spl_filesystem_object *intern) /* {{{ */ { - if(!intern->u.file.stream) { + if (!intern->u.file.stream) { zend_throw_exception_ex(spl_ce_RuntimeException, 0, "Object not initialized"); return; } @@ -2203,10 +2147,7 @@ PHP_METHOD(SplFileObject, eof) RETURN_THROWS(); } - if(!intern->u.file.stream) { - zend_throw_exception_ex(spl_ce_RuntimeException, 0, "Object not initialized"); - RETURN_THROWS(); - } + CHECK_SPL_FILE_OBJECT_IS_INITIALIZED(intern); RETURN_BOOL(php_stream_eof(intern->u.file.stream)); } /* }}} */ @@ -2239,10 +2180,7 @@ PHP_METHOD(SplFileObject, fgets) RETURN_THROWS(); } - if(!intern->u.file.stream) { - zend_throw_exception_ex(spl_ce_RuntimeException, 0, "Object not initialized"); - RETURN_THROWS(); - } + CHECK_SPL_FILE_OBJECT_IS_INITIALIZED(intern); if (spl_filesystem_file_read(intern, 0) == FAILURE) { RETURN_FALSE; @@ -2259,10 +2197,7 @@ PHP_METHOD(SplFileObject, current) RETURN_THROWS(); } - if(!intern->u.file.stream) { - zend_throw_exception_ex(spl_ce_RuntimeException, 0, "Object not initialized"); - RETURN_THROWS(); - } + CHECK_SPL_FILE_OBJECT_IS_INITIALIZED(intern); if (!intern->u.file.current_line && Z_ISUNDEF(intern->u.file.current_zval)) { spl_filesystem_file_read_line(ZEND_THIS, intern, 1); @@ -2382,15 +2317,6 @@ PHP_METHOD(SplFileObject, getChildren) /* return NULL */ } /* }}} */ -/* {{{ FileFunction */ -#define FileFunction(func_name) \ -PHP_METHOD(SplFileObject, func_name) \ -{ \ - spl_filesystem_object *intern = Z_SPLFILESYSTEM_P(ZEND_THIS); \ - FileFunctionCall(func_name, ZEND_NUM_ARGS(), NULL); \ -} -/* }}} */ - /* {{{ Return current line as csv */ PHP_METHOD(SplFileObject, fgetcsv) { @@ -2402,10 +2328,7 @@ PHP_METHOD(SplFileObject, fgetcsv) if (zend_parse_parameters(ZEND_NUM_ARGS(), "|sss", &delim, &d_len, &enclo, &e_len, &esc, &esc_len) == SUCCESS) { - if(!intern->u.file.stream) { - zend_throw_exception_ex(spl_ce_RuntimeException, 0, "Object not initialized"); - RETURN_THROWS(); - } + CHECK_SPL_FILE_OBJECT_IS_INITIALIZED(intern); switch(ZEND_NUM_ARGS()) { @@ -2570,8 +2493,43 @@ PHP_METHOD(SplFileObject, getCsvControl) } /* }}} */ -/* {{{ Portable file locking */ -FileFunction(flock) +static int flock_values[] = { LOCK_SH, LOCK_EX, LOCK_UN }; + +/* {{{ Portable file locking, copy pasted from ext/standard/file.c flock() function. + * This is done to prevent this to fail if flock is disabled via disable_functions */ +PHP_METHOD(SplFileObject, flock) +{ + spl_filesystem_object *intern = Z_SPLFILESYSTEM_P(ZEND_THIS); + zval *wouldblock = NULL; + int act; + zend_long operation = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "l|z", &operation, &wouldblock) == FAILURE) { + RETURN_THROWS(); + } + + CHECK_SPL_FILE_OBJECT_IS_INITIALIZED(intern); + + act = operation & PHP_LOCK_UN; + if (act < 1 || act > 3) { + zend_argument_value_error(1, "must be either LOCK_SH, LOCK_EX, or LOCK_UN"); + RETURN_THROWS(); + } + + if (wouldblock) { + ZEND_TRY_ASSIGN_REF_LONG(wouldblock, 0); + } + + /* flock_values contains all possible actions if (operation & PHP_LOCK_NB) we won't block on the lock */ + act = flock_values[act - 1] | (operation & PHP_LOCK_NB ? LOCK_NB : 0); + if (php_stream_lock(intern->u.file.stream, act)) { + if (operation && errno == EWOULDBLOCK && wouldblock) { + ZEND_TRY_ASSIGN_REF_LONG(wouldblock, 1); + } + RETURN_FALSE; + } + RETURN_TRUE; +} /* }}} */ /* {{{ Flush the file */ @@ -2579,10 +2537,7 @@ PHP_METHOD(SplFileObject, fflush) { spl_filesystem_object *intern = Z_SPLFILESYSTEM_P(ZEND_THIS); - if(!intern->u.file.stream) { - zend_throw_exception_ex(spl_ce_RuntimeException, 0, "Object not initialized"); - RETURN_THROWS(); - } + CHECK_SPL_FILE_OBJECT_IS_INITIALIZED(intern); RETURN_BOOL(!php_stream_flush(intern->u.file.stream)); } /* }}} */ @@ -2593,10 +2548,7 @@ PHP_METHOD(SplFileObject, ftell) spl_filesystem_object *intern = Z_SPLFILESYSTEM_P(ZEND_THIS); zend_long ret; - if(!intern->u.file.stream) { - zend_throw_exception_ex(spl_ce_RuntimeException, 0, "Object not initialized"); - RETURN_THROWS(); - } + CHECK_SPL_FILE_OBJECT_IS_INITIALIZED(intern); ret = php_stream_tell(intern->u.file.stream); @@ -2617,10 +2569,7 @@ PHP_METHOD(SplFileObject, fseek) RETURN_THROWS(); } - if(!intern->u.file.stream) { - zend_throw_exception_ex(spl_ce_RuntimeException, 0, "Object not initialized"); - RETURN_THROWS(); - } + CHECK_SPL_FILE_OBJECT_IS_INITIALIZED(intern); spl_filesystem_file_free_line(intern); RETURN_LONG(php_stream_seek(intern->u.file.stream, pos, (int)whence)); @@ -2633,10 +2582,7 @@ PHP_METHOD(SplFileObject, fgetc) char buf[2]; int result; - if(!intern->u.file.stream) { - zend_throw_exception_ex(spl_ce_RuntimeException, 0, "Object not initialized"); - RETURN_THROWS(); - } + CHECK_SPL_FILE_OBJECT_IS_INITIALIZED(intern); spl_filesystem_file_free_line(intern); @@ -2660,10 +2606,7 @@ PHP_METHOD(SplFileObject, fpassthru) { spl_filesystem_object *intern = Z_SPLFILESYSTEM_P(ZEND_THIS); - if(!intern->u.file.stream) { - zend_throw_exception_ex(spl_ce_RuntimeException, 0, "Object not initialized"); - RETURN_THROWS(); - } + CHECK_SPL_FILE_OBJECT_IS_INITIALIZED(intern); RETURN_LONG(php_stream_passthru(intern->u.file.stream)); } /* }}} */ @@ -2671,17 +2614,27 @@ PHP_METHOD(SplFileObject, fpassthru) /* {{{ Implements a mostly ANSI compatible fscanf() */ PHP_METHOD(SplFileObject, fscanf) { + int result, num_varargs = 0; + zend_string *format_str; + zval *varargs= NULL; spl_filesystem_object *intern = Z_SPLFILESYSTEM_P(ZEND_THIS); - if(!intern->u.file.stream) { - zend_throw_exception_ex(spl_ce_RuntimeException, 0, "Object not initialized"); + if (zend_parse_parameters(ZEND_NUM_ARGS(), "S*", &format_str, &varargs, &num_varargs) == FAILURE) { RETURN_THROWS(); } - spl_filesystem_file_free_line(intern); - intern->u.file.current_line_num++; + CHECK_SPL_FILE_OBJECT_IS_INITIALIZED(intern); - FileFunctionCall(fscanf, ZEND_NUM_ARGS(), NULL); + /* Get next line */ + if (spl_filesystem_file_read(intern, 0) == FAILURE) { + RETURN_THROWS(); + } + + result = php_sscanf_internal(intern->u.file.current_line, ZSTR_VAL(format_str), num_varargs, varargs, 0, return_value); + + if (SCAN_ERROR_WRONG_PARAM_COUNT == result) { + WRONG_PARAM_COUNT; + } } /* }}} */ @@ -2698,10 +2651,7 @@ PHP_METHOD(SplFileObject, fwrite) RETURN_THROWS(); } - if(!intern->u.file.stream) { - zend_throw_exception_ex(spl_ce_RuntimeException, 0, "Object not initialized"); - RETURN_THROWS(); - } + CHECK_SPL_FILE_OBJECT_IS_INITIALIZED(intern); if (ZEND_NUM_ARGS() > 1) { if (length >= 0) { @@ -2732,10 +2682,7 @@ PHP_METHOD(SplFileObject, fread) RETURN_THROWS(); } - if(!intern->u.file.stream) { - zend_throw_exception_ex(spl_ce_RuntimeException, 0, "Object not initialized"); - RETURN_THROWS(); - } + CHECK_SPL_FILE_OBJECT_IS_INITIALIZED(intern); if (length <= 0) { php_error_docref(NULL, E_WARNING, "Length parameter must be greater than 0"); @@ -2750,7 +2697,18 @@ PHP_METHOD(SplFileObject, fread) } /* {{{ Stat() on a filehandle */ -FileFunction(fstat) +PHP_METHOD(SplFileObject, fstat) +{ + spl_filesystem_object *intern = Z_SPLFILESYSTEM_P(ZEND_THIS); + + if (zend_parse_parameters_none() == FAILURE) { + RETURN_THROWS(); + } + + CHECK_SPL_FILE_OBJECT_IS_INITIALIZED(intern); + + php_fstat(intern->u.file.stream, return_value); +} /* }}} */ /* {{{ Truncate file to 'size' length */ @@ -2763,10 +2721,7 @@ PHP_METHOD(SplFileObject, ftruncate) RETURN_THROWS(); } - if(!intern->u.file.stream) { - zend_throw_exception_ex(spl_ce_RuntimeException, 0, "Object not initialized"); - RETURN_THROWS(); - } + CHECK_SPL_FILE_OBJECT_IS_INITIALIZED(intern); if (!php_stream_truncate_supported(intern->u.file.stream)) { zend_throw_exception_ex(spl_ce_LogicException, 0, "Can't truncate file %s", intern->file_name); @@ -2785,10 +2740,8 @@ PHP_METHOD(SplFileObject, seek) if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &line_pos) == FAILURE) { RETURN_THROWS(); } - if(!intern->u.file.stream) { - zend_throw_exception_ex(spl_ce_RuntimeException, 0, "Object not initialized"); - RETURN_THROWS(); - } + + CHECK_SPL_FILE_OBJECT_IS_INITIALIZED(intern); if (line_pos < 0) { zend_throw_exception_ex(spl_ce_LogicException, 0, "Can't seek file %s to negative line " ZEND_LONG_FMT, intern->file_name, line_pos); diff --git a/ext/spl/tests/SplFileObject_fstat_with_basic_fstat_disabled.phpt b/ext/spl/tests/SplFileObject_fstat_with_basic_fstat_disabled.phpt new file mode 100644 index 0000000000000..dda7f1e4283fa --- /dev/null +++ b/ext/spl/tests/SplFileObject_fstat_with_basic_fstat_disabled.phpt @@ -0,0 +1,64 @@ +--TEST-- +SplFileObject::fstat when fstat() has been disabled. +--INI-- +disable_functions="fstat" +--FILE-- +fstat()); +?> +--EXPECTF-- +array(26) { + [0]=> + int(%i) + [1]=> + int(%i) + [2]=> + int(%i) + [3]=> + int(%i) + [4]=> + int(%i) + [5]=> + int(%i) + [6]=> + int(%i) + [7]=> + int(%i) + [8]=> + int(%i) + [9]=> + int(%i) + [10]=> + int(%i) + [11]=> + int(%i) + [12]=> + int(%i) + ["dev"]=> + int(%i) + ["ino"]=> + int(%i) + ["mode"]=> + int(%i) + ["nlink"]=> + int(%i) + ["uid"]=> + int(%i) + ["gid"]=> + int(%i) + ["rdev"]=> + int(%i) + ["size"]=> + int(%i) + ["atime"]=> + int(%i) + ["mtime"]=> + int(%i) + ["ctime"]=> + int(%i) + ["blksize"]=> + int(%i) + ["blocks"]=> + int(%i) +} diff --git a/ext/standard/file.c b/ext/standard/file.c index 9c08d163295ac..d402c60acf48e 100644 --- a/ext/standard/file.c +++ b/ext/standard/file.c @@ -344,7 +344,7 @@ PHP_FUNCTION(flock) PHP_STREAM_TO_ZVAL(stream, res); - act = operation & 3; + act = operation & PHP_LOCK_UN; if (act < 1 || act > 3) { zend_argument_value_error(2, "must be either LOCK_SH, LOCK_EX, or LOCK_UN"); RETURN_THROWS(); @@ -354,7 +354,7 @@ PHP_FUNCTION(flock) ZEND_TRY_ASSIGN_REF_LONG(wouldblock, 0); } - /* flock_values contains all possible actions if (operation & 4) we won't block on the lock */ + /* flock_values contains all possible actions if (operation & PHP_LOCK_NB) we won't block on the lock */ act = flock_values[act - 1] | (operation & PHP_LOCK_NB ? LOCK_NB : 0); if (php_stream_lock(stream, act)) { if (operation && errno == EWOULDBLOCK && wouldblock) { @@ -1487,26 +1487,16 @@ PHP_FUNCTION(ftruncate) RETURN_BOOL(0 == php_stream_truncate_set_size(stream, size)); } /* }}} */ - -/* {{{ Stat() on a filehandle */ -PHP_FUNCTION(fstat) +PHPAPI void php_fstat(php_stream *stream, zval *return_value) { - zval *fp; + php_stream_statbuf stat_ssb; zval stat_dev, stat_ino, stat_mode, stat_nlink, stat_uid, stat_gid, stat_rdev, stat_size, stat_atime, stat_mtime, stat_ctime, stat_blksize, stat_blocks; - php_stream *stream; - php_stream_statbuf stat_ssb; char *stat_sb_names[13] = { "dev", "ino", "mode", "nlink", "uid", "gid", "rdev", "size", "atime", "mtime", "ctime", "blksize", "blocks" }; - ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_RESOURCE(fp) - ZEND_PARSE_PARAMETERS_END(); - - PHP_STREAM_TO_ZVAL(stream, fp); - if (php_stream_stat(stream, &stat_ssb)) { RETURN_FALSE; } @@ -1568,6 +1558,21 @@ PHP_FUNCTION(fstat) zend_hash_str_add_new(Z_ARRVAL_P(return_value), stat_sb_names[11], strlen(stat_sb_names[11]), &stat_blksize); zend_hash_str_add_new(Z_ARRVAL_P(return_value), stat_sb_names[12], strlen(stat_sb_names[12]), &stat_blocks); } + +/* {{{ Stat() on a filehandle */ +PHP_FUNCTION(fstat) +{ + zval *fp; + php_stream *stream; + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_RESOURCE(fp) + ZEND_PARSE_PARAMETERS_END(); + + PHP_STREAM_TO_ZVAL(stream, fp); + + php_fstat(stream, return_value); +} /* }}} */ /* {{{ Copy a file */ diff --git a/ext/standard/file.h b/ext/standard/file.h index 28f906e0ba1ad..1faf667a00be5 100644 --- a/ext/standard/file.h +++ b/ext/standard/file.h @@ -43,6 +43,7 @@ PHPAPI int php_copy_file_ex(const char *src, const char *dest, int src_chk); PHPAPI int php_copy_file_ctx(const char *src, const char *dest, int src_chk, php_stream_context *ctx); PHPAPI int php_mkdir_ex(const char *dir, zend_long mode, int options); PHPAPI int php_mkdir(const char *dir, zend_long mode); +PHPAPI void php_fstat(php_stream *stream, zval *return_value); #define PHP_CSV_NO_ESCAPE EOF PHPAPI void php_fgetcsv(php_stream *stream, char delimiter, char enclosure, int escape_char, size_t buf_len, char *buf, zval *return_value); diff --git a/ext/standard/flock_compat.c b/ext/standard/flock_compat.c index 6751aedfc1990..7b0ad2df23cdc 100644 --- a/ext/standard/flock_compat.c +++ b/ext/standard/flock_compat.c @@ -18,17 +18,6 @@ #include #include "ext/standard/flock_compat.h" -#if HAVE_STRUCT_FLOCK -#include -#include -#include -#endif - -#ifdef PHP_WIN32 -#include -#include "config.w32.h" -#endif - #ifndef HAVE_FLOCK PHPAPI int flock(int fd, int operation) { diff --git a/ext/standard/flock_compat.h b/ext/standard/flock_compat.h index 7c875792c6443..11ed38b4baf34 100644 --- a/ext/standard/flock_compat.h +++ b/ext/standard/flock_compat.h @@ -17,6 +17,17 @@ #ifndef FLOCK_COMPAT_H #define FLOCK_COMPAT_H +#if HAVE_STRUCT_FLOCK +#include +#include +#include +#endif + +#ifdef PHP_WIN32 +#include +#include "config.w32.h" +#endif + /* php_flock internally uses fcntl whether or not flock is available * This way our php_flock even works on NFS files. * More info: /usr/src/linux/Documentation From 94fd52dd091051d4d4089c4c89b68fee6a876e23 Mon Sep 17 00:00:00 2001 From: Levi Morrison Date: Thu, 3 Sep 2020 07:03:12 -0600 Subject: [PATCH 36/87] Add Z_PARAM_ITERABLE and co --- Zend/tests/iterable_or_null.phpt | 49 ++++++++++++++++++++++++++++++++ Zend/zend_API.h | 31 ++++++++++++++++++++ build/gen_stub.php | 2 ++ ext/zend_test/test.c | 12 ++++++++ ext/zend_test/test.stub.php | 2 ++ ext/zend_test/test_arginfo.h | 9 +++++- 6 files changed, 104 insertions(+), 1 deletion(-) create mode 100644 Zend/tests/iterable_or_null.phpt diff --git a/Zend/tests/iterable_or_null.phpt b/Zend/tests/iterable_or_null.phpt new file mode 100644 index 0000000000000..9f798af06d766 --- /dev/null +++ b/Zend/tests/iterable_or_null.phpt @@ -0,0 +1,49 @@ +--TEST-- +Test Z_PARAM_ITERABLE() and Z_PARAM_ITERABLE_OR_NULL +--SKIPIF-- + +--FILE-- +getMessage() . "\n"; +} + +try { + var_dump(zend_iterable(1)); +} catch (TypeError $exception) { + echo $exception->getMessage() . "\n"; +} + +try { + var_dump(zend_iterable(null)); +} catch (TypeError $exception) { + echo $exception->getMessage() . "\n"; +} + + +zend_iterable([]); +zend_iterable([], []); + +$iterator = new ArrayIterator([]); +zend_iterable($iterator); +zend_iterable($iterator, $iterator); +zend_iterable($iterator, null); + +try { + var_dump(zend_iterable([], "string")); +} catch (TypeError $exception) { + echo $exception->getMessage() . "\n"; +} + +?> +--EXPECT-- +zend_iterable(): Argument #1 ($arg1) must be of type iterable, string given +zend_iterable(): Argument #1 ($arg1) must be of type iterable, int given +zend_iterable(): Argument #1 ($arg1) must be of type iterable, null given +zend_iterable(): Argument #2 ($arg2) must be of type ?iterable, string given + diff --git a/Zend/zend_API.h b/Zend/zend_API.h index 70e757c1bb630..a81a43f2314de 100644 --- a/Zend/zend_API.h +++ b/Zend/zend_API.h @@ -1209,6 +1209,8 @@ static zend_always_inline zval *zend_try_array_init(zval *zv) _(Z_EXPECTED_STRING_OR_NULL, "of type ?string") \ _(Z_EXPECTED_ARRAY, "of type array") \ _(Z_EXPECTED_ARRAY_OR_NULL, "of type ?array") \ + _(Z_EXPECTED_ITERABLE, "of type iterable") \ + _(Z_EXPECTED_ITERABLE_OR_NULL, "of type ?iterable") \ _(Z_EXPECTED_FUNC, "a valid callback") \ _(Z_EXPECTED_FUNC_OR_NULL, "a valid callback or null") \ _(Z_EXPECTED_RESOURCE, "of type resource") \ @@ -1373,6 +1375,20 @@ ZEND_API ZEND_COLD void zend_argument_value_error(uint32_t arg_num, const char * #define Z_PARAM_ARRAY_OR_OBJECT(dest) \ Z_PARAM_ARRAY_OR_OBJECT_EX(dest, 0, 0) +#define Z_PARAM_ITERABLE_EX(dest, check_null) \ + Z_PARAM_PROLOGUE(0, 0); \ + if (UNEXPECTED(!zend_parse_arg_iterable(_arg, &dest, check_null))) { \ + _expected_type = check_null ? Z_EXPECTED_ITERABLE_OR_NULL : Z_EXPECTED_ITERABLE; \ + _error_code = ZPP_ERROR_WRONG_ARG; \ + break; \ + } + +#define Z_PARAM_ITERABLE(dest) \ + Z_PARAM_ITERABLE_EX(dest, 0) + +#define Z_PARAM_ITERABLE_OR_NULL(dest) \ + Z_PARAM_ITERABLE_EX(dest, 1) + /* old "b" */ #define Z_PARAM_BOOL_EX2(dest, is_null, check_null, deref, separate) \ Z_PARAM_PROLOGUE(deref, separate); \ @@ -1903,6 +1919,21 @@ static zend_always_inline bool zend_parse_arg_path(zval *arg, char **dest, size_ return 1; } +static zend_always_inline bool zend_parse_arg_iterable(zval *arg, zval **dest, bool check_null) +{ + if (EXPECTED(zend_is_iterable(arg))) { + *dest = arg; + return 1; + } + + if (check_null && EXPECTED(Z_TYPE_P(arg) == IS_NULL)) { + *dest = NULL; + return 1; + } + + return 0; +} + static zend_always_inline bool zend_parse_arg_array(zval *arg, zval **dest, bool check_null, bool or_object) { if (EXPECTED(Z_TYPE_P(arg) == IS_ARRAY) || diff --git a/build/gen_stub.php b/build/gen_stub.php index 214d1f563e737..de2d3b144b06d 100755 --- a/build/gen_stub.php +++ b/build/gen_stub.php @@ -112,6 +112,8 @@ public function toTypeCode() { return "IS_VOID"; case "callable": return "IS_CALLABLE"; + case "iterable": + return "IS_ITERABLE"; case "mixed": return "IS_MIXED"; default: diff --git a/ext/zend_test/test.c b/ext/zend_test/test.c index 2d91543cf1f66..18e744331339b 100644 --- a/ext/zend_test/test.c +++ b/ext/zend_test/test.c @@ -221,6 +221,18 @@ ZEND_FUNCTION(zend_string_or_stdclass_or_null) } /* }}} */ +/* TESTS Z_PARAM_ITERABLE and Z_PARAM_ITERABLE_OR_NULL */ +ZEND_FUNCTION(zend_iterable) +{ + zval *arg1, *arg2; + + ZEND_PARSE_PARAMETERS_START(1, 2) + Z_PARAM_ITERABLE(arg1) + Z_PARAM_OPTIONAL + Z_PARAM_ITERABLE_OR_NULL(arg2) + ZEND_PARSE_PARAMETERS_END(); +} + static zend_object *zend_test_class_new(zend_class_entry *class_type) /* {{{ */ { zend_object *obj = zend_objects_new(class_type); object_properties_init(obj, class_type); diff --git a/ext/zend_test/test.stub.php b/ext/zend_test/test.stub.php index cc4a561f54237..1dd0cfec4e5b1 100644 --- a/ext/zend_test/test.stub.php +++ b/ext/zend_test/test.stub.php @@ -39,3 +39,5 @@ function zend_string_or_stdclass($param): stdClass|string {} /** @param stdClass|string|null $param */ function zend_string_or_stdclass_or_null($param): stdClass|string|null {} + +function zend_iterable(iterable $arg1, ?iterable $arg2 = null): void {} diff --git a/ext/zend_test/test_arginfo.h b/ext/zend_test/test_arginfo.h index ae7cd77b587c8..bd8d477b42b16 100644 --- a/ext/zend_test/test_arginfo.h +++ b/ext/zend_test/test_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 82fd97d4985448884141842955a4bee2c90ba338 */ + * Stub hash: 87c9d71b08c538c28b4f9bad01d7a7a3a3b191ef */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_zend_test_array_return, 0, 0, IS_ARRAY, 0) ZEND_END_ARG_INFO() @@ -46,6 +46,11 @@ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_zend_string_or_stdclass_or_n ZEND_ARG_INFO(0, param) ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_zend_iterable, 0, 1, IS_VOID, 0) + ZEND_ARG_TYPE_INFO(0, arg1, IS_ITERABLE, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, arg2, IS_ITERABLE, 1, "null") +ZEND_END_ARG_INFO() + ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class__ZendTestClass_is_object, 0, 0, IS_LONG, 0) ZEND_END_ARG_INFO() @@ -68,6 +73,7 @@ ZEND_FUNCTION(zend_string_or_object); ZEND_FUNCTION(zend_string_or_object_or_null); ZEND_FUNCTION(zend_string_or_stdclass); ZEND_FUNCTION(zend_string_or_stdclass_or_null); +ZEND_FUNCTION(zend_iterable); ZEND_METHOD(_ZendTestClass, is_object); ZEND_METHOD(_ZendTestClass, __toString); ZEND_METHOD(_ZendTestTrait, testMethod); @@ -86,6 +92,7 @@ static const zend_function_entry ext_functions[] = { ZEND_FE(zend_string_or_object_or_null, arginfo_zend_string_or_object_or_null) ZEND_FE(zend_string_or_stdclass, arginfo_zend_string_or_stdclass) ZEND_FE(zend_string_or_stdclass_or_null, arginfo_zend_string_or_stdclass_or_null) + ZEND_FE(zend_iterable, arginfo_zend_iterable) ZEND_FE_END }; From 42a6ff42010ee6d0670ee043e055ae223a3693d2 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Thu, 3 Sep 2020 15:06:42 +0200 Subject: [PATCH 37/87] Try to fix windows build --- ext/libxml/libxml.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/libxml/libxml.c b/ext/libxml/libxml.c index 5a18c1dde15b5..7dc4804905234 100644 --- a/ext/libxml/libxml.c +++ b/ext/libxml/libxml.c @@ -78,7 +78,7 @@ static PHP_RINIT_FUNCTION(libxml); static PHP_RSHUTDOWN_FUNCTION(libxml); static PHP_MSHUTDOWN_FUNCTION(libxml); static PHP_MINFO_FUNCTION(libxml); -static int php_libxml_post_deactivate(void); +static zend_result php_libxml_post_deactivate(void); /* }}} */ @@ -882,7 +882,7 @@ static PHP_MSHUTDOWN_FUNCTION(libxml) return SUCCESS; } -static int php_libxml_post_deactivate(void) +static zend_result php_libxml_post_deactivate(void) { /* reset libxml generic error handling */ if (_php_libxml_per_request_initialization) { From 5fdabeb9695d008afcc967bd6e0c60e889fa6883 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Thu, 3 Sep 2020 15:28:30 +0200 Subject: [PATCH 38/87] Fix Windows build --- ext/opcache/ZendAccelerator.c | 2 +- ext/opcache/ZendAccelerator.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c index 8683dc106f24a..6cef3ebe10c88 100644 --- a/ext/opcache/ZendAccelerator.c +++ b/ext/opcache/ZendAccelerator.c @@ -2547,7 +2547,7 @@ void accel_deactivate(void) } #endif -int accel_post_deactivate(void) +zend_result accel_post_deactivate(void) { if (ZCG(cwd)) { zend_string_release_ex(ZCG(cwd), 0); diff --git a/ext/opcache/ZendAccelerator.h b/ext/opcache/ZendAccelerator.h index 0d6dda86a1256..500647265cb96 100644 --- a/ext/opcache/ZendAccelerator.h +++ b/ext/opcache/ZendAccelerator.h @@ -317,7 +317,7 @@ extern char *zps_api_failure_reason; void accel_shutdown(void); zend_result accel_activate(INIT_FUNC_ARGS); -int accel_post_deactivate(void); +zend_result accel_post_deactivate(void); void zend_accel_schedule_restart(zend_accel_restart_reason reason); void zend_accel_schedule_restart_if_necessary(zend_accel_restart_reason reason); accel_time_t zend_get_file_handle_timestamp(zend_file_handle *file_handle, size_t *size); From 1848ccdae2b9fbdfbbe8de56f8eda8b8869c825e Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Thu, 3 Sep 2020 14:27:45 +0200 Subject: [PATCH 39/87] Fix #80048: Bug #69100 has not been fixed for Windows We fix the erroneous length calculation on Windows, too. Closes GH-6067. --- NEWS | 3 +++ main/streams/plain_wrapper.c | 12 ++++-------- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/NEWS b/NEWS index 8a2432c2df8a1..0800e83e0f934 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,9 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? ????, PHP 7.3.23 +- Core: + . Fixed bug #80048 (Bug #69100 has not been fixed for Windows). (cmb) + - Calendar: . Fixed bug #80007 (Potential type confusion in unixtojd() parameter parsing). (Andy Postnikov) diff --git a/main/streams/plain_wrapper.c b/main/streams/plain_wrapper.c index c975997981304..2b81912857626 100644 --- a/main/streams/plain_wrapper.c +++ b/main/streams/plain_wrapper.c @@ -786,15 +786,11 @@ static int php_stdiop_set_option(php_stream *stream, int option, int value, void } size = GetFileSize(hfile, NULL); - if (range->length == 0 && range->offset > 0 && range->offset < size) { - range->length = size - range->offset; - } - if (range->length == 0 || range->length > size) { - range->length = size; - } - if (range->offset >= size) { + if (range->offset > size) { range->offset = size; - range->length = 0; + } + if (range->length == 0 || range->length > size - range->offset) { + range->length = size - range->offset; } /* figure out how big a chunk to map to be able to view the part that we need */ From 409aa20ab0f1c4673366b2cbfc4d618e710ff7bf Mon Sep 17 00:00:00 2001 From: Alex Dowad Date: Wed, 15 Jul 2020 21:56:33 +0200 Subject: [PATCH 40/87] Refactor mbfl_convert.c --- .../libmbfl/filters/mbfilter_cp5022x.c | 2 +- ext/mbstring/libmbfl/mbfl/mbfilter.c | 10 +- ext/mbstring/libmbfl/mbfl/mbfl_convert.c | 159 +++++------------- ext/mbstring/libmbfl/mbfl/mbfl_convert.h | 28 ++- ext/mbstring/mbstring.c | 2 +- 5 files changed, 65 insertions(+), 136 deletions(-) diff --git a/ext/mbstring/libmbfl/filters/mbfilter_cp5022x.c b/ext/mbstring/libmbfl/filters/mbfilter_cp5022x.c index 4b63602916de2..a20115416999d 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_cp5022x.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_cp5022x.c @@ -592,7 +592,7 @@ mbfl_filt_conv_wchar_cp50220_ctor(mbfl_convert_filter *filt) filt->filter_function = vtbl_tl_jisx0201_jisx0208.filter_function; filt->filter_flush = vtbl_tl_jisx0201_jisx0208.filter_flush; filt->output_function = (int(*)(int, void *))ctx->last.filter_function; - filt->flush_function = (int(*)(void *))ctx->last.filter_flush; + filt->flush_function = ctx->last.filter_flush; filt->data = &ctx->last; filt->opaque = ctx; vtbl_tl_jisx0201_jisx0208.filter_ctor(filt); diff --git a/ext/mbstring/libmbfl/mbfl/mbfilter.c b/ext/mbstring/libmbfl/mbfl/mbfilter.c index a1191716a170f..65817d384a2f0 100644 --- a/ext/mbstring/libmbfl/mbfl/mbfilter.c +++ b/ext/mbstring/libmbfl/mbfl/mbfilter.c @@ -131,7 +131,7 @@ mbfl_buffer_converter_new( convd->filter1 = mbfl_convert_filter_new(convd->from, &mbfl_encoding_wchar, (int (*)(int, void*))convd->filter2->filter_function, - (int (*)(void*))convd->filter2->filter_flush, + convd->filter2->filter_flush, convd->filter2); if (convd->filter1 == NULL) { mbfl_convert_filter_delete(convd->filter2); @@ -1205,7 +1205,7 @@ mbfl_strcut( /* switch the drain direction */ encoder->output_function = (int(*)(int,void *))decoder->filter_function; - encoder->flush_function = (int(*)(void *))decoder->filter_flush; + encoder->flush_function = decoder->filter_flush; encoder->data = decoder; q = string->val + string->len; @@ -1591,7 +1591,7 @@ mbfl_ja_jp_hantozen( tl_filter = mbfl_convert_filter_new2( &vtbl_tl_jisx0201_jisx0208, (int(*)(int, void*))next_filter->filter_function, - (int(*)(void*))next_filter->filter_flush, + next_filter->filter_flush, next_filter); if (tl_filter == NULL) { efree(param); @@ -1605,7 +1605,7 @@ mbfl_ja_jp_hantozen( string->encoding, &mbfl_encoding_wchar, (int(*)(int, void*))next_filter->filter_function, - (int(*)(void*))next_filter->filter_flush, + next_filter->filter_flush, next_filter); if (encoder == NULL) { goto out; @@ -2623,7 +2623,7 @@ mbfl_html_numeric_entity( string->encoding, &mbfl_encoding_wchar, collector_decode_htmlnumericentity, - (int (*)(void*))mbfl_filt_decode_htmlnumericentity_flush, &pc); + mbfl_filt_decode_htmlnumericentity_flush, &pc); } if (pc.decoder == NULL || encoder == NULL) { mbfl_convert_filter_delete(encoder); diff --git a/ext/mbstring/libmbfl/mbfl/mbfl_convert.c b/ext/mbstring/libmbfl/mbfl/mbfl_convert.c index e301254e031a3..0f41e35b25158 100644 --- a/ext/mbstring/libmbfl/mbfl/mbfl_convert.c +++ b/ext/mbstring/libmbfl/mbfl/mbfl_convert.c @@ -115,15 +115,8 @@ static const struct mbfl_convert_vtbl *mbfl_special_filter_list[] = { NULL }; -static int -mbfl_convert_filter_common_init( - mbfl_convert_filter *filter, - const mbfl_encoding *from, - const mbfl_encoding *to, - const struct mbfl_convert_vtbl *vtbl, - int (*output_function)(int, void* ), - int (*flush_function)(void*), - void* data) +static void mbfl_convert_filter_common_init(mbfl_convert_filter *filter, const mbfl_encoding *from, const mbfl_encoding *to, + const struct mbfl_convert_vtbl *vtbl, filter_output_func output_function, filter_flush_func flush_function, void* data) { /* encoding structure */ filter->from = from; @@ -138,7 +131,7 @@ mbfl_convert_filter_common_init( filter->flush_function = flush_function; filter->data = data; filter->illegal_mode = MBFL_OUTPUTFILTER_ILLEGAL_MODE_CHAR; - filter->illegal_substchar = 0x3f; /* '?' */ + filter->illegal_substchar = '?'; filter->num_illegalchar = 0; filter->filter_ctor = vtbl->filter_ctor; filter->filter_dtor = vtbl->filter_dtor; @@ -147,102 +140,63 @@ mbfl_convert_filter_common_init( filter->filter_copy = vtbl->filter_copy; (*filter->filter_ctor)(filter); - - return 0; } -mbfl_convert_filter * -mbfl_convert_filter_new( - const mbfl_encoding *from, - const mbfl_encoding *to, - int (*output_function)(int, void* ), - int (*flush_function)(void*), - void* data) +mbfl_convert_filter* mbfl_convert_filter_new(const mbfl_encoding *from, const mbfl_encoding *to, filter_output_func output_function, + filter_flush_func flush_function, void* data) { - mbfl_convert_filter *filter; - const struct mbfl_convert_vtbl *vtbl; - - vtbl = mbfl_convert_filter_get_vtbl(from, to); + const struct mbfl_convert_vtbl *vtbl = mbfl_convert_filter_get_vtbl(from, to); if (vtbl == NULL) { return NULL; } - filter = emalloc(sizeof(mbfl_convert_filter)); - - if (mbfl_convert_filter_common_init(filter, from, to, vtbl, - output_function, flush_function, data)) { - efree(filter); - return NULL; - } - + mbfl_convert_filter *filter = emalloc(sizeof(mbfl_convert_filter)); + mbfl_convert_filter_common_init(filter, from, to, vtbl, output_function, flush_function, data); return filter; } -mbfl_convert_filter * -mbfl_convert_filter_new2( - const struct mbfl_convert_vtbl *vtbl, - int (*output_function)(int, void* ), - int (*flush_function)(void*), - void* data) +mbfl_convert_filter* mbfl_convert_filter_new2(const struct mbfl_convert_vtbl *vtbl, filter_output_func output_function, + filter_flush_func flush_function, void* data) { - mbfl_convert_filter *filter; - const mbfl_encoding *from_encoding, *to_encoding; - - if (vtbl == NULL) { - vtbl = &vtbl_pass; - } - - from_encoding = mbfl_no2encoding(vtbl->from); - to_encoding = mbfl_no2encoding(vtbl->to); - - filter = emalloc(sizeof(mbfl_convert_filter)); - - if (mbfl_convert_filter_common_init(filter, from_encoding, to_encoding, vtbl, - output_function, flush_function, data)) { - efree(filter); - return NULL; - } + const mbfl_encoding *from_encoding = mbfl_no2encoding(vtbl->from); + const mbfl_encoding *to_encoding = mbfl_no2encoding(vtbl->to); + mbfl_convert_filter *filter = emalloc(sizeof(mbfl_convert_filter)); + mbfl_convert_filter_common_init(filter, from_encoding, to_encoding, vtbl, output_function, flush_function, data); return filter; } -void -mbfl_convert_filter_delete(mbfl_convert_filter *filter) +void mbfl_convert_filter_delete(mbfl_convert_filter *filter) { - if (filter) { - (*filter->filter_dtor)(filter); - efree((void*)filter); - } + (*filter->filter_dtor)(filter); + efree(filter); } -int -mbfl_convert_filter_feed_string(mbfl_convert_filter *filter, const unsigned char *p, size_t len) { - while (len > 0) { +/* Feed string into `filter` byte by byte; return pointer to first byte not processed */ +unsigned char* mbfl_convert_filter_feed_string(mbfl_convert_filter *filter, unsigned char *p, size_t len) +{ + while (len--) { if ((*filter->filter_function)(*p++, filter) < 0) { - return -1; + break; } - len--; } - return 0; + return p; } -int -mbfl_convert_filter_flush(mbfl_convert_filter *filter) +int mbfl_convert_filter_flush(mbfl_convert_filter *filter) { (*filter->filter_flush)(filter); - return (filter->flush_function ? (*filter->flush_function)(filter->data) : 0); + return filter->flush_function ? (*filter->flush_function)(filter->data) : 0; } -void mbfl_convert_filter_reset(mbfl_convert_filter *filter, - const mbfl_encoding *from, const mbfl_encoding *to) +void mbfl_convert_filter_reset(mbfl_convert_filter *filter, const mbfl_encoding *from, const mbfl_encoding *to) { - const struct mbfl_convert_vtbl *vtbl; - - /* destruct old filter */ - (*filter->filter_dtor)(filter); + if (filter->filter_dtor) { + (*filter->filter_dtor)(filter); + } - vtbl = mbfl_convert_filter_get_vtbl(from, to); + const struct mbfl_convert_vtbl *vtbl = mbfl_convert_filter_get_vtbl(from, to); if (vtbl == NULL) { vtbl = &vtbl_pass; @@ -252,10 +206,7 @@ void mbfl_convert_filter_reset(mbfl_convert_filter *filter, filter->output_function, filter->flush_function, filter->data); } -void -mbfl_convert_filter_copy( - mbfl_convert_filter *src, - mbfl_convert_filter *dest) +void mbfl_convert_filter_copy(mbfl_convert_filter *src, mbfl_convert_filter *dest) { if (src->filter_copy != NULL) { src->filter_copy(src, dest); @@ -265,28 +216,15 @@ mbfl_convert_filter_copy( *dest = *src; } -int mbfl_convert_filter_devcat(mbfl_convert_filter *filter, mbfl_memory_device *src) +void mbfl_convert_filter_devcat(mbfl_convert_filter *filter, mbfl_memory_device *src) { - size_t n; - unsigned char *p; - - p = src->buffer; - n = src->pos; - while (n > 0) { - if ((*filter->filter_function)(*p++, filter) < 0) { - return -1; - } - n--; - } - - return 0; + mbfl_convert_filter_feed_string(filter, src->buffer, src->pos); } int mbfl_convert_filter_strcat(mbfl_convert_filter *filter, const unsigned char *p) { int c; - - while ((c = *p++) != '\0') { + while ((c = *p++)) { if ((*filter->filter_function)(c, filter) < 0) { return -1; } @@ -296,22 +234,20 @@ int mbfl_convert_filter_strcat(mbfl_convert_filter *filter, const unsigned char } /* illegal character output function for conv-filter */ -int -mbfl_filt_conv_illegal_output(int c, mbfl_convert_filter *filter) +int mbfl_filt_conv_illegal_output(int c, mbfl_convert_filter *filter) { - int mode_backup, substchar_backup, ret, n, m, r; - - ret = 0; + int n, m, r; - mode_backup = filter->illegal_mode; - substchar_backup = filter->illegal_substchar; + int ret = 0; + int mode_backup = filter->illegal_mode; + int substchar_backup = filter->illegal_substchar; /* The used substitution character may not be supported by the target character encoding. * If that happens, first try to use "?" instead and if that also fails, silently drop the * character. */ if (filter->illegal_mode == MBFL_OUTPUTFILTER_ILLEGAL_MODE_CHAR - && filter->illegal_substchar != 0x3f) { - filter->illegal_substchar = 0x3f; + && filter->illegal_substchar != '?') { + filter->illegal_substchar = '?'; } else { filter->illegal_mode = MBFL_OUTPUTFILTER_ILLEGAL_MODE_NONE; } @@ -370,7 +306,7 @@ mbfl_filt_conv_illegal_output(int c, mbfl_convert_filter *filter) } r -= 4; } - if (m == 0 && ret >= 0) { + if (m == 0) { ret = (*filter->filter_function)(mbfl_hexchar_table[0], filter); } } @@ -396,11 +332,9 @@ mbfl_filt_conv_illegal_output(int c, mbfl_convert_filter *filter) } r -= 4; } - if (ret < 0) { - break; - } if (m == 0) { - ret = (*filter->filter_function)(mbfl_hexchar_table[0], filter); + /* illegal character was zero; no hex digits were output by above loop */ + ret = (*filter->filter_function)('0', filter); } ret = mbfl_convert_filter_strcat(filter, (const unsigned char *)";"); } else { @@ -420,8 +354,7 @@ mbfl_filt_conv_illegal_output(int c, mbfl_convert_filter *filter) return ret; } -const struct mbfl_convert_vtbl * mbfl_convert_filter_get_vtbl( - const mbfl_encoding *from, const mbfl_encoding *to) +const struct mbfl_convert_vtbl* mbfl_convert_filter_get_vtbl(const mbfl_encoding *from, const mbfl_encoding *to) { if (to->no_encoding == mbfl_no_encoding_base64 || to->no_encoding == mbfl_no_encoding_qprint || @@ -444,7 +377,7 @@ const struct mbfl_convert_vtbl * mbfl_convert_filter_get_vtbl( } else { int i = 0; const struct mbfl_convert_vtbl *vtbl; - while ((vtbl = mbfl_special_filter_list[i++]) != NULL){ + while ((vtbl = mbfl_special_filter_list[i++])) { if (vtbl->from == from->no_encoding && vtbl->to == to->no_encoding) { return vtbl; } diff --git a/ext/mbstring/libmbfl/mbfl/mbfl_convert.h b/ext/mbstring/libmbfl/mbfl/mbfl_convert.h index 852e669dac913..f38de7eefe628 100644 --- a/ext/mbstring/libmbfl/mbfl/mbfl_convert.h +++ b/ext/mbstring/libmbfl/mbfl/mbfl_convert.h @@ -37,14 +37,17 @@ typedef struct _mbfl_convert_filter mbfl_convert_filter; +typedef int (*filter_output_func)(int, void*); +typedef int (*filter_flush_func)(mbfl_convert_filter*); + struct _mbfl_convert_filter { void (*filter_ctor)(mbfl_convert_filter *filter); void (*filter_dtor)(mbfl_convert_filter *filter); void (*filter_copy)(mbfl_convert_filter *src, mbfl_convert_filter *dest); int (*filter_function)(int c, mbfl_convert_filter *filter); - int (*filter_flush)(mbfl_convert_filter *filter); - int (*output_function)(int c, void *data); - int (*flush_function)(void *data); + filter_flush_func filter_flush; + filter_output_func output_function; + filter_flush_func flush_function; void *data; int status; int cache; @@ -56,19 +59,12 @@ struct _mbfl_convert_filter { void *opaque; }; -MBFLAPI extern mbfl_convert_filter *mbfl_convert_filter_new( - const mbfl_encoding *from, - const mbfl_encoding *to, - int (*output_function)(int, void *), - int (*flush_function)(void *), - void *data ); -MBFLAPI extern mbfl_convert_filter *mbfl_convert_filter_new2( - const struct mbfl_convert_vtbl *vtbl, - int (*output_function)(int, void *), - int (*flush_function)(void *), - void *data ); +MBFLAPI extern mbfl_convert_filter *mbfl_convert_filter_new(const mbfl_encoding *from, const mbfl_encoding *to, filter_output_func output_function, + filter_flush_func flush_function, void *data); +MBFLAPI extern mbfl_convert_filter *mbfl_convert_filter_new2(const struct mbfl_convert_vtbl *vtbl, filter_output_func output_function, + filter_flush_func flush_function, void *data); MBFLAPI extern void mbfl_convert_filter_delete(mbfl_convert_filter *filter); -MBFLAPI extern int mbfl_convert_filter_feed_string(mbfl_convert_filter *filter, const unsigned char *p, size_t len); +MBFLAPI extern unsigned char* mbfl_convert_filter_feed_string(mbfl_convert_filter *filter, unsigned char *p, size_t len); MBFLAPI extern int mbfl_convert_filter_flush(mbfl_convert_filter *filter); MBFLAPI extern void mbfl_convert_filter_reset(mbfl_convert_filter *filter, const mbfl_encoding *from, const mbfl_encoding *to); MBFLAPI extern void mbfl_convert_filter_copy(mbfl_convert_filter *src, mbfl_convert_filter *dist); @@ -79,7 +75,7 @@ MBFLAPI extern void mbfl_filt_conv_common_ctor(mbfl_convert_filter *filter); MBFLAPI extern int mbfl_filt_conv_common_flush(mbfl_convert_filter *filter); MBFLAPI extern void mbfl_filt_conv_common_dtor(mbfl_convert_filter *filter); -MBFLAPI extern int mbfl_convert_filter_devcat(mbfl_convert_filter *filter, mbfl_memory_device *src); +MBFLAPI extern void mbfl_convert_filter_devcat(mbfl_convert_filter *filter, mbfl_memory_device *src); MBFLAPI extern int mbfl_convert_filter_strcat(mbfl_convert_filter *filter, const unsigned char *p); #endif /* MBFL_CONVERT_H */ diff --git a/ext/mbstring/mbstring.c b/ext/mbstring/mbstring.c index 13031d90d3e39..24c55509759dc 100644 --- a/ext/mbstring/mbstring.c +++ b/ext/mbstring/mbstring.c @@ -4104,7 +4104,7 @@ static inline zend_long php_mb_ord(const char *str, size_t str_len, zend_string /* If this assertion fails this means some memory allocation failure which is a bug */ ZEND_ASSERT(filter != NULL); - mbfl_convert_filter_feed_string(filter, (const unsigned char *) str, str_len); + mbfl_convert_filter_feed_string(filter, (unsigned char*)str, str_len); mbfl_convert_filter_flush(filter); if (dev.pos < 1 || filter->num_illegalchar || dev.buffer[0] >= MBFL_WCSGROUP_UCS4MAX) { From dcd6c6043eff310ac160551ffeeaa905c7e26aa5 Mon Sep 17 00:00:00 2001 From: Alex Dowad Date: Thu, 16 Jul 2020 09:15:56 +0200 Subject: [PATCH 41/87] Remove unneeded function mbfl_filt_conv_common_dtor This is a default destructor for mbfl_convert_filter structs. The thing is: there isn't really anything that needs to be done to those structs before freeing them. The default destructor just zeroed out some fields, but there's no reason why we should actually do that. --- ext/mbstring/libmbfl/filters/mbfilter_7bit.c | 4 +- .../libmbfl/filters/mbfilter_armscii8.c | 4 +- ext/mbstring/libmbfl/filters/mbfilter_ascii.c | 4 +- .../libmbfl/filters/mbfilter_base64.c | 4 +- ext/mbstring/libmbfl/filters/mbfilter_big5.c | 8 +-- ext/mbstring/libmbfl/filters/mbfilter_byte2.c | 8 +-- ext/mbstring/libmbfl/filters/mbfilter_byte4.c | 8 +-- .../libmbfl/filters/mbfilter_cp1251.c | 4 +- .../libmbfl/filters/mbfilter_cp1252.c | 4 +- .../libmbfl/filters/mbfilter_cp1254.c | 4 +- .../libmbfl/filters/mbfilter_cp5022x.c | 20 +++--- .../libmbfl/filters/mbfilter_cp51932.c | 4 +- ext/mbstring/libmbfl/filters/mbfilter_cp850.c | 4 +- ext/mbstring/libmbfl/filters/mbfilter_cp866.c | 4 +- ext/mbstring/libmbfl/filters/mbfilter_cp932.c | 4 +- ext/mbstring/libmbfl/filters/mbfilter_cp936.c | 4 +- .../libmbfl/filters/mbfilter_euc_cn.c | 4 +- .../libmbfl/filters/mbfilter_euc_jp.c | 4 +- .../libmbfl/filters/mbfilter_euc_jp_2004.c | 4 +- .../libmbfl/filters/mbfilter_euc_jp_win.c | 4 +- .../libmbfl/filters/mbfilter_euc_kr.c | 4 +- .../libmbfl/filters/mbfilter_euc_tw.c | 4 +- .../libmbfl/filters/mbfilter_gb18030.c | 4 +- .../libmbfl/filters/mbfilter_htmlent.c | 2 +- .../libmbfl/filters/mbfilter_htmlent.h | 2 - ext/mbstring/libmbfl/filters/mbfilter_hz.c | 4 +- .../libmbfl/filters/mbfilter_iso2022_jp_ms.c | 4 +- .../libmbfl/filters/mbfilter_iso2022_kr.c | 4 +- .../libmbfl/filters/mbfilter_iso2022jp_2004.c | 4 +- .../filters/mbfilter_iso2022jp_mobile.c | 4 +- .../libmbfl/filters/mbfilter_iso8859_1.c | 4 +- .../libmbfl/filters/mbfilter_iso8859_10.c | 4 +- .../libmbfl/filters/mbfilter_iso8859_13.c | 4 +- .../libmbfl/filters/mbfilter_iso8859_14.c | 4 +- .../libmbfl/filters/mbfilter_iso8859_15.c | 4 +- .../libmbfl/filters/mbfilter_iso8859_16.c | 4 +- .../libmbfl/filters/mbfilter_iso8859_2.c | 4 +- .../libmbfl/filters/mbfilter_iso8859_3.c | 4 +- .../libmbfl/filters/mbfilter_iso8859_4.c | 4 +- .../libmbfl/filters/mbfilter_iso8859_5.c | 4 +- .../libmbfl/filters/mbfilter_iso8859_6.c | 4 +- .../libmbfl/filters/mbfilter_iso8859_7.c | 4 +- .../libmbfl/filters/mbfilter_iso8859_8.c | 4 +- .../libmbfl/filters/mbfilter_iso8859_9.c | 4 +- ext/mbstring/libmbfl/filters/mbfilter_jis.c | 8 +-- ext/mbstring/libmbfl/filters/mbfilter_koi8r.c | 4 +- ext/mbstring/libmbfl/filters/mbfilter_koi8u.c | 4 +- .../libmbfl/filters/mbfilter_qprint.c | 4 +- ext/mbstring/libmbfl/filters/mbfilter_sjis.c | 4 +- .../libmbfl/filters/mbfilter_sjis_2004.c | 4 +- .../libmbfl/filters/mbfilter_sjis_mac.c | 4 +- .../libmbfl/filters/mbfilter_sjis_mobile.c | 12 ++-- .../libmbfl/filters/mbfilter_sjis_open.c | 4 +- .../filters/mbfilter_tl_jisx0201_jisx0208.c | 7 +- ext/mbstring/libmbfl/filters/mbfilter_ucs2.c | 12 ++-- ext/mbstring/libmbfl/filters/mbfilter_ucs4.c | 12 ++-- ext/mbstring/libmbfl/filters/mbfilter_uhc.c | 4 +- ext/mbstring/libmbfl/filters/mbfilter_utf16.c | 12 ++-- ext/mbstring/libmbfl/filters/mbfilter_utf32.c | 12 ++-- ext/mbstring/libmbfl/filters/mbfilter_utf7.c | 4 +- .../libmbfl/filters/mbfilter_utf7imap.c | 4 +- ext/mbstring/libmbfl/filters/mbfilter_utf8.c | 4 +- .../libmbfl/filters/mbfilter_utf8_mobile.c | 16 ++--- .../libmbfl/filters/mbfilter_uuencode.c | 2 +- ext/mbstring/libmbfl/mbfl/mbfilter.c | 66 ++++++++++++------- ext/mbstring/libmbfl/mbfl/mbfilter_8bit.c | 4 +- ext/mbstring/libmbfl/mbfl/mbfilter_pass.c | 2 +- ext/mbstring/libmbfl/mbfl/mbfl_convert.c | 12 ++-- ext/mbstring/libmbfl/mbfl/mbfl_convert.h | 1 - 69 files changed, 214 insertions(+), 208 deletions(-) diff --git a/ext/mbstring/libmbfl/filters/mbfilter_7bit.c b/ext/mbstring/libmbfl/filters/mbfilter_7bit.c index 451860f435bfe..42ed23326daf6 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_7bit.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_7bit.c @@ -46,7 +46,7 @@ const struct mbfl_convert_vtbl vtbl_8bit_7bit = { mbfl_no_encoding_8bit, mbfl_no_encoding_7bit, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_any_7bit, mbfl_filt_conv_common_flush, NULL, @@ -56,7 +56,7 @@ const struct mbfl_convert_vtbl vtbl_7bit_8bit = { mbfl_no_encoding_7bit, mbfl_no_encoding_8bit, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_7bit_any, mbfl_filt_conv_common_flush, NULL, diff --git a/ext/mbstring/libmbfl/filters/mbfilter_armscii8.c b/ext/mbstring/libmbfl/filters/mbfilter_armscii8.c index 697e37dee9976..e168176cc03d2 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_armscii8.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_armscii8.c @@ -56,7 +56,7 @@ const struct mbfl_convert_vtbl vtbl_wchar_armscii8 = { mbfl_no_encoding_wchar, mbfl_no_encoding_armscii8, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_wchar_armscii8, mbfl_filt_conv_common_flush, NULL, @@ -66,7 +66,7 @@ const struct mbfl_convert_vtbl vtbl_armscii8_wchar = { mbfl_no_encoding_armscii8, mbfl_no_encoding_wchar, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_armscii8_wchar, mbfl_filt_conv_common_flush, NULL, diff --git a/ext/mbstring/libmbfl/filters/mbfilter_ascii.c b/ext/mbstring/libmbfl/filters/mbfilter_ascii.c index 489f1deea340a..a1e9533bc86b2 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_ascii.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_ascii.c @@ -57,7 +57,7 @@ const struct mbfl_convert_vtbl vtbl_ascii_wchar = { mbfl_no_encoding_ascii, mbfl_no_encoding_wchar, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_ascii_wchar, mbfl_filt_conv_common_flush, NULL, @@ -67,7 +67,7 @@ const struct mbfl_convert_vtbl vtbl_wchar_ascii = { mbfl_no_encoding_wchar, mbfl_no_encoding_ascii, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_wchar_ascii, mbfl_filt_conv_common_flush, NULL, diff --git a/ext/mbstring/libmbfl/filters/mbfilter_base64.c b/ext/mbstring/libmbfl/filters/mbfilter_base64.c index 45a2049c03788..9e5548b49419a 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_base64.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_base64.c @@ -46,7 +46,7 @@ const struct mbfl_convert_vtbl vtbl_8bit_b64 = { mbfl_no_encoding_8bit, mbfl_no_encoding_base64, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_base64enc, mbfl_filt_conv_base64enc_flush, NULL, @@ -56,7 +56,7 @@ const struct mbfl_convert_vtbl vtbl_b64_8bit = { mbfl_no_encoding_base64, mbfl_no_encoding_8bit, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_base64dec, mbfl_filt_conv_base64dec_flush, NULL, diff --git a/ext/mbstring/libmbfl/filters/mbfilter_big5.c b/ext/mbstring/libmbfl/filters/mbfilter_big5.c index 692f449d54293..6d0d22aa192d2 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_big5.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_big5.c @@ -95,7 +95,7 @@ const struct mbfl_convert_vtbl vtbl_big5_wchar = { mbfl_no_encoding_big5, mbfl_no_encoding_wchar, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_big5_wchar, mbfl_filt_conv_common_flush, NULL, @@ -105,7 +105,7 @@ const struct mbfl_convert_vtbl vtbl_wchar_big5 = { mbfl_no_encoding_wchar, mbfl_no_encoding_big5, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_wchar_big5, mbfl_filt_conv_common_flush, NULL @@ -115,7 +115,7 @@ const struct mbfl_convert_vtbl vtbl_cp950_wchar = { mbfl_no_encoding_cp950, mbfl_no_encoding_wchar, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_big5_wchar, mbfl_filt_conv_common_flush, NULL, @@ -125,7 +125,7 @@ const struct mbfl_convert_vtbl vtbl_wchar_cp950 = { mbfl_no_encoding_wchar, mbfl_no_encoding_cp950, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_wchar_big5, mbfl_filt_conv_common_flush, NULL, diff --git a/ext/mbstring/libmbfl/filters/mbfilter_byte2.c b/ext/mbstring/libmbfl/filters/mbfilter_byte2.c index 8a9f80fe56981..72b5b2b7b2f8a 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_byte2.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_byte2.c @@ -57,7 +57,7 @@ const struct mbfl_convert_vtbl vtbl_byte2be_wchar = { mbfl_no_encoding_byte2be, mbfl_no_encoding_wchar, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_byte2be_wchar, mbfl_filt_conv_common_flush, NULL, @@ -67,7 +67,7 @@ const struct mbfl_convert_vtbl vtbl_wchar_byte2be = { mbfl_no_encoding_wchar, mbfl_no_encoding_byte2be, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_wchar_byte2be, mbfl_filt_conv_common_flush, NULL, @@ -77,7 +77,7 @@ const struct mbfl_convert_vtbl vtbl_byte2le_wchar = { mbfl_no_encoding_byte2le, mbfl_no_encoding_wchar, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_byte2le_wchar, mbfl_filt_conv_common_flush, NULL, @@ -87,7 +87,7 @@ const struct mbfl_convert_vtbl vtbl_wchar_byte2le = { mbfl_no_encoding_wchar, mbfl_no_encoding_byte2le, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_wchar_byte2le, mbfl_filt_conv_common_flush, NULL, diff --git a/ext/mbstring/libmbfl/filters/mbfilter_byte4.c b/ext/mbstring/libmbfl/filters/mbfilter_byte4.c index 22ff22fd41b0e..b566e547725d7 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_byte4.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_byte4.c @@ -57,7 +57,7 @@ const struct mbfl_convert_vtbl vtbl_byte4be_wchar = { mbfl_no_encoding_byte4be, mbfl_no_encoding_wchar, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_byte4be_wchar, mbfl_filt_conv_common_flush, NULL, @@ -67,7 +67,7 @@ const struct mbfl_convert_vtbl vtbl_wchar_byte4be = { mbfl_no_encoding_wchar, mbfl_no_encoding_byte4be, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_wchar_byte4be, mbfl_filt_conv_common_flush, NULL, @@ -77,7 +77,7 @@ const struct mbfl_convert_vtbl vtbl_byte4le_wchar = { mbfl_no_encoding_byte4le, mbfl_no_encoding_wchar, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_byte4le_wchar, mbfl_filt_conv_common_flush, NULL, @@ -87,7 +87,7 @@ const struct mbfl_convert_vtbl vtbl_wchar_byte4le = { mbfl_no_encoding_wchar, mbfl_no_encoding_byte4le, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_wchar_byte4le, mbfl_filt_conv_common_flush, NULL, diff --git a/ext/mbstring/libmbfl/filters/mbfilter_cp1251.c b/ext/mbstring/libmbfl/filters/mbfilter_cp1251.c index 5295700e2888a..021c2f617ef92 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_cp1251.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_cp1251.c @@ -57,7 +57,7 @@ const struct mbfl_convert_vtbl vtbl_wchar_cp1251 = { mbfl_no_encoding_wchar, mbfl_no_encoding_cp1251, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_wchar_cp1251, mbfl_filt_conv_common_flush, NULL, @@ -67,7 +67,7 @@ const struct mbfl_convert_vtbl vtbl_cp1251_wchar = { mbfl_no_encoding_cp1251, mbfl_no_encoding_wchar, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_cp1251_wchar, mbfl_filt_conv_common_flush, NULL, diff --git a/ext/mbstring/libmbfl/filters/mbfilter_cp1252.c b/ext/mbstring/libmbfl/filters/mbfilter_cp1252.c index 7e9a69881d767..8208efffaa93c 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_cp1252.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_cp1252.c @@ -57,7 +57,7 @@ const struct mbfl_convert_vtbl vtbl_cp1252_wchar = { mbfl_no_encoding_cp1252, mbfl_no_encoding_wchar, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_cp1252_wchar, mbfl_filt_conv_common_flush, NULL, @@ -67,7 +67,7 @@ const struct mbfl_convert_vtbl vtbl_wchar_cp1252 = { mbfl_no_encoding_wchar, mbfl_no_encoding_cp1252, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_wchar_cp1252, mbfl_filt_conv_common_flush, NULL, diff --git a/ext/mbstring/libmbfl/filters/mbfilter_cp1254.c b/ext/mbstring/libmbfl/filters/mbfilter_cp1254.c index 2c9050f275975..70846984f778c 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_cp1254.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_cp1254.c @@ -57,7 +57,7 @@ const struct mbfl_convert_vtbl vtbl_cp1254_wchar = { mbfl_no_encoding_cp1254, mbfl_no_encoding_wchar, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_cp1254_wchar, mbfl_filt_conv_common_flush, NULL, @@ -67,7 +67,7 @@ const struct mbfl_convert_vtbl vtbl_wchar_cp1254 = { mbfl_no_encoding_wchar, mbfl_no_encoding_cp1254, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_wchar_cp1254, mbfl_filt_conv_common_flush, NULL, diff --git a/ext/mbstring/libmbfl/filters/mbfilter_cp5022x.c b/ext/mbstring/libmbfl/filters/mbfilter_cp5022x.c index a20115416999d..61a862f94b62f 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_cp5022x.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_cp5022x.c @@ -138,7 +138,7 @@ const struct mbfl_convert_vtbl vtbl_jis_ms_wchar = { mbfl_no_encoding_jis_ms, mbfl_no_encoding_wchar, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_jis_ms_wchar, mbfl_filt_conv_common_flush, NULL, @@ -148,7 +148,7 @@ const struct mbfl_convert_vtbl vtbl_wchar_jis_ms = { mbfl_no_encoding_wchar, mbfl_no_encoding_jis_ms, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_wchar_jis_ms, mbfl_filt_conv_any_jis_flush, NULL, @@ -158,7 +158,7 @@ const struct mbfl_convert_vtbl vtbl_cp50220_wchar = { mbfl_no_encoding_cp50220, mbfl_no_encoding_wchar, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_jis_ms_wchar, mbfl_filt_conv_common_flush, NULL, @@ -178,7 +178,7 @@ const struct mbfl_convert_vtbl vtbl_cp50220raw_wchar = { mbfl_no_encoding_cp50220raw, mbfl_no_encoding_wchar, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_jis_ms_wchar, mbfl_filt_conv_common_flush, NULL, @@ -198,7 +198,7 @@ const struct mbfl_convert_vtbl vtbl_cp50221_wchar = { mbfl_no_encoding_cp50221, mbfl_no_encoding_wchar, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_jis_ms_wchar, mbfl_filt_conv_common_flush, NULL, @@ -208,7 +208,7 @@ const struct mbfl_convert_vtbl vtbl_wchar_cp50221 = { mbfl_no_encoding_wchar, mbfl_no_encoding_cp50221, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_wchar_cp50221, mbfl_filt_conv_any_jis_flush, NULL, @@ -218,7 +218,7 @@ const struct mbfl_convert_vtbl vtbl_cp50222_wchar = { mbfl_no_encoding_cp50222, mbfl_no_encoding_wchar, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_jis_ms_wchar, mbfl_filt_conv_common_flush, NULL, @@ -228,7 +228,7 @@ const struct mbfl_convert_vtbl vtbl_wchar_cp50222 = { mbfl_no_encoding_wchar, mbfl_no_encoding_cp50222, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_wchar_cp50222, mbfl_filt_conv_wchar_cp50222_flush, NULL, @@ -612,13 +612,9 @@ mbfl_filt_conv_wchar_cp50220_copy(mbfl_convert_filter *src, mbfl_convert_filter static void mbfl_filt_conv_wchar_cp50220_dtor(mbfl_convert_filter *filt) { - vtbl_tl_jisx0201_jisx0208.filter_dtor(filt); - if (filt->opaque != NULL) { efree(filt->opaque); } - - mbfl_filt_conv_common_dtor(filt); } /* diff --git a/ext/mbstring/libmbfl/filters/mbfilter_cp51932.c b/ext/mbstring/libmbfl/filters/mbfilter_cp51932.c index f6f28faf12ac5..e3d96da8b88ab 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_cp51932.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_cp51932.c @@ -80,7 +80,7 @@ const struct mbfl_convert_vtbl vtbl_cp51932_wchar = { mbfl_no_encoding_cp51932, mbfl_no_encoding_wchar, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_cp51932_wchar, mbfl_filt_conv_common_flush, NULL, @@ -90,7 +90,7 @@ const struct mbfl_convert_vtbl vtbl_wchar_cp51932 = { mbfl_no_encoding_wchar, mbfl_no_encoding_cp51932, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_wchar_cp51932, mbfl_filt_conv_common_flush, NULL, diff --git a/ext/mbstring/libmbfl/filters/mbfilter_cp850.c b/ext/mbstring/libmbfl/filters/mbfilter_cp850.c index 93d4427b94dae..e8833ad87b49e 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_cp850.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_cp850.c @@ -53,7 +53,7 @@ const struct mbfl_convert_vtbl vtbl_wchar_cp850 = { mbfl_no_encoding_wchar, mbfl_no_encoding_cp850, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_wchar_cp850, mbfl_filt_conv_common_flush, NULL, @@ -63,7 +63,7 @@ const struct mbfl_convert_vtbl vtbl_cp850_wchar = { mbfl_no_encoding_cp850, mbfl_no_encoding_wchar, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_cp850_wchar, mbfl_filt_conv_common_flush, NULL, diff --git a/ext/mbstring/libmbfl/filters/mbfilter_cp866.c b/ext/mbstring/libmbfl/filters/mbfilter_cp866.c index 1632f893dea9f..14c49ff790386 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_cp866.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_cp866.c @@ -57,7 +57,7 @@ const struct mbfl_convert_vtbl vtbl_wchar_cp866 = { mbfl_no_encoding_wchar, mbfl_no_encoding_cp866, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_wchar_cp866, mbfl_filt_conv_common_flush, NULL, @@ -67,7 +67,7 @@ const struct mbfl_convert_vtbl vtbl_cp866_wchar = { mbfl_no_encoding_cp866, mbfl_no_encoding_wchar, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_cp866_wchar, mbfl_filt_conv_common_flush, NULL, diff --git a/ext/mbstring/libmbfl/filters/mbfilter_cp932.c b/ext/mbstring/libmbfl/filters/mbfilter_cp932.c index 19f6481d5cda1..b2ec5a99685b3 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_cp932.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_cp932.c @@ -78,7 +78,7 @@ const struct mbfl_convert_vtbl vtbl_cp932_wchar = { mbfl_no_encoding_cp932, mbfl_no_encoding_wchar, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_cp932_wchar, mbfl_filt_conv_common_flush, NULL, @@ -88,7 +88,7 @@ const struct mbfl_convert_vtbl vtbl_wchar_cp932 = { mbfl_no_encoding_wchar, mbfl_no_encoding_cp932, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_wchar_cp932, mbfl_filt_conv_common_flush, NULL, diff --git a/ext/mbstring/libmbfl/filters/mbfilter_cp936.c b/ext/mbstring/libmbfl/filters/mbfilter_cp936.c index 8b36058b2cc4c..5baa0dabbcbaa 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_cp936.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_cp936.c @@ -77,7 +77,7 @@ const struct mbfl_convert_vtbl vtbl_cp936_wchar = { mbfl_no_encoding_cp936, mbfl_no_encoding_wchar, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_cp936_wchar, mbfl_filt_conv_common_flush, NULL, @@ -87,7 +87,7 @@ const struct mbfl_convert_vtbl vtbl_wchar_cp936 = { mbfl_no_encoding_wchar, mbfl_no_encoding_cp936, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_wchar_cp936, mbfl_filt_conv_common_flush, NULL, diff --git a/ext/mbstring/libmbfl/filters/mbfilter_euc_cn.c b/ext/mbstring/libmbfl/filters/mbfilter_euc_cn.c index bff3bf9d0eb66..7a8431219e42c 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_euc_cn.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_euc_cn.c @@ -77,7 +77,7 @@ const struct mbfl_convert_vtbl vtbl_euccn_wchar = { mbfl_no_encoding_euc_cn, mbfl_no_encoding_wchar, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_euccn_wchar, mbfl_filt_conv_common_flush, NULL, @@ -87,7 +87,7 @@ const struct mbfl_convert_vtbl vtbl_wchar_euccn = { mbfl_no_encoding_wchar, mbfl_no_encoding_euc_cn, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_wchar_euccn, mbfl_filt_conv_common_flush, NULL, diff --git a/ext/mbstring/libmbfl/filters/mbfilter_euc_jp.c b/ext/mbstring/libmbfl/filters/mbfilter_euc_jp.c index 0802ab7b7d50b..ac12b3ed948b4 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_euc_jp.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_euc_jp.c @@ -78,7 +78,7 @@ const struct mbfl_convert_vtbl vtbl_eucjp_wchar = { mbfl_no_encoding_euc_jp, mbfl_no_encoding_wchar, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_eucjp_wchar, mbfl_filt_conv_common_flush, NULL, @@ -88,7 +88,7 @@ const struct mbfl_convert_vtbl vtbl_wchar_eucjp = { mbfl_no_encoding_wchar, mbfl_no_encoding_euc_jp, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_wchar_eucjp, mbfl_filt_conv_common_flush, NULL, diff --git a/ext/mbstring/libmbfl/filters/mbfilter_euc_jp_2004.c b/ext/mbstring/libmbfl/filters/mbfilter_euc_jp_2004.c index 4cced6adcf248..8efb49eff71f5 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_euc_jp_2004.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_euc_jp_2004.c @@ -58,7 +58,7 @@ const struct mbfl_convert_vtbl vtbl_eucjp2004_wchar = { mbfl_no_encoding_eucjp2004, mbfl_no_encoding_wchar, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_jis2004_wchar, mbfl_filt_conv_common_flush, NULL, @@ -68,7 +68,7 @@ const struct mbfl_convert_vtbl vtbl_wchar_eucjp2004 = { mbfl_no_encoding_wchar, mbfl_no_encoding_eucjp2004, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_wchar_jis2004, mbfl_filt_conv_jis2004_flush, NULL, diff --git a/ext/mbstring/libmbfl/filters/mbfilter_euc_jp_win.c b/ext/mbstring/libmbfl/filters/mbfilter_euc_jp_win.c index c224bfe59d22e..7845fa2d1aa4a 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_euc_jp_win.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_euc_jp_win.c @@ -81,7 +81,7 @@ const struct mbfl_convert_vtbl vtbl_eucjpwin_wchar = { mbfl_no_encoding_eucjp_win, mbfl_no_encoding_wchar, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_eucjpwin_wchar, mbfl_filt_conv_common_flush, NULL, @@ -91,7 +91,7 @@ const struct mbfl_convert_vtbl vtbl_wchar_eucjpwin = { mbfl_no_encoding_wchar, mbfl_no_encoding_eucjp_win, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_wchar_eucjpwin, mbfl_filt_conv_common_flush, NULL, diff --git a/ext/mbstring/libmbfl/filters/mbfilter_euc_kr.c b/ext/mbstring/libmbfl/filters/mbfilter_euc_kr.c index d8c46345ed477..fef81b693be19 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_euc_kr.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_euc_kr.c @@ -76,7 +76,7 @@ const struct mbfl_convert_vtbl vtbl_euckr_wchar = { mbfl_no_encoding_euc_kr, mbfl_no_encoding_wchar, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_euckr_wchar, mbfl_filt_conv_common_flush, NULL, @@ -86,7 +86,7 @@ const struct mbfl_convert_vtbl vtbl_wchar_euckr = { mbfl_no_encoding_wchar, mbfl_no_encoding_euc_kr, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_wchar_euckr, mbfl_filt_conv_common_flush, NULL, diff --git a/ext/mbstring/libmbfl/filters/mbfilter_euc_tw.c b/ext/mbstring/libmbfl/filters/mbfilter_euc_tw.c index e1df5cf0437c9..fe908c4ffb1bc 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_euc_tw.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_euc_tw.c @@ -78,7 +78,7 @@ const struct mbfl_convert_vtbl vtbl_euctw_wchar = { mbfl_no_encoding_euc_tw, mbfl_no_encoding_wchar, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_euctw_wchar, mbfl_filt_conv_common_flush, NULL, @@ -88,7 +88,7 @@ const struct mbfl_convert_vtbl vtbl_wchar_euctw = { mbfl_no_encoding_wchar, mbfl_no_encoding_euc_tw, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_wchar_euctw, mbfl_filt_conv_common_flush, NULL, diff --git a/ext/mbstring/libmbfl/filters/mbfilter_gb18030.c b/ext/mbstring/libmbfl/filters/mbfilter_gb18030.c index 7e3900a1cf504..1bda813bb9aad 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_gb18030.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_gb18030.c @@ -59,7 +59,7 @@ const struct mbfl_convert_vtbl vtbl_gb18030_wchar = { mbfl_no_encoding_gb18030, mbfl_no_encoding_wchar, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_gb18030_wchar, mbfl_filt_conv_common_flush, NULL, @@ -69,7 +69,7 @@ const struct mbfl_convert_vtbl vtbl_wchar_gb18030 = { mbfl_no_encoding_wchar, mbfl_no_encoding_gb18030, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_wchar_gb18030, mbfl_filt_conv_common_flush, NULL, diff --git a/ext/mbstring/libmbfl/filters/mbfilter_htmlent.c b/ext/mbstring/libmbfl/filters/mbfilter_htmlent.c index f61ac6f5a88eb..7176fd4717ade 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_htmlent.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_htmlent.c @@ -68,7 +68,7 @@ const struct mbfl_convert_vtbl vtbl_wchar_html = { mbfl_no_encoding_wchar, mbfl_no_encoding_html_ent, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_html_enc, mbfl_filt_conv_html_enc_flush, NULL, diff --git a/ext/mbstring/libmbfl/filters/mbfilter_htmlent.h b/ext/mbstring/libmbfl/filters/mbfilter_htmlent.h index 979f6011ea033..b61207da262d4 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_htmlent.h +++ b/ext/mbstring/libmbfl/filters/mbfilter_htmlent.h @@ -43,7 +43,5 @@ int mbfl_filt_conv_html_enc_flush(mbfl_convert_filter *filter); int mbfl_filt_conv_html_dec(int c, mbfl_convert_filter *filter); int mbfl_filt_conv_html_dec_flush(mbfl_convert_filter *filter); void mbfl_filt_conv_html_dec_copy(mbfl_convert_filter *src, mbfl_convert_filter *dest); -void mbfl_filt_conv_html_dec_ctor(mbfl_convert_filter *filter); -void mbfl_filt_conv_html_dec_dtor(mbfl_convert_filter *filter); #endif /* MBFL_MBFILTER_HTMLENT_H */ diff --git a/ext/mbstring/libmbfl/filters/mbfilter_hz.c b/ext/mbstring/libmbfl/filters/mbfilter_hz.c index 93de2bffebe66..1d95613b7455f 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_hz.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_hz.c @@ -56,7 +56,7 @@ const struct mbfl_convert_vtbl vtbl_hz_wchar = { mbfl_no_encoding_hz, mbfl_no_encoding_wchar, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_hz_wchar, mbfl_filt_conv_common_flush, NULL, @@ -66,7 +66,7 @@ const struct mbfl_convert_vtbl vtbl_wchar_hz = { mbfl_no_encoding_wchar, mbfl_no_encoding_hz, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_wchar_hz, mbfl_filt_conv_any_hz_flush, NULL, diff --git a/ext/mbstring/libmbfl/filters/mbfilter_iso2022_jp_ms.c b/ext/mbstring/libmbfl/filters/mbfilter_iso2022_jp_ms.c index 69c95d57f3b7b..9183e1e2a3491 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_iso2022_jp_ms.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_iso2022_jp_ms.c @@ -60,7 +60,7 @@ const struct mbfl_convert_vtbl vtbl_2022jpms_wchar = { mbfl_no_encoding_2022jpms, mbfl_no_encoding_wchar, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_2022jpms_wchar, mbfl_filt_conv_common_flush, NULL, @@ -70,7 +70,7 @@ const struct mbfl_convert_vtbl vtbl_wchar_2022jpms = { mbfl_no_encoding_wchar, mbfl_no_encoding_2022jpms, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_wchar_2022jpms, mbfl_filt_conv_any_2022jpms_flush, NULL, diff --git a/ext/mbstring/libmbfl/filters/mbfilter_iso2022_kr.c b/ext/mbstring/libmbfl/filters/mbfilter_iso2022_kr.c index 1ed8940e75345..8d8f9171867dc 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_iso2022_kr.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_iso2022_kr.c @@ -55,7 +55,7 @@ const struct mbfl_convert_vtbl vtbl_wchar_2022kr = { mbfl_no_encoding_wchar, mbfl_no_encoding_2022kr, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_wchar_2022kr, mbfl_filt_conv_any_2022kr_flush, NULL, @@ -65,7 +65,7 @@ const struct mbfl_convert_vtbl vtbl_2022kr_wchar = { mbfl_no_encoding_2022kr, mbfl_no_encoding_wchar, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_2022kr_wchar, mbfl_filt_conv_common_flush, NULL, diff --git a/ext/mbstring/libmbfl/filters/mbfilter_iso2022jp_2004.c b/ext/mbstring/libmbfl/filters/mbfilter_iso2022jp_2004.c index 85520c2af89c0..7b9a663e12293 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_iso2022jp_2004.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_iso2022jp_2004.c @@ -58,7 +58,7 @@ const struct mbfl_convert_vtbl vtbl_2022jp_2004_wchar = { mbfl_no_encoding_2022jp_2004, mbfl_no_encoding_wchar, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_jis2004_wchar, mbfl_filt_conv_common_flush, NULL, @@ -68,7 +68,7 @@ const struct mbfl_convert_vtbl vtbl_wchar_2022jp_2004 = { mbfl_no_encoding_wchar, mbfl_no_encoding_2022jp_2004, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_wchar_jis2004, mbfl_filt_conv_jis2004_flush, NULL, diff --git a/ext/mbstring/libmbfl/filters/mbfilter_iso2022jp_mobile.c b/ext/mbstring/libmbfl/filters/mbfilter_iso2022jp_mobile.c index 2fe7379d01cff..0d4795942adde 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_iso2022jp_mobile.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_iso2022jp_mobile.c @@ -62,7 +62,7 @@ const struct mbfl_convert_vtbl vtbl_2022jp_kddi_wchar = { mbfl_no_encoding_2022jp_kddi, mbfl_no_encoding_wchar, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_2022jp_mobile_wchar, mbfl_filt_conv_common_flush, NULL, @@ -72,7 +72,7 @@ const struct mbfl_convert_vtbl vtbl_wchar_2022jp_kddi = { mbfl_no_encoding_wchar, mbfl_no_encoding_2022jp_kddi, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_wchar_2022jp_mobile, mbfl_filt_conv_any_jis_flush, NULL, diff --git a/ext/mbstring/libmbfl/filters/mbfilter_iso8859_1.c b/ext/mbstring/libmbfl/filters/mbfilter_iso8859_1.c index ad876d53dfcd6..ce94528f4a363 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_iso8859_1.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_iso8859_1.c @@ -54,7 +54,7 @@ const struct mbfl_convert_vtbl vtbl_8859_1_wchar = { mbfl_no_encoding_8859_1, mbfl_no_encoding_wchar, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_8859_1_wchar, mbfl_filt_conv_common_flush, NULL, @@ -64,7 +64,7 @@ const struct mbfl_convert_vtbl vtbl_wchar_8859_1 = { mbfl_no_encoding_wchar, mbfl_no_encoding_8859_1, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_wchar_8859_1, mbfl_filt_conv_common_flush, NULL, diff --git a/ext/mbstring/libmbfl/filters/mbfilter_iso8859_10.c b/ext/mbstring/libmbfl/filters/mbfilter_iso8859_10.c index 49599d43f5b76..cee8d60a8fa4e 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_iso8859_10.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_iso8859_10.c @@ -55,7 +55,7 @@ const struct mbfl_convert_vtbl vtbl_8859_10_wchar = { mbfl_no_encoding_8859_10, mbfl_no_encoding_wchar, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_8859_10_wchar, mbfl_filt_conv_common_flush, NULL, @@ -65,7 +65,7 @@ const struct mbfl_convert_vtbl vtbl_wchar_8859_10 = { mbfl_no_encoding_wchar, mbfl_no_encoding_8859_10, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_wchar_8859_10, mbfl_filt_conv_common_flush, NULL, diff --git a/ext/mbstring/libmbfl/filters/mbfilter_iso8859_13.c b/ext/mbstring/libmbfl/filters/mbfilter_iso8859_13.c index 7a3193b66c179..daaf7bec50f3f 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_iso8859_13.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_iso8859_13.c @@ -55,7 +55,7 @@ const struct mbfl_convert_vtbl vtbl_8859_13_wchar = { mbfl_no_encoding_8859_13, mbfl_no_encoding_wchar, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_8859_13_wchar, mbfl_filt_conv_common_flush, NULL, @@ -65,7 +65,7 @@ const struct mbfl_convert_vtbl vtbl_wchar_8859_13 = { mbfl_no_encoding_wchar, mbfl_no_encoding_8859_13, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_wchar_8859_13, mbfl_filt_conv_common_flush, NULL, diff --git a/ext/mbstring/libmbfl/filters/mbfilter_iso8859_14.c b/ext/mbstring/libmbfl/filters/mbfilter_iso8859_14.c index 62ea49ca2f4ff..edc5c72c85e00 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_iso8859_14.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_iso8859_14.c @@ -55,7 +55,7 @@ const struct mbfl_convert_vtbl vtbl_8859_14_wchar = { mbfl_no_encoding_8859_14, mbfl_no_encoding_wchar, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_8859_14_wchar, mbfl_filt_conv_common_flush, NULL, @@ -65,7 +65,7 @@ const struct mbfl_convert_vtbl vtbl_wchar_8859_14 = { mbfl_no_encoding_wchar, mbfl_no_encoding_8859_14, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_wchar_8859_14, mbfl_filt_conv_common_flush, NULL, diff --git a/ext/mbstring/libmbfl/filters/mbfilter_iso8859_15.c b/ext/mbstring/libmbfl/filters/mbfilter_iso8859_15.c index 702c260c3d0fe..38b77fc0775b4 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_iso8859_15.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_iso8859_15.c @@ -55,7 +55,7 @@ const struct mbfl_convert_vtbl vtbl_8859_15_wchar = { mbfl_no_encoding_8859_15, mbfl_no_encoding_wchar, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_8859_15_wchar, mbfl_filt_conv_common_flush, NULL, @@ -65,7 +65,7 @@ const struct mbfl_convert_vtbl vtbl_wchar_8859_15 = { mbfl_no_encoding_wchar, mbfl_no_encoding_8859_15, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_wchar_8859_15, mbfl_filt_conv_common_flush, NULL, diff --git a/ext/mbstring/libmbfl/filters/mbfilter_iso8859_16.c b/ext/mbstring/libmbfl/filters/mbfilter_iso8859_16.c index f63df4a32494f..355c3004669a2 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_iso8859_16.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_iso8859_16.c @@ -55,7 +55,7 @@ const struct mbfl_convert_vtbl vtbl_8859_16_wchar = { mbfl_no_encoding_8859_16, mbfl_no_encoding_wchar, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_8859_16_wchar, mbfl_filt_conv_common_flush, NULL, @@ -65,7 +65,7 @@ const struct mbfl_convert_vtbl vtbl_wchar_8859_16 = { mbfl_no_encoding_wchar, mbfl_no_encoding_8859_16, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_wchar_8859_16, mbfl_filt_conv_common_flush, NULL, diff --git a/ext/mbstring/libmbfl/filters/mbfilter_iso8859_2.c b/ext/mbstring/libmbfl/filters/mbfilter_iso8859_2.c index 4488ec49b9073..279ee694fcc52 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_iso8859_2.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_iso8859_2.c @@ -55,7 +55,7 @@ const struct mbfl_convert_vtbl vtbl_8859_2_wchar = { mbfl_no_encoding_8859_2, mbfl_no_encoding_wchar, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_8859_2_wchar, mbfl_filt_conv_common_flush, NULL, @@ -65,7 +65,7 @@ const struct mbfl_convert_vtbl vtbl_wchar_8859_2 = { mbfl_no_encoding_wchar, mbfl_no_encoding_8859_2, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_wchar_8859_2, mbfl_filt_conv_common_flush, NULL, diff --git a/ext/mbstring/libmbfl/filters/mbfilter_iso8859_3.c b/ext/mbstring/libmbfl/filters/mbfilter_iso8859_3.c index 0f19aff8fced3..853a7e202fd56 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_iso8859_3.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_iso8859_3.c @@ -55,7 +55,7 @@ const struct mbfl_convert_vtbl vtbl_8859_3_wchar = { mbfl_no_encoding_8859_3, mbfl_no_encoding_wchar, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_8859_3_wchar, mbfl_filt_conv_common_flush, NULL, @@ -65,7 +65,7 @@ const struct mbfl_convert_vtbl vtbl_wchar_8859_3 = { mbfl_no_encoding_wchar, mbfl_no_encoding_8859_3, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_wchar_8859_3, mbfl_filt_conv_common_flush, NULL, diff --git a/ext/mbstring/libmbfl/filters/mbfilter_iso8859_4.c b/ext/mbstring/libmbfl/filters/mbfilter_iso8859_4.c index 42b19152add10..264c0eae98fc1 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_iso8859_4.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_iso8859_4.c @@ -54,7 +54,7 @@ const struct mbfl_convert_vtbl vtbl_8859_4_wchar = { mbfl_no_encoding_8859_4, mbfl_no_encoding_wchar, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_8859_4_wchar, mbfl_filt_conv_common_flush, NULL, @@ -64,7 +64,7 @@ const struct mbfl_convert_vtbl vtbl_wchar_8859_4 = { mbfl_no_encoding_wchar, mbfl_no_encoding_8859_4, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_wchar_8859_4, mbfl_filt_conv_common_flush, NULL, diff --git a/ext/mbstring/libmbfl/filters/mbfilter_iso8859_5.c b/ext/mbstring/libmbfl/filters/mbfilter_iso8859_5.c index d7674ab28130d..f17da31260b69 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_iso8859_5.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_iso8859_5.c @@ -55,7 +55,7 @@ const struct mbfl_convert_vtbl vtbl_8859_5_wchar = { mbfl_no_encoding_8859_5, mbfl_no_encoding_wchar, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_8859_5_wchar, mbfl_filt_conv_common_flush, NULL, @@ -65,7 +65,7 @@ const struct mbfl_convert_vtbl vtbl_wchar_8859_5 = { mbfl_no_encoding_wchar, mbfl_no_encoding_8859_5, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_wchar_8859_5, mbfl_filt_conv_common_flush, NULL, diff --git a/ext/mbstring/libmbfl/filters/mbfilter_iso8859_6.c b/ext/mbstring/libmbfl/filters/mbfilter_iso8859_6.c index 9c44928685c2e..d184a71495a64 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_iso8859_6.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_iso8859_6.c @@ -55,7 +55,7 @@ const struct mbfl_convert_vtbl vtbl_8859_6_wchar = { mbfl_no_encoding_8859_6, mbfl_no_encoding_wchar, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_8859_6_wchar, mbfl_filt_conv_common_flush, NULL, @@ -65,7 +65,7 @@ const struct mbfl_convert_vtbl vtbl_wchar_8859_6 = { mbfl_no_encoding_wchar, mbfl_no_encoding_8859_6, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_wchar_8859_6, mbfl_filt_conv_common_flush, NULL, diff --git a/ext/mbstring/libmbfl/filters/mbfilter_iso8859_7.c b/ext/mbstring/libmbfl/filters/mbfilter_iso8859_7.c index 6d475c9ccff8b..029fed07294d9 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_iso8859_7.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_iso8859_7.c @@ -55,7 +55,7 @@ const struct mbfl_convert_vtbl vtbl_8859_7_wchar = { mbfl_no_encoding_8859_7, mbfl_no_encoding_wchar, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_8859_7_wchar, mbfl_filt_conv_common_flush, NULL, @@ -65,7 +65,7 @@ const struct mbfl_convert_vtbl vtbl_wchar_8859_7 = { mbfl_no_encoding_wchar, mbfl_no_encoding_8859_7, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_wchar_8859_7, mbfl_filt_conv_common_flush, NULL, diff --git a/ext/mbstring/libmbfl/filters/mbfilter_iso8859_8.c b/ext/mbstring/libmbfl/filters/mbfilter_iso8859_8.c index 0fe7fbe761f6d..16bc6e4f6ecc4 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_iso8859_8.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_iso8859_8.c @@ -55,7 +55,7 @@ const struct mbfl_convert_vtbl vtbl_8859_8_wchar = { mbfl_no_encoding_8859_8, mbfl_no_encoding_wchar, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_8859_8_wchar, mbfl_filt_conv_common_flush, NULL, @@ -65,7 +65,7 @@ const struct mbfl_convert_vtbl vtbl_wchar_8859_8 = { mbfl_no_encoding_wchar, mbfl_no_encoding_8859_8, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_wchar_8859_8, mbfl_filt_conv_common_flush, NULL, diff --git a/ext/mbstring/libmbfl/filters/mbfilter_iso8859_9.c b/ext/mbstring/libmbfl/filters/mbfilter_iso8859_9.c index 7493e1519c7a2..2d45c1b91c426 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_iso8859_9.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_iso8859_9.c @@ -55,7 +55,7 @@ const struct mbfl_convert_vtbl vtbl_8859_9_wchar = { mbfl_no_encoding_8859_9, mbfl_no_encoding_wchar, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_8859_9_wchar, mbfl_filt_conv_common_flush, NULL, @@ -65,7 +65,7 @@ const struct mbfl_convert_vtbl vtbl_wchar_8859_9 = { mbfl_no_encoding_wchar, mbfl_no_encoding_8859_9, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_wchar_8859_9, mbfl_filt_conv_common_flush, NULL, diff --git a/ext/mbstring/libmbfl/filters/mbfilter_jis.c b/ext/mbstring/libmbfl/filters/mbfilter_jis.c index 84656e64daa7a..91ed552bcde89 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_jis.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_jis.c @@ -76,7 +76,7 @@ const struct mbfl_convert_vtbl vtbl_jis_wchar = { mbfl_no_encoding_jis, mbfl_no_encoding_wchar, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_jis_wchar, mbfl_filt_conv_common_flush, NULL, @@ -86,7 +86,7 @@ const struct mbfl_convert_vtbl vtbl_wchar_jis = { mbfl_no_encoding_wchar, mbfl_no_encoding_jis, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_wchar_jis, mbfl_filt_conv_any_jis_flush, NULL, @@ -96,7 +96,7 @@ const struct mbfl_convert_vtbl vtbl_2022jp_wchar = { mbfl_no_encoding_2022jp, mbfl_no_encoding_wchar, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_jis_wchar, mbfl_filt_conv_common_flush, NULL, @@ -106,7 +106,7 @@ const struct mbfl_convert_vtbl vtbl_wchar_2022jp = { mbfl_no_encoding_wchar, mbfl_no_encoding_2022jp, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_wchar_2022jp, mbfl_filt_conv_any_jis_flush, NULL, diff --git a/ext/mbstring/libmbfl/filters/mbfilter_koi8r.c b/ext/mbstring/libmbfl/filters/mbfilter_koi8r.c index a0eb7dd08fe12..850437710ccf8 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_koi8r.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_koi8r.c @@ -57,7 +57,7 @@ const struct mbfl_convert_vtbl vtbl_wchar_koi8r = { mbfl_no_encoding_wchar, mbfl_no_encoding_koi8r, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_wchar_koi8r, mbfl_filt_conv_common_flush, NULL, @@ -67,7 +67,7 @@ const struct mbfl_convert_vtbl vtbl_koi8r_wchar = { mbfl_no_encoding_koi8r, mbfl_no_encoding_wchar, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_koi8r_wchar, mbfl_filt_conv_common_flush, NULL, diff --git a/ext/mbstring/libmbfl/filters/mbfilter_koi8u.c b/ext/mbstring/libmbfl/filters/mbfilter_koi8u.c index 0d75a43f82c7c..fe495336cb1eb 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_koi8u.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_koi8u.c @@ -54,7 +54,7 @@ const struct mbfl_convert_vtbl vtbl_wchar_koi8u = { mbfl_no_encoding_wchar, mbfl_no_encoding_koi8u, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_wchar_koi8u, mbfl_filt_conv_common_flush, NULL, @@ -64,7 +64,7 @@ const struct mbfl_convert_vtbl vtbl_koi8u_wchar = { mbfl_no_encoding_koi8u, mbfl_no_encoding_wchar, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_koi8u_wchar, mbfl_filt_conv_common_flush, NULL, diff --git a/ext/mbstring/libmbfl/filters/mbfilter_qprint.c b/ext/mbstring/libmbfl/filters/mbfilter_qprint.c index b03e4921d91f7..d42cdca883ea0 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_qprint.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_qprint.c @@ -48,7 +48,7 @@ const struct mbfl_convert_vtbl vtbl_8bit_qprint = { mbfl_no_encoding_8bit, mbfl_no_encoding_qprint, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_qprintenc, mbfl_filt_conv_qprintenc_flush, NULL, @@ -58,7 +58,7 @@ const struct mbfl_convert_vtbl vtbl_qprint_8bit = { mbfl_no_encoding_qprint, mbfl_no_encoding_8bit, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_qprintdec, mbfl_filt_conv_qprintdec_flush, NULL, diff --git a/ext/mbstring/libmbfl/filters/mbfilter_sjis.c b/ext/mbstring/libmbfl/filters/mbfilter_sjis.c index 0fd98a167dbf3..c6e83913dacfe 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_sjis.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_sjis.c @@ -81,7 +81,7 @@ const struct mbfl_convert_vtbl vtbl_sjis_wchar = { mbfl_no_encoding_sjis, mbfl_no_encoding_wchar, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_sjis_wchar, mbfl_filt_conv_common_flush, NULL, @@ -91,7 +91,7 @@ const struct mbfl_convert_vtbl vtbl_wchar_sjis = { mbfl_no_encoding_wchar, mbfl_no_encoding_sjis, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_wchar_sjis, mbfl_filt_conv_common_flush, NULL, diff --git a/ext/mbstring/libmbfl/filters/mbfilter_sjis_2004.c b/ext/mbstring/libmbfl/filters/mbfilter_sjis_2004.c index 43656e144695e..93324a4ae730e 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_sjis_2004.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_sjis_2004.c @@ -63,7 +63,7 @@ const struct mbfl_convert_vtbl vtbl_sjis2004_wchar = { mbfl_no_encoding_sjis2004, mbfl_no_encoding_wchar, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_jis2004_wchar, mbfl_filt_conv_common_flush, NULL, @@ -73,7 +73,7 @@ const struct mbfl_convert_vtbl vtbl_wchar_sjis2004 = { mbfl_no_encoding_wchar, mbfl_no_encoding_sjis2004, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_wchar_jis2004, mbfl_filt_conv_jis2004_flush, NULL, diff --git a/ext/mbstring/libmbfl/filters/mbfilter_sjis_mac.c b/ext/mbstring/libmbfl/filters/mbfilter_sjis_mac.c index af21db07ba83f..196ec0a59d0a6 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_sjis_mac.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_sjis_mac.c @@ -64,7 +64,7 @@ const struct mbfl_convert_vtbl vtbl_sjis_mac_wchar = { mbfl_no_encoding_sjis_mac, mbfl_no_encoding_wchar, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_sjis_mac_wchar, mbfl_filt_conv_common_flush, NULL, @@ -74,7 +74,7 @@ const struct mbfl_convert_vtbl vtbl_wchar_sjis_mac = { mbfl_no_encoding_wchar, mbfl_no_encoding_sjis_mac, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_wchar_sjis_mac, mbfl_filt_conv_sjis_mac_flush, NULL, diff --git a/ext/mbstring/libmbfl/filters/mbfilter_sjis_mobile.c b/ext/mbstring/libmbfl/filters/mbfilter_sjis_mobile.c index 28de982e8698f..ca84faae4782a 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_sjis_mobile.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_sjis_mobile.c @@ -101,7 +101,7 @@ const struct mbfl_convert_vtbl vtbl_sjis_docomo_wchar = { mbfl_no_encoding_sjis_docomo, mbfl_no_encoding_wchar, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_sjis_mobile_wchar, mbfl_filt_conv_common_flush, NULL, @@ -111,7 +111,7 @@ const struct mbfl_convert_vtbl vtbl_wchar_sjis_docomo = { mbfl_no_encoding_wchar, mbfl_no_encoding_sjis_docomo, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_wchar_sjis_mobile, mbfl_filt_conv_sjis_mobile_flush, NULL, @@ -121,7 +121,7 @@ const struct mbfl_convert_vtbl vtbl_sjis_kddi_wchar = { mbfl_no_encoding_sjis_kddi, mbfl_no_encoding_wchar, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_sjis_mobile_wchar, mbfl_filt_conv_common_flush, NULL, @@ -131,7 +131,7 @@ const struct mbfl_convert_vtbl vtbl_wchar_sjis_kddi = { mbfl_no_encoding_wchar, mbfl_no_encoding_sjis_kddi, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_wchar_sjis_mobile, mbfl_filt_conv_sjis_mobile_flush, NULL, @@ -141,7 +141,7 @@ const struct mbfl_convert_vtbl vtbl_sjis_sb_wchar = { mbfl_no_encoding_sjis_sb, mbfl_no_encoding_wchar, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_sjis_mobile_wchar, mbfl_filt_conv_common_flush, NULL, @@ -151,7 +151,7 @@ const struct mbfl_convert_vtbl vtbl_wchar_sjis_sb = { mbfl_no_encoding_wchar, mbfl_no_encoding_sjis_sb, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_wchar_sjis_mobile, mbfl_filt_conv_sjis_mobile_flush, NULL, diff --git a/ext/mbstring/libmbfl/filters/mbfilter_sjis_open.c b/ext/mbstring/libmbfl/filters/mbfilter_sjis_open.c index 70f33370e3458..f8adc5474ea27 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_sjis_open.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_sjis_open.c @@ -78,7 +78,7 @@ const struct mbfl_convert_vtbl vtbl_sjis_open_wchar = { mbfl_no_encoding_sjis_open, mbfl_no_encoding_wchar, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_sjis_open_wchar, mbfl_filt_conv_common_flush, NULL, @@ -88,7 +88,7 @@ const struct mbfl_convert_vtbl vtbl_wchar_sjis_open = { mbfl_no_encoding_wchar, mbfl_no_encoding_sjis_open, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_wchar_sjis_open, mbfl_filt_conv_common_flush, NULL, diff --git a/ext/mbstring/libmbfl/filters/mbfilter_tl_jisx0201_jisx0208.c b/ext/mbstring/libmbfl/filters/mbfilter_tl_jisx0201_jisx0208.c index 7424480a220c9..6831c2d2e7660 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_tl_jisx0201_jisx0208.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_tl_jisx0201_jisx0208.c @@ -31,11 +31,6 @@ mbfl_filt_tl_jisx0201_jisx0208_init(mbfl_convert_filter *filt) mbfl_filt_conv_common_ctor(filt); } -void -mbfl_filt_tl_jisx0201_jisx0208_cleanup(mbfl_convert_filter *filt) -{ -} - int mbfl_filt_tl_jisx0201_jisx0208(int c, mbfl_convert_filter *filt) { @@ -294,7 +289,7 @@ const struct mbfl_convert_vtbl vtbl_tl_jisx0201_jisx0208 = { mbfl_no_encoding_wchar, mbfl_no_encoding_wchar, mbfl_filt_tl_jisx0201_jisx0208_init, - mbfl_filt_tl_jisx0201_jisx0208_cleanup, + NULL, mbfl_filt_tl_jisx0201_jisx0208, mbfl_filt_tl_jisx0201_jisx0208_flush, NULL, diff --git a/ext/mbstring/libmbfl/filters/mbfilter_ucs2.c b/ext/mbstring/libmbfl/filters/mbfilter_ucs2.c index 02046b30e856c..68172efbe610c 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_ucs2.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_ucs2.c @@ -69,7 +69,7 @@ const struct mbfl_convert_vtbl vtbl_ucs2_wchar = { mbfl_no_encoding_ucs2, mbfl_no_encoding_wchar, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_ucs2_wchar, mbfl_filt_conv_common_flush, NULL, @@ -79,7 +79,7 @@ const struct mbfl_convert_vtbl vtbl_wchar_ucs2 = { mbfl_no_encoding_wchar, mbfl_no_encoding_ucs2, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_wchar_ucs2be, mbfl_filt_conv_common_flush, NULL, @@ -89,7 +89,7 @@ const struct mbfl_convert_vtbl vtbl_ucs2be_wchar = { mbfl_no_encoding_ucs2be, mbfl_no_encoding_wchar, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_ucs2be_wchar, mbfl_filt_conv_common_flush, NULL, @@ -99,7 +99,7 @@ const struct mbfl_convert_vtbl vtbl_wchar_ucs2be = { mbfl_no_encoding_wchar, mbfl_no_encoding_ucs2be, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_wchar_ucs2be, mbfl_filt_conv_common_flush, NULL, @@ -109,7 +109,7 @@ const struct mbfl_convert_vtbl vtbl_ucs2le_wchar = { mbfl_no_encoding_ucs2le, mbfl_no_encoding_wchar, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_ucs2le_wchar, mbfl_filt_conv_common_flush, NULL, @@ -119,7 +119,7 @@ const struct mbfl_convert_vtbl vtbl_wchar_ucs2le = { mbfl_no_encoding_wchar, mbfl_no_encoding_ucs2le, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_wchar_ucs2le, mbfl_filt_conv_common_flush, NULL, diff --git a/ext/mbstring/libmbfl/filters/mbfilter_ucs4.c b/ext/mbstring/libmbfl/filters/mbfilter_ucs4.c index 9ce1fc931be9b..fcdd20d6158d6 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_ucs4.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_ucs4.c @@ -69,7 +69,7 @@ const struct mbfl_convert_vtbl vtbl_ucs4_wchar = { mbfl_no_encoding_ucs4, mbfl_no_encoding_wchar, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_ucs4_wchar, mbfl_filt_conv_common_flush, NULL, @@ -79,7 +79,7 @@ const struct mbfl_convert_vtbl vtbl_wchar_ucs4 = { mbfl_no_encoding_wchar, mbfl_no_encoding_ucs4, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_wchar_ucs4be, mbfl_filt_conv_common_flush, NULL, @@ -89,7 +89,7 @@ const struct mbfl_convert_vtbl vtbl_ucs4be_wchar = { mbfl_no_encoding_ucs4be, mbfl_no_encoding_wchar, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_ucs4be_wchar, mbfl_filt_conv_common_flush, NULL, @@ -99,7 +99,7 @@ const struct mbfl_convert_vtbl vtbl_wchar_ucs4be = { mbfl_no_encoding_wchar, mbfl_no_encoding_ucs4be, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_wchar_ucs4be, mbfl_filt_conv_common_flush, NULL, @@ -109,7 +109,7 @@ const struct mbfl_convert_vtbl vtbl_ucs4le_wchar = { mbfl_no_encoding_ucs4le, mbfl_no_encoding_wchar, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_ucs4le_wchar, mbfl_filt_conv_common_flush, NULL, @@ -119,7 +119,7 @@ const struct mbfl_convert_vtbl vtbl_wchar_ucs4le = { mbfl_no_encoding_wchar, mbfl_no_encoding_ucs4le, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_wchar_ucs4le, mbfl_filt_conv_common_flush, NULL, diff --git a/ext/mbstring/libmbfl/filters/mbfilter_uhc.c b/ext/mbstring/libmbfl/filters/mbfilter_uhc.c index aa55395e9055f..403fc01081d13 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_uhc.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_uhc.c @@ -77,7 +77,7 @@ const struct mbfl_convert_vtbl vtbl_uhc_wchar = { mbfl_no_encoding_uhc, mbfl_no_encoding_wchar, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_uhc_wchar, mbfl_filt_conv_common_flush, NULL, @@ -87,7 +87,7 @@ const struct mbfl_convert_vtbl vtbl_wchar_uhc = { mbfl_no_encoding_wchar, mbfl_no_encoding_uhc, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_wchar_uhc, mbfl_filt_conv_common_flush, NULL, diff --git a/ext/mbstring/libmbfl/filters/mbfilter_utf16.c b/ext/mbstring/libmbfl/filters/mbfilter_utf16.c index 27e307c8e8dab..620e8a76f7c52 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_utf16.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_utf16.c @@ -69,7 +69,7 @@ const struct mbfl_convert_vtbl vtbl_utf16_wchar = { mbfl_no_encoding_utf16, mbfl_no_encoding_wchar, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_utf16_wchar, mbfl_filt_conv_common_flush, NULL, @@ -79,7 +79,7 @@ const struct mbfl_convert_vtbl vtbl_wchar_utf16 = { mbfl_no_encoding_wchar, mbfl_no_encoding_utf16, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_wchar_utf16be, mbfl_filt_conv_common_flush, NULL, @@ -89,7 +89,7 @@ const struct mbfl_convert_vtbl vtbl_utf16be_wchar = { mbfl_no_encoding_utf16be, mbfl_no_encoding_wchar, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_utf16be_wchar, mbfl_filt_conv_common_flush, NULL, @@ -99,7 +99,7 @@ const struct mbfl_convert_vtbl vtbl_wchar_utf16be = { mbfl_no_encoding_wchar, mbfl_no_encoding_utf16be, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_wchar_utf16be, mbfl_filt_conv_common_flush, NULL, @@ -109,7 +109,7 @@ const struct mbfl_convert_vtbl vtbl_utf16le_wchar = { mbfl_no_encoding_utf16le, mbfl_no_encoding_wchar, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_utf16le_wchar, mbfl_filt_conv_common_flush, NULL, @@ -119,7 +119,7 @@ const struct mbfl_convert_vtbl vtbl_wchar_utf16le = { mbfl_no_encoding_wchar, mbfl_no_encoding_utf16le, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_wchar_utf16le, mbfl_filt_conv_common_flush, NULL, diff --git a/ext/mbstring/libmbfl/filters/mbfilter_utf32.c b/ext/mbstring/libmbfl/filters/mbfilter_utf32.c index ac3c32b12c8d6..b936ab410241a 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_utf32.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_utf32.c @@ -69,7 +69,7 @@ const struct mbfl_convert_vtbl vtbl_utf32_wchar = { mbfl_no_encoding_utf32, mbfl_no_encoding_wchar, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_utf32_wchar, mbfl_filt_conv_common_flush, NULL, @@ -79,7 +79,7 @@ const struct mbfl_convert_vtbl vtbl_wchar_utf32 = { mbfl_no_encoding_wchar, mbfl_no_encoding_utf32, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_wchar_utf32be, mbfl_filt_conv_common_flush, NULL, @@ -89,7 +89,7 @@ const struct mbfl_convert_vtbl vtbl_utf32be_wchar = { mbfl_no_encoding_utf32be, mbfl_no_encoding_wchar, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_utf32be_wchar, mbfl_filt_conv_common_flush, NULL, @@ -99,7 +99,7 @@ const struct mbfl_convert_vtbl vtbl_wchar_utf32be = { mbfl_no_encoding_wchar, mbfl_no_encoding_utf32be, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_wchar_utf32be, mbfl_filt_conv_common_flush, NULL, @@ -109,7 +109,7 @@ const struct mbfl_convert_vtbl vtbl_utf32le_wchar = { mbfl_no_encoding_utf32le, mbfl_no_encoding_wchar, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_utf32le_wchar, mbfl_filt_conv_common_flush, NULL, @@ -119,7 +119,7 @@ const struct mbfl_convert_vtbl vtbl_wchar_utf32le = { mbfl_no_encoding_wchar, mbfl_no_encoding_utf32le, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_wchar_utf32le, mbfl_filt_conv_common_flush, NULL, diff --git a/ext/mbstring/libmbfl/filters/mbfilter_utf7.c b/ext/mbstring/libmbfl/filters/mbfilter_utf7.c index 2318a195840ba..744c522807f26 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_utf7.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_utf7.c @@ -69,7 +69,7 @@ const struct mbfl_convert_vtbl vtbl_utf7_wchar = { mbfl_no_encoding_utf7, mbfl_no_encoding_wchar, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_utf7_wchar, mbfl_filt_conv_common_flush, NULL, @@ -79,7 +79,7 @@ const struct mbfl_convert_vtbl vtbl_wchar_utf7 = { mbfl_no_encoding_wchar, mbfl_no_encoding_utf7, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_wchar_utf7, mbfl_filt_conv_wchar_utf7_flush, NULL, diff --git a/ext/mbstring/libmbfl/filters/mbfilter_utf7imap.c b/ext/mbstring/libmbfl/filters/mbfilter_utf7imap.c index 7b346236bb5b0..c8fe70fc7f67a 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_utf7imap.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_utf7imap.c @@ -45,7 +45,7 @@ const struct mbfl_convert_vtbl vtbl_utf7imap_wchar = { mbfl_no_encoding_utf7imap, mbfl_no_encoding_wchar, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_utf7imap_wchar, mbfl_filt_conv_common_flush, NULL, @@ -55,7 +55,7 @@ const struct mbfl_convert_vtbl vtbl_wchar_utf7imap = { mbfl_no_encoding_wchar, mbfl_no_encoding_utf7imap, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_wchar_utf7imap, mbfl_filt_conv_wchar_utf7imap_flush, NULL, diff --git a/ext/mbstring/libmbfl/filters/mbfilter_utf8.c b/ext/mbstring/libmbfl/filters/mbfilter_utf8.c index dac6e0afa9330..26fd41def1a12 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_utf8.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_utf8.c @@ -75,7 +75,7 @@ const struct mbfl_convert_vtbl vtbl_utf8_wchar = { mbfl_no_encoding_utf8, mbfl_no_encoding_wchar, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_utf8_wchar, mbfl_filt_conv_utf8_wchar_flush, NULL, @@ -85,7 +85,7 @@ const struct mbfl_convert_vtbl vtbl_wchar_utf8 = { mbfl_no_encoding_wchar, mbfl_no_encoding_utf8, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_wchar_utf8, mbfl_filt_conv_common_flush, NULL, diff --git a/ext/mbstring/libmbfl/filters/mbfilter_utf8_mobile.c b/ext/mbstring/libmbfl/filters/mbfilter_utf8_mobile.c index 041d5fa799a91..5d23b75d4c5c8 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_utf8_mobile.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_utf8_mobile.c @@ -118,7 +118,7 @@ const struct mbfl_convert_vtbl vtbl_utf8_docomo_wchar = { mbfl_no_encoding_utf8_docomo, mbfl_no_encoding_wchar, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_utf8_mobile_wchar, mbfl_filt_conv_utf8_wchar_flush, NULL, @@ -128,7 +128,7 @@ const struct mbfl_convert_vtbl vtbl_wchar_utf8_docomo = { mbfl_no_encoding_wchar, mbfl_no_encoding_utf8_docomo, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_wchar_utf8_mobile, mbfl_filt_conv_common_flush, NULL, @@ -138,7 +138,7 @@ const struct mbfl_convert_vtbl vtbl_utf8_kddi_a_wchar = { mbfl_no_encoding_utf8_kddi_a, mbfl_no_encoding_wchar, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_utf8_mobile_wchar, mbfl_filt_conv_utf8_wchar_flush, NULL, @@ -148,7 +148,7 @@ const struct mbfl_convert_vtbl vtbl_wchar_utf8_kddi_a = { mbfl_no_encoding_wchar, mbfl_no_encoding_utf8_kddi_a, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_wchar_utf8_mobile, mbfl_filt_conv_common_flush, NULL, @@ -158,7 +158,7 @@ const struct mbfl_convert_vtbl vtbl_utf8_kddi_b_wchar = { mbfl_no_encoding_utf8_kddi_b, mbfl_no_encoding_wchar, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_utf8_mobile_wchar, mbfl_filt_conv_utf8_wchar_flush, NULL, @@ -168,7 +168,7 @@ const struct mbfl_convert_vtbl vtbl_wchar_utf8_kddi_b = { mbfl_no_encoding_wchar, mbfl_no_encoding_utf8_kddi_b, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_wchar_utf8_mobile, mbfl_filt_conv_common_flush, NULL, @@ -178,7 +178,7 @@ const struct mbfl_convert_vtbl vtbl_utf8_sb_wchar = { mbfl_no_encoding_utf8_sb, mbfl_no_encoding_wchar, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_utf8_mobile_wchar, mbfl_filt_conv_utf8_wchar_flush, NULL, @@ -188,7 +188,7 @@ const struct mbfl_convert_vtbl vtbl_wchar_utf8_sb = { mbfl_no_encoding_wchar, mbfl_no_encoding_utf8_sb, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_wchar_utf8_mobile, mbfl_filt_conv_common_flush, NULL, diff --git a/ext/mbstring/libmbfl/filters/mbfilter_uuencode.c b/ext/mbstring/libmbfl/filters/mbfilter_uuencode.c index a78acd3718772..fab29ef9fc8dd 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_uuencode.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_uuencode.c @@ -45,7 +45,7 @@ const struct mbfl_convert_vtbl vtbl_uuencode_8bit = { mbfl_no_encoding_uuencode, mbfl_no_encoding_8bit, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_uudec, mbfl_filt_conv_common_flush, NULL, diff --git a/ext/mbstring/libmbfl/mbfl/mbfilter.c b/ext/mbstring/libmbfl/mbfl/mbfilter.c index 65817d384a2f0..b5b760a2bc19e 100644 --- a/ext/mbstring/libmbfl/mbfl/mbfilter.c +++ b/ext/mbstring/libmbfl/mbfl/mbfilter.c @@ -1232,8 +1232,10 @@ mbfl_strcut( if (device.pos > length) { p = _bk.p; device.pos = _bk.pos; - decoder->filter_dtor(decoder); - encoder->filter_dtor(encoder); + if (decoder->filter_dtor) + decoder->filter_dtor(decoder); + if (encoder->filter_dtor) + encoder->filter_dtor(encoder); mbfl_convert_filter_copy(&_bk.decoder, decoder); mbfl_convert_filter_copy(&_bk.encoder, encoder); bk = _bk; @@ -1250,24 +1252,32 @@ mbfl_strcut( /* if the offset of the resulting string exceeds the length, * then restore the state */ if (device.pos > length) { - bk.decoder.filter_dtor(&bk.decoder); - bk.encoder.filter_dtor(&bk.encoder); + if (bk.decoder.filter_dtor) + bk.decoder.filter_dtor(&bk.decoder); + if (bk.encoder.filter_dtor) + bk.encoder.filter_dtor(&bk.encoder); p = _bk.p; device.pos = _bk.pos; - decoder->filter_dtor(decoder); - encoder->filter_dtor(encoder); + if (decoder->filter_dtor) + decoder->filter_dtor(decoder); + if (encoder->filter_dtor) + encoder->filter_dtor(encoder); mbfl_convert_filter_copy(&_bk.decoder, decoder); mbfl_convert_filter_copy(&_bk.encoder, encoder); bk = _bk; } else { - _bk.decoder.filter_dtor(&_bk.decoder); - _bk.encoder.filter_dtor(&_bk.encoder); + if (_bk.decoder.filter_dtor) + _bk.decoder.filter_dtor(&_bk.decoder); + if (_bk.encoder.filter_dtor) + _bk.encoder.filter_dtor(&_bk.encoder); p = bk.p; device.pos = bk.pos; - decoder->filter_dtor(decoder); - encoder->filter_dtor(encoder); + if (decoder->filter_dtor) + decoder->filter_dtor(decoder); + if (encoder->filter_dtor) + encoder->filter_dtor(encoder); mbfl_convert_filter_copy(&bk.decoder, decoder); mbfl_convert_filter_copy(&bk.encoder, encoder); } @@ -1284,8 +1294,10 @@ mbfl_strcut( /* restore filter */ p = bk.p; device.pos = bk.pos; - decoder->filter_dtor(decoder); - encoder->filter_dtor(encoder); + if (decoder->filter_dtor) + decoder->filter_dtor(decoder); + if (encoder->filter_dtor) + encoder->filter_dtor(encoder); mbfl_convert_filter_copy(&bk.decoder, decoder); mbfl_convert_filter_copy(&bk.encoder, encoder); break; @@ -1302,26 +1314,34 @@ mbfl_strcut( (*encoder->filter_flush)(encoder); if (device.pos > length) { - _bk.decoder.filter_dtor(&_bk.decoder); - _bk.encoder.filter_dtor(&_bk.encoder); + if (_bk.decoder.filter_dtor) + _bk.decoder.filter_dtor(&_bk.decoder); + if (_bk.encoder.filter_dtor) + _bk.encoder.filter_dtor(&_bk.encoder); /* restore filter */ p = bk.p; device.pos = bk.pos; - decoder->filter_dtor(decoder); - encoder->filter_dtor(encoder); + if (decoder->filter_dtor) + decoder->filter_dtor(decoder); + if (encoder->filter_dtor) + encoder->filter_dtor(encoder); mbfl_convert_filter_copy(&bk.decoder, decoder); mbfl_convert_filter_copy(&bk.encoder, encoder); break; } - bk.decoder.filter_dtor(&bk.decoder); - bk.encoder.filter_dtor(&bk.encoder); + if (bk.decoder.filter_dtor) + bk.decoder.filter_dtor(&bk.decoder); + if (bk.encoder.filter_dtor) + bk.encoder.filter_dtor(&bk.encoder); p = _bk.p; device.pos = _bk.pos; - decoder->filter_dtor(decoder); - encoder->filter_dtor(encoder); + if (decoder->filter_dtor) + decoder->filter_dtor(decoder); + if (encoder->filter_dtor) + encoder->filter_dtor(encoder); mbfl_convert_filter_copy(&_bk.decoder, decoder); mbfl_convert_filter_copy(&_bk.encoder, encoder); @@ -1330,8 +1350,10 @@ mbfl_strcut( (*encoder->filter_flush)(encoder); - bk.decoder.filter_dtor(&bk.decoder); - bk.encoder.filter_dtor(&bk.encoder); + if (bk.decoder.filter_dtor) + bk.decoder.filter_dtor(&bk.decoder); + if (bk.encoder.filter_dtor) + bk.encoder.filter_dtor(&bk.encoder); result = mbfl_memory_device_result(&device, result); diff --git a/ext/mbstring/libmbfl/mbfl/mbfilter_8bit.c b/ext/mbstring/libmbfl/mbfl/mbfilter_8bit.c index 059feb0b3c4ec..f4c74946c11b8 100644 --- a/ext/mbstring/libmbfl/mbfl/mbfilter_8bit.c +++ b/ext/mbstring/libmbfl/mbfl/mbfilter_8bit.c @@ -54,7 +54,7 @@ const struct mbfl_convert_vtbl vtbl_8bit_wchar = { mbfl_no_encoding_8bit, mbfl_no_encoding_wchar, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_8bit_wchar, mbfl_filt_conv_common_flush, NULL, @@ -64,7 +64,7 @@ const struct mbfl_convert_vtbl vtbl_wchar_8bit = { mbfl_no_encoding_wchar, mbfl_no_encoding_8bit, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_wchar_8bit, mbfl_filt_conv_common_flush, NULL, diff --git a/ext/mbstring/libmbfl/mbfl/mbfilter_pass.c b/ext/mbstring/libmbfl/mbfl/mbfilter_pass.c index 5136bb1c72982..3d7cffe9c14f7 100644 --- a/ext/mbstring/libmbfl/mbfl/mbfilter_pass.c +++ b/ext/mbstring/libmbfl/mbfl/mbfilter_pass.c @@ -49,7 +49,7 @@ const struct mbfl_convert_vtbl vtbl_pass = { mbfl_no_encoding_pass, mbfl_no_encoding_pass, mbfl_filt_conv_common_ctor, - mbfl_filt_conv_common_dtor, + NULL, mbfl_filt_conv_pass, mbfl_filt_conv_common_flush, NULL, diff --git a/ext/mbstring/libmbfl/mbfl/mbfl_convert.c b/ext/mbstring/libmbfl/mbfl/mbfl_convert.c index 0f41e35b25158..544fee7a33ca8 100644 --- a/ext/mbstring/libmbfl/mbfl/mbfl_convert.c +++ b/ext/mbstring/libmbfl/mbfl/mbfl_convert.c @@ -169,7 +169,9 @@ mbfl_convert_filter* mbfl_convert_filter_new2(const struct mbfl_convert_vtbl *vt void mbfl_convert_filter_delete(mbfl_convert_filter *filter) { - (*filter->filter_dtor)(filter); + if (filter->filter_dtor) { + (*filter->filter_dtor)(filter); + } efree(filter); } @@ -387,7 +389,7 @@ const struct mbfl_convert_vtbl* mbfl_convert_filter_get_vtbl(const mbfl_encoding } /* - * commonly used constructor and destructor + * commonly used constructor */ void mbfl_filt_conv_common_ctor(mbfl_convert_filter *filter) { @@ -405,9 +407,3 @@ int mbfl_filt_conv_common_flush(mbfl_convert_filter *filter) } return 0; } - -void mbfl_filt_conv_common_dtor(mbfl_convert_filter *filter) -{ - filter->status = 0; - filter->cache = 0; -} diff --git a/ext/mbstring/libmbfl/mbfl/mbfl_convert.h b/ext/mbstring/libmbfl/mbfl/mbfl_convert.h index f38de7eefe628..6fc6b3c6bccf6 100644 --- a/ext/mbstring/libmbfl/mbfl/mbfl_convert.h +++ b/ext/mbstring/libmbfl/mbfl/mbfl_convert.h @@ -73,7 +73,6 @@ MBFLAPI extern const struct mbfl_convert_vtbl * mbfl_convert_filter_get_vtbl(con MBFLAPI extern void mbfl_filt_conv_common_ctor(mbfl_convert_filter *filter); MBFLAPI extern int mbfl_filt_conv_common_flush(mbfl_convert_filter *filter); -MBFLAPI extern void mbfl_filt_conv_common_dtor(mbfl_convert_filter *filter); MBFLAPI extern void mbfl_convert_filter_devcat(mbfl_convert_filter *filter, mbfl_memory_device *src); MBFLAPI extern int mbfl_convert_filter_strcat(mbfl_convert_filter *filter, const unsigned char *p); From a2b40ee9a5cb2161304fd205ac6b2125fe46b412 Mon Sep 17 00:00:00 2001 From: Alex Dowad Date: Thu, 16 Jul 2020 09:23:37 +0200 Subject: [PATCH 42/87] Remove unneeded function mbfl_filt_ident_common_dtor This was the default destructor for mbfl_identify_filter structs, but there's nothing we actually need to do to those structs before freeing them. --- .../libmbfl/filters/mbfilter_armscii8.c | 1 - ext/mbstring/libmbfl/filters/mbfilter_ascii.c | 1 - ext/mbstring/libmbfl/filters/mbfilter_big5.c | 2 -- .../libmbfl/filters/mbfilter_cp1251.c | 1 - .../libmbfl/filters/mbfilter_cp1252.c | 1 - .../libmbfl/filters/mbfilter_cp1254.c | 1 - .../libmbfl/filters/mbfilter_cp5022x.c | 5 ----- .../libmbfl/filters/mbfilter_cp51932.c | 1 - ext/mbstring/libmbfl/filters/mbfilter_cp850.c | 1 - ext/mbstring/libmbfl/filters/mbfilter_cp866.c | 1 - ext/mbstring/libmbfl/filters/mbfilter_cp932.c | 1 - ext/mbstring/libmbfl/filters/mbfilter_cp936.c | 1 - .../libmbfl/filters/mbfilter_euc_cn.c | 1 - .../libmbfl/filters/mbfilter_euc_jp.c | 1 - .../libmbfl/filters/mbfilter_euc_jp_2004.c | 1 - .../libmbfl/filters/mbfilter_euc_jp_win.c | 1 - .../libmbfl/filters/mbfilter_euc_kr.c | 1 - .../libmbfl/filters/mbfilter_euc_tw.c | 1 - .../libmbfl/filters/mbfilter_gb18030.c | 1 - ext/mbstring/libmbfl/filters/mbfilter_hz.c | 1 - .../libmbfl/filters/mbfilter_iso2022_jp_ms.c | 1 - .../libmbfl/filters/mbfilter_iso2022_kr.c | 1 - .../libmbfl/filters/mbfilter_iso2022jp_2004.c | 1 - .../filters/mbfilter_iso2022jp_mobile.c | 1 - .../libmbfl/filters/mbfilter_iso8859_1.c | 1 - .../libmbfl/filters/mbfilter_iso8859_10.c | 1 - .../libmbfl/filters/mbfilter_iso8859_13.c | 1 - .../libmbfl/filters/mbfilter_iso8859_14.c | 1 - .../libmbfl/filters/mbfilter_iso8859_15.c | 1 - .../libmbfl/filters/mbfilter_iso8859_16.c | 1 - .../libmbfl/filters/mbfilter_iso8859_2.c | 1 - .../libmbfl/filters/mbfilter_iso8859_3.c | 1 - .../libmbfl/filters/mbfilter_iso8859_4.c | 4 ++-- .../libmbfl/filters/mbfilter_iso8859_5.c | 1 - .../libmbfl/filters/mbfilter_iso8859_6.c | 1 - .../libmbfl/filters/mbfilter_iso8859_7.c | 1 - .../libmbfl/filters/mbfilter_iso8859_8.c | 1 - .../libmbfl/filters/mbfilter_iso8859_9.c | 1 - ext/mbstring/libmbfl/filters/mbfilter_jis.c | 2 -- ext/mbstring/libmbfl/filters/mbfilter_koi8r.c | 1 - ext/mbstring/libmbfl/filters/mbfilter_koi8u.c | 1 - ext/mbstring/libmbfl/filters/mbfilter_sjis.c | 1 - .../libmbfl/filters/mbfilter_sjis_2004.c | 1 - .../libmbfl/filters/mbfilter_sjis_mac.c | 1 - .../libmbfl/filters/mbfilter_sjis_mobile.c | 3 --- .../libmbfl/filters/mbfilter_sjis_open.c | 1 - ext/mbstring/libmbfl/filters/mbfilter_uhc.c | 1 - ext/mbstring/libmbfl/filters/mbfilter_utf7.c | 1 - ext/mbstring/libmbfl/filters/mbfilter_utf8.c | 1 - .../libmbfl/filters/mbfilter_utf8_mobile.c | 4 ---- ext/mbstring/libmbfl/mbfl/mbfilter.c | 7 ------- ext/mbstring/libmbfl/mbfl/mbfl_ident.c | 19 ++----------------- ext/mbstring/libmbfl/mbfl/mbfl_ident.h | 4 ---- 53 files changed, 4 insertions(+), 90 deletions(-) diff --git a/ext/mbstring/libmbfl/filters/mbfilter_armscii8.c b/ext/mbstring/libmbfl/filters/mbfilter_armscii8.c index e168176cc03d2..38c8f98bd18ae 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_armscii8.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_armscii8.c @@ -48,7 +48,6 @@ const mbfl_encoding mbfl_encoding_armscii8 = { const struct mbfl_identify_vtbl vtbl_identify_armscii8 = { mbfl_no_encoding_armscii8, mbfl_filt_ident_common_ctor, - mbfl_filt_ident_common_dtor, mbfl_filt_ident_armscii8 }; diff --git a/ext/mbstring/libmbfl/filters/mbfilter_ascii.c b/ext/mbstring/libmbfl/filters/mbfilter_ascii.c index a1e9533bc86b2..43d659a46c899 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_ascii.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_ascii.c @@ -49,7 +49,6 @@ const mbfl_encoding mbfl_encoding_ascii = { const struct mbfl_identify_vtbl vtbl_identify_ascii = { mbfl_no_encoding_ascii, mbfl_filt_ident_common_ctor, - mbfl_filt_ident_common_dtor, mbfl_filt_ident_ascii }; diff --git a/ext/mbstring/libmbfl/filters/mbfilter_big5.c b/ext/mbstring/libmbfl/filters/mbfilter_big5.c index 6d0d22aa192d2..1e59924092ac2 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_big5.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_big5.c @@ -80,14 +80,12 @@ const mbfl_encoding mbfl_encoding_cp950 = { const struct mbfl_identify_vtbl vtbl_identify_big5 = { mbfl_no_encoding_big5, mbfl_filt_ident_common_ctor, - mbfl_filt_ident_common_dtor, mbfl_filt_ident_big5 }; const struct mbfl_identify_vtbl vtbl_identify_cp950 = { mbfl_no_encoding_cp950, mbfl_filt_ident_common_ctor, - mbfl_filt_ident_common_dtor, mbfl_filt_ident_big5 }; diff --git a/ext/mbstring/libmbfl/filters/mbfilter_cp1251.c b/ext/mbstring/libmbfl/filters/mbfilter_cp1251.c index 021c2f617ef92..470adf1a08491 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_cp1251.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_cp1251.c @@ -49,7 +49,6 @@ const mbfl_encoding mbfl_encoding_cp1251 = { const struct mbfl_identify_vtbl vtbl_identify_cp1251 = { mbfl_no_encoding_cp1251, mbfl_filt_ident_common_ctor, - mbfl_filt_ident_common_dtor, mbfl_filt_ident_cp1251 }; diff --git a/ext/mbstring/libmbfl/filters/mbfilter_cp1252.c b/ext/mbstring/libmbfl/filters/mbfilter_cp1252.c index 8208efffaa93c..a274e4b796c57 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_cp1252.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_cp1252.c @@ -49,7 +49,6 @@ const mbfl_encoding mbfl_encoding_cp1252 = { const struct mbfl_identify_vtbl vtbl_identify_cp1252 = { mbfl_no_encoding_cp1252, mbfl_filt_ident_common_ctor, - mbfl_filt_ident_common_dtor, mbfl_filt_ident_cp1252 }; diff --git a/ext/mbstring/libmbfl/filters/mbfilter_cp1254.c b/ext/mbstring/libmbfl/filters/mbfilter_cp1254.c index 70846984f778c..7e4bb4b148e96 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_cp1254.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_cp1254.c @@ -49,7 +49,6 @@ const mbfl_encoding mbfl_encoding_cp1254 = { const struct mbfl_identify_vtbl vtbl_identify_cp1254 = { mbfl_no_encoding_cp1254, mbfl_filt_ident_common_ctor, - mbfl_filt_ident_common_dtor, mbfl_filt_ident_cp1254 }; diff --git a/ext/mbstring/libmbfl/filters/mbfilter_cp5022x.c b/ext/mbstring/libmbfl/filters/mbfilter_cp5022x.c index 61a862f94b62f..a68285bc7310d 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_cp5022x.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_cp5022x.c @@ -102,35 +102,30 @@ const mbfl_encoding mbfl_encoding_cp50222 = { const struct mbfl_identify_vtbl vtbl_identify_jis_ms = { mbfl_no_encoding_jis_ms, mbfl_filt_ident_common_ctor, - mbfl_filt_ident_common_dtor, mbfl_filt_ident_jis_ms }; const struct mbfl_identify_vtbl vtbl_identify_cp50220 = { mbfl_no_encoding_cp50220, mbfl_filt_ident_common_ctor, - mbfl_filt_ident_common_dtor, mbfl_filt_ident_cp50220 }; const struct mbfl_identify_vtbl vtbl_identify_cp50220raw = { mbfl_no_encoding_cp50220raw, mbfl_filt_ident_common_ctor, - mbfl_filt_ident_common_dtor, mbfl_filt_ident_cp50220 }; const struct mbfl_identify_vtbl vtbl_identify_cp50221 = { mbfl_no_encoding_cp50221, mbfl_filt_ident_common_ctor, - mbfl_filt_ident_common_dtor, mbfl_filt_ident_cp50221 }; const struct mbfl_identify_vtbl vtbl_identify_cp50222 = { mbfl_no_encoding_cp50222, mbfl_filt_ident_common_ctor, - mbfl_filt_ident_common_dtor, mbfl_filt_ident_cp50222 }; diff --git a/ext/mbstring/libmbfl/filters/mbfilter_cp51932.c b/ext/mbstring/libmbfl/filters/mbfilter_cp51932.c index e3d96da8b88ab..da046c86b7609 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_cp51932.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_cp51932.c @@ -61,7 +61,6 @@ static const char *mbfl_encoding_cp51932_aliases[] = {"cp51932", NULL}; const struct mbfl_identify_vtbl vtbl_identify_cp51932 = { mbfl_no_encoding_cp51932, mbfl_filt_ident_common_ctor, - mbfl_filt_ident_common_dtor, mbfl_filt_ident_cp51932 }; diff --git a/ext/mbstring/libmbfl/filters/mbfilter_cp850.c b/ext/mbstring/libmbfl/filters/mbfilter_cp850.c index e8833ad87b49e..5d6b265fc15e9 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_cp850.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_cp850.c @@ -45,7 +45,6 @@ const mbfl_encoding mbfl_encoding_cp850 = { const struct mbfl_identify_vtbl vtbl_identify_cp850 = { mbfl_no_encoding_cp850, mbfl_filt_ident_common_ctor, - mbfl_filt_ident_common_dtor, mbfl_filt_ident_cp850 }; diff --git a/ext/mbstring/libmbfl/filters/mbfilter_cp866.c b/ext/mbstring/libmbfl/filters/mbfilter_cp866.c index 14c49ff790386..504903bef0c06 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_cp866.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_cp866.c @@ -49,7 +49,6 @@ const mbfl_encoding mbfl_encoding_cp866 = { const struct mbfl_identify_vtbl vtbl_identify_cp866 = { mbfl_no_encoding_cp866, mbfl_filt_ident_common_ctor, - mbfl_filt_ident_common_dtor, mbfl_filt_ident_cp866 }; diff --git a/ext/mbstring/libmbfl/filters/mbfilter_cp932.c b/ext/mbstring/libmbfl/filters/mbfilter_cp932.c index b2ec5a99685b3..3cbca1cb6451b 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_cp932.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_cp932.c @@ -70,7 +70,6 @@ const mbfl_encoding mbfl_encoding_cp932 = { const struct mbfl_identify_vtbl vtbl_identify_cp932 = { mbfl_no_encoding_cp932, mbfl_filt_ident_common_ctor, - mbfl_filt_ident_common_dtor, mbfl_filt_ident_cp932 }; diff --git a/ext/mbstring/libmbfl/filters/mbfilter_cp936.c b/ext/mbstring/libmbfl/filters/mbfilter_cp936.c index 5baa0dabbcbaa..df6d77907fc3f 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_cp936.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_cp936.c @@ -69,7 +69,6 @@ const mbfl_encoding mbfl_encoding_cp936 = { const struct mbfl_identify_vtbl vtbl_identify_cp936 = { mbfl_no_encoding_cp936, mbfl_filt_ident_common_ctor, - mbfl_filt_ident_common_dtor, mbfl_filt_ident_cp936 }; diff --git a/ext/mbstring/libmbfl/filters/mbfilter_euc_cn.c b/ext/mbstring/libmbfl/filters/mbfilter_euc_cn.c index 7a8431219e42c..53a8aac2a64c0 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_euc_cn.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_euc_cn.c @@ -69,7 +69,6 @@ const mbfl_encoding mbfl_encoding_euc_cn = { const struct mbfl_identify_vtbl vtbl_identify_euccn = { mbfl_no_encoding_euc_cn, mbfl_filt_ident_common_ctor, - mbfl_filt_ident_common_dtor, mbfl_filt_ident_euccn }; diff --git a/ext/mbstring/libmbfl/filters/mbfilter_euc_jp.c b/ext/mbstring/libmbfl/filters/mbfilter_euc_jp.c index ac12b3ed948b4..252a10a58dcfb 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_euc_jp.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_euc_jp.c @@ -70,7 +70,6 @@ const mbfl_encoding mbfl_encoding_euc_jp = { const struct mbfl_identify_vtbl vtbl_identify_eucjp = { mbfl_no_encoding_euc_jp, mbfl_filt_ident_common_ctor, - mbfl_filt_ident_common_dtor, mbfl_filt_ident_eucjp }; diff --git a/ext/mbstring/libmbfl/filters/mbfilter_euc_jp_2004.c b/ext/mbstring/libmbfl/filters/mbfilter_euc_jp_2004.c index 8efb49eff71f5..30d869cea5b6f 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_euc_jp_2004.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_euc_jp_2004.c @@ -50,7 +50,6 @@ const mbfl_encoding mbfl_encoding_eucjp2004 = { const struct mbfl_identify_vtbl vtbl_identify_eucjp2004 = { mbfl_no_encoding_eucjp2004, mbfl_filt_ident_common_ctor, - mbfl_filt_ident_common_dtor, mbfl_filt_ident_eucjp }; diff --git a/ext/mbstring/libmbfl/filters/mbfilter_euc_jp_win.c b/ext/mbstring/libmbfl/filters/mbfilter_euc_jp_win.c index 7845fa2d1aa4a..5798bff0fca1f 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_euc_jp_win.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_euc_jp_win.c @@ -62,7 +62,6 @@ static const char *mbfl_encoding_eucjp_win_aliases[] = {"eucJP-open", const struct mbfl_identify_vtbl vtbl_identify_eucjpwin = { mbfl_no_encoding_eucjp_win, mbfl_filt_ident_common_ctor, - mbfl_filt_ident_common_dtor, mbfl_filt_ident_eucjp_win }; diff --git a/ext/mbstring/libmbfl/filters/mbfilter_euc_kr.c b/ext/mbstring/libmbfl/filters/mbfilter_euc_kr.c index fef81b693be19..e9b08e08c1f72 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_euc_kr.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_euc_kr.c @@ -68,7 +68,6 @@ const mbfl_encoding mbfl_encoding_euc_kr = { const struct mbfl_identify_vtbl vtbl_identify_euckr = { mbfl_no_encoding_euc_kr, mbfl_filt_ident_common_ctor, - mbfl_filt_ident_common_dtor, mbfl_filt_ident_euckr }; diff --git a/ext/mbstring/libmbfl/filters/mbfilter_euc_tw.c b/ext/mbstring/libmbfl/filters/mbfilter_euc_tw.c index fe908c4ffb1bc..c76eeb36bfdfe 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_euc_tw.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_euc_tw.c @@ -70,7 +70,6 @@ const mbfl_encoding mbfl_encoding_euc_tw = { const struct mbfl_identify_vtbl vtbl_identify_euctw = { mbfl_no_encoding_euc_tw, mbfl_filt_ident_common_ctor, - mbfl_filt_ident_common_dtor, mbfl_filt_ident_euctw }; diff --git a/ext/mbstring/libmbfl/filters/mbfilter_gb18030.c b/ext/mbstring/libmbfl/filters/mbfilter_gb18030.c index 1bda813bb9aad..b94d664f401d7 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_gb18030.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_gb18030.c @@ -51,7 +51,6 @@ const mbfl_encoding mbfl_encoding_gb18030 = { const struct mbfl_identify_vtbl vtbl_identify_gb18030 = { mbfl_no_encoding_gb18030, mbfl_filt_ident_common_ctor, - mbfl_filt_ident_common_dtor, mbfl_filt_ident_gb18030 }; diff --git a/ext/mbstring/libmbfl/filters/mbfilter_hz.c b/ext/mbstring/libmbfl/filters/mbfilter_hz.c index 1d95613b7455f..ceac85816cf09 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_hz.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_hz.c @@ -48,7 +48,6 @@ const mbfl_encoding mbfl_encoding_hz = { const struct mbfl_identify_vtbl vtbl_identify_hz = { mbfl_no_encoding_hz, mbfl_filt_ident_common_ctor, - mbfl_filt_ident_common_dtor, mbfl_filt_ident_hz }; diff --git a/ext/mbstring/libmbfl/filters/mbfilter_iso2022_jp_ms.c b/ext/mbstring/libmbfl/filters/mbfilter_iso2022_jp_ms.c index 9183e1e2a3491..1e9757eae62e5 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_iso2022_jp_ms.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_iso2022_jp_ms.c @@ -52,7 +52,6 @@ const mbfl_encoding mbfl_encoding_2022jpms = { const struct mbfl_identify_vtbl vtbl_identify_2022jpms = { mbfl_no_encoding_2022jpms, mbfl_filt_ident_common_ctor, - mbfl_filt_ident_common_dtor, mbfl_filt_ident_2022jpms }; diff --git a/ext/mbstring/libmbfl/filters/mbfilter_iso2022_kr.c b/ext/mbstring/libmbfl/filters/mbfilter_iso2022_kr.c index 8d8f9171867dc..8df1d6f9b5603 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_iso2022_kr.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_iso2022_kr.c @@ -47,7 +47,6 @@ const mbfl_encoding mbfl_encoding_2022kr = { const struct mbfl_identify_vtbl vtbl_identify_2022kr = { mbfl_no_encoding_2022kr, mbfl_filt_ident_common_ctor, - mbfl_filt_ident_common_dtor, mbfl_filt_ident_2022kr }; diff --git a/ext/mbstring/libmbfl/filters/mbfilter_iso2022jp_2004.c b/ext/mbstring/libmbfl/filters/mbfilter_iso2022jp_2004.c index 7b9a663e12293..b381f09bea56e 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_iso2022jp_2004.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_iso2022jp_2004.c @@ -50,7 +50,6 @@ const mbfl_encoding mbfl_encoding_2022jp_2004 = { const struct mbfl_identify_vtbl vtbl_identify_2022jp_2004 = { mbfl_no_encoding_2022jp_2004, mbfl_filt_ident_common_ctor, - mbfl_filt_ident_common_dtor, mbfl_filt_ident_2022jp_2004 }; diff --git a/ext/mbstring/libmbfl/filters/mbfilter_iso2022jp_mobile.c b/ext/mbstring/libmbfl/filters/mbfilter_iso2022jp_mobile.c index 0d4795942adde..32ea47712e165 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_iso2022jp_mobile.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_iso2022jp_mobile.c @@ -54,7 +54,6 @@ const mbfl_encoding mbfl_encoding_2022jp_kddi = { const struct mbfl_identify_vtbl vtbl_identify_2022jp_kddi = { mbfl_no_encoding_2022jp_kddi, mbfl_filt_ident_common_ctor, - mbfl_filt_ident_common_dtor, mbfl_filt_ident_2022jpms }; diff --git a/ext/mbstring/libmbfl/filters/mbfilter_iso8859_1.c b/ext/mbstring/libmbfl/filters/mbfilter_iso8859_1.c index ce94528f4a363..1549ba81bfb95 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_iso8859_1.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_iso8859_1.c @@ -46,7 +46,6 @@ const mbfl_encoding mbfl_encoding_8859_1 = { const struct mbfl_identify_vtbl vtbl_identify_8859_1 = { mbfl_no_encoding_8859_1, mbfl_filt_ident_common_ctor, - mbfl_filt_ident_common_dtor, mbfl_filt_ident_true }; diff --git a/ext/mbstring/libmbfl/filters/mbfilter_iso8859_10.c b/ext/mbstring/libmbfl/filters/mbfilter_iso8859_10.c index cee8d60a8fa4e..12cd960a8802e 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_iso8859_10.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_iso8859_10.c @@ -47,7 +47,6 @@ const mbfl_encoding mbfl_encoding_8859_10 = { const struct mbfl_identify_vtbl vtbl_identify_8859_10 = { mbfl_no_encoding_8859_10, mbfl_filt_ident_common_ctor, - mbfl_filt_ident_common_dtor, mbfl_filt_ident_true }; diff --git a/ext/mbstring/libmbfl/filters/mbfilter_iso8859_13.c b/ext/mbstring/libmbfl/filters/mbfilter_iso8859_13.c index daaf7bec50f3f..25526263b86c9 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_iso8859_13.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_iso8859_13.c @@ -47,7 +47,6 @@ const mbfl_encoding mbfl_encoding_8859_13 = { const struct mbfl_identify_vtbl vtbl_identify_8859_13 = { mbfl_no_encoding_8859_13, mbfl_filt_ident_common_ctor, - mbfl_filt_ident_common_dtor, mbfl_filt_ident_true }; diff --git a/ext/mbstring/libmbfl/filters/mbfilter_iso8859_14.c b/ext/mbstring/libmbfl/filters/mbfilter_iso8859_14.c index edc5c72c85e00..06a2e4cd984c0 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_iso8859_14.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_iso8859_14.c @@ -47,7 +47,6 @@ const mbfl_encoding mbfl_encoding_8859_14 = { const struct mbfl_identify_vtbl vtbl_identify_8859_14 = { mbfl_no_encoding_8859_14, mbfl_filt_ident_common_ctor, - mbfl_filt_ident_common_dtor, mbfl_filt_ident_true }; diff --git a/ext/mbstring/libmbfl/filters/mbfilter_iso8859_15.c b/ext/mbstring/libmbfl/filters/mbfilter_iso8859_15.c index 38b77fc0775b4..82b40796b8f7a 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_iso8859_15.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_iso8859_15.c @@ -47,7 +47,6 @@ const mbfl_encoding mbfl_encoding_8859_15 = { const struct mbfl_identify_vtbl vtbl_identify_8859_15 = { mbfl_no_encoding_8859_15, mbfl_filt_ident_common_ctor, - mbfl_filt_ident_common_dtor, mbfl_filt_ident_true }; diff --git a/ext/mbstring/libmbfl/filters/mbfilter_iso8859_16.c b/ext/mbstring/libmbfl/filters/mbfilter_iso8859_16.c index 355c3004669a2..80f1461364a3e 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_iso8859_16.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_iso8859_16.c @@ -47,7 +47,6 @@ const mbfl_encoding mbfl_encoding_8859_16 = { const struct mbfl_identify_vtbl vtbl_identify_8859_16 = { mbfl_no_encoding_8859_16, mbfl_filt_ident_common_ctor, - mbfl_filt_ident_common_dtor, mbfl_filt_ident_true }; diff --git a/ext/mbstring/libmbfl/filters/mbfilter_iso8859_2.c b/ext/mbstring/libmbfl/filters/mbfilter_iso8859_2.c index 279ee694fcc52..86044e15d3a02 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_iso8859_2.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_iso8859_2.c @@ -47,7 +47,6 @@ const mbfl_encoding mbfl_encoding_8859_2 = { const struct mbfl_identify_vtbl vtbl_identify_8859_2 = { mbfl_no_encoding_8859_2, mbfl_filt_ident_common_ctor, - mbfl_filt_ident_common_dtor, mbfl_filt_ident_true }; diff --git a/ext/mbstring/libmbfl/filters/mbfilter_iso8859_3.c b/ext/mbstring/libmbfl/filters/mbfilter_iso8859_3.c index 853a7e202fd56..64eb9b5cf9283 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_iso8859_3.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_iso8859_3.c @@ -47,7 +47,6 @@ const mbfl_encoding mbfl_encoding_8859_3 = { const struct mbfl_identify_vtbl vtbl_identify_8859_3 = { mbfl_no_encoding_8859_3, mbfl_filt_ident_common_ctor, - mbfl_filt_ident_common_dtor, mbfl_filt_ident_true }; diff --git a/ext/mbstring/libmbfl/filters/mbfilter_iso8859_4.c b/ext/mbstring/libmbfl/filters/mbfilter_iso8859_4.c index 264c0eae98fc1..12a9f7cb1063a 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_iso8859_4.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_iso8859_4.c @@ -47,8 +47,8 @@ const mbfl_encoding mbfl_encoding_8859_4 = { const struct mbfl_identify_vtbl vtbl_identify_8859_4 = { mbfl_no_encoding_8859_4, mbfl_filt_ident_common_ctor, - mbfl_filt_ident_common_dtor, - mbfl_filt_ident_true }; + mbfl_filt_ident_true +}; const struct mbfl_convert_vtbl vtbl_8859_4_wchar = { mbfl_no_encoding_8859_4, diff --git a/ext/mbstring/libmbfl/filters/mbfilter_iso8859_5.c b/ext/mbstring/libmbfl/filters/mbfilter_iso8859_5.c index f17da31260b69..70496d07e7a4d 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_iso8859_5.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_iso8859_5.c @@ -47,7 +47,6 @@ const mbfl_encoding mbfl_encoding_8859_5 = { const struct mbfl_identify_vtbl vtbl_identify_8859_5 = { mbfl_no_encoding_8859_5, mbfl_filt_ident_common_ctor, - mbfl_filt_ident_common_dtor, mbfl_filt_ident_true }; diff --git a/ext/mbstring/libmbfl/filters/mbfilter_iso8859_6.c b/ext/mbstring/libmbfl/filters/mbfilter_iso8859_6.c index d184a71495a64..59d981e9c2c79 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_iso8859_6.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_iso8859_6.c @@ -47,7 +47,6 @@ const mbfl_encoding mbfl_encoding_8859_6 = { const struct mbfl_identify_vtbl vtbl_identify_8859_6 = { mbfl_no_encoding_8859_6, mbfl_filt_ident_common_ctor, - mbfl_filt_ident_common_dtor, mbfl_filt_ident_true }; diff --git a/ext/mbstring/libmbfl/filters/mbfilter_iso8859_7.c b/ext/mbstring/libmbfl/filters/mbfilter_iso8859_7.c index 029fed07294d9..73ead533ea771 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_iso8859_7.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_iso8859_7.c @@ -47,7 +47,6 @@ const mbfl_encoding mbfl_encoding_8859_7 = { const struct mbfl_identify_vtbl vtbl_identify_8859_7 = { mbfl_no_encoding_8859_7, mbfl_filt_ident_common_ctor, - mbfl_filt_ident_common_dtor, mbfl_filt_ident_true }; diff --git a/ext/mbstring/libmbfl/filters/mbfilter_iso8859_8.c b/ext/mbstring/libmbfl/filters/mbfilter_iso8859_8.c index 16bc6e4f6ecc4..05ca13f330d57 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_iso8859_8.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_iso8859_8.c @@ -47,7 +47,6 @@ const mbfl_encoding mbfl_encoding_8859_8 = { const struct mbfl_identify_vtbl vtbl_identify_8859_8 = { mbfl_no_encoding_8859_8, mbfl_filt_ident_common_ctor, - mbfl_filt_ident_common_dtor, mbfl_filt_ident_true }; diff --git a/ext/mbstring/libmbfl/filters/mbfilter_iso8859_9.c b/ext/mbstring/libmbfl/filters/mbfilter_iso8859_9.c index 2d45c1b91c426..074f90bef2404 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_iso8859_9.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_iso8859_9.c @@ -47,7 +47,6 @@ const mbfl_encoding mbfl_encoding_8859_9 = { const struct mbfl_identify_vtbl vtbl_identify_8859_9 = { mbfl_no_encoding_8859_9, mbfl_filt_ident_common_ctor, - mbfl_filt_ident_common_dtor, mbfl_filt_ident_true }; diff --git a/ext/mbstring/libmbfl/filters/mbfilter_jis.c b/ext/mbstring/libmbfl/filters/mbfilter_jis.c index 91ed552bcde89..b08eec38b0ab7 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_jis.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_jis.c @@ -61,14 +61,12 @@ const mbfl_encoding mbfl_encoding_2022jp = { const struct mbfl_identify_vtbl vtbl_identify_jis = { mbfl_no_encoding_jis, mbfl_filt_ident_common_ctor, - mbfl_filt_ident_common_dtor, mbfl_filt_ident_jis }; const struct mbfl_identify_vtbl vtbl_identify_2022jp = { mbfl_no_encoding_2022jp, mbfl_filt_ident_common_ctor, - mbfl_filt_ident_common_dtor, mbfl_filt_ident_2022jp }; diff --git a/ext/mbstring/libmbfl/filters/mbfilter_koi8r.c b/ext/mbstring/libmbfl/filters/mbfilter_koi8r.c index 850437710ccf8..7790be65bb937 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_koi8r.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_koi8r.c @@ -49,7 +49,6 @@ const mbfl_encoding mbfl_encoding_koi8r = { const struct mbfl_identify_vtbl vtbl_identify_koi8r = { mbfl_no_encoding_koi8r, mbfl_filt_ident_common_ctor, - mbfl_filt_ident_common_dtor, mbfl_filt_ident_koi8r }; diff --git a/ext/mbstring/libmbfl/filters/mbfilter_koi8u.c b/ext/mbstring/libmbfl/filters/mbfilter_koi8u.c index fe495336cb1eb..a62a1c596b87f 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_koi8u.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_koi8u.c @@ -46,7 +46,6 @@ const mbfl_encoding mbfl_encoding_koi8u = { const struct mbfl_identify_vtbl vtbl_identify_koi8u = { mbfl_no_encoding_koi8u, mbfl_filt_ident_common_ctor, - mbfl_filt_ident_common_dtor, mbfl_filt_ident_koi8u }; diff --git a/ext/mbstring/libmbfl/filters/mbfilter_sjis.c b/ext/mbstring/libmbfl/filters/mbfilter_sjis.c index c6e83913dacfe..dc5c2e4882739 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_sjis.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_sjis.c @@ -73,7 +73,6 @@ const mbfl_encoding mbfl_encoding_sjis = { const struct mbfl_identify_vtbl vtbl_identify_sjis = { mbfl_no_encoding_sjis, mbfl_filt_ident_common_ctor, - mbfl_filt_ident_common_dtor, mbfl_filt_ident_sjis }; diff --git a/ext/mbstring/libmbfl/filters/mbfilter_sjis_2004.c b/ext/mbstring/libmbfl/filters/mbfilter_sjis_2004.c index 93324a4ae730e..04e1d3af17af3 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_sjis_2004.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_sjis_2004.c @@ -55,7 +55,6 @@ const mbfl_encoding mbfl_encoding_sjis2004 = { const struct mbfl_identify_vtbl vtbl_identify_sjis2004 = { mbfl_no_encoding_sjis2004, mbfl_filt_ident_common_ctor, - mbfl_filt_ident_common_dtor, mbfl_filt_ident_sjis }; diff --git a/ext/mbstring/libmbfl/filters/mbfilter_sjis_mac.c b/ext/mbstring/libmbfl/filters/mbfilter_sjis_mac.c index 196ec0a59d0a6..dc3d3692f4e67 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_sjis_mac.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_sjis_mac.c @@ -56,7 +56,6 @@ const mbfl_encoding mbfl_encoding_sjis_mac = { const struct mbfl_identify_vtbl vtbl_identify_sjis_mac = { mbfl_no_encoding_sjis_mac, mbfl_filt_ident_common_ctor, - mbfl_filt_ident_common_dtor, mbfl_filt_ident_sjis }; diff --git a/ext/mbstring/libmbfl/filters/mbfilter_sjis_mobile.c b/ext/mbstring/libmbfl/filters/mbfilter_sjis_mobile.c index ca84faae4782a..68084a0e0a39c 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_sjis_mobile.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_sjis_mobile.c @@ -79,21 +79,18 @@ const mbfl_encoding mbfl_encoding_sjis_sb = { const struct mbfl_identify_vtbl vtbl_identify_sjis_docomo = { mbfl_no_encoding_sjis_docomo, mbfl_filt_ident_common_ctor, - mbfl_filt_ident_common_dtor, mbfl_filt_ident_sjis }; const struct mbfl_identify_vtbl vtbl_identify_sjis_kddi = { mbfl_no_encoding_sjis_kddi, mbfl_filt_ident_common_ctor, - mbfl_filt_ident_common_dtor, mbfl_filt_ident_sjis }; const struct mbfl_identify_vtbl vtbl_identify_sjis_sb = { mbfl_no_encoding_sjis_sb, mbfl_filt_ident_common_ctor, - mbfl_filt_ident_common_dtor, mbfl_filt_ident_sjis }; diff --git a/ext/mbstring/libmbfl/filters/mbfilter_sjis_open.c b/ext/mbstring/libmbfl/filters/mbfilter_sjis_open.c index f8adc5474ea27..2535036e23a1a 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_sjis_open.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_sjis_open.c @@ -70,7 +70,6 @@ const mbfl_encoding mbfl_encoding_sjis_open = { const struct mbfl_identify_vtbl vtbl_identify_sjis_open = { mbfl_no_encoding_sjis_open, mbfl_filt_ident_common_ctor, - mbfl_filt_ident_common_dtor, mbfl_filt_ident_sjis_open }; diff --git a/ext/mbstring/libmbfl/filters/mbfilter_uhc.c b/ext/mbstring/libmbfl/filters/mbfilter_uhc.c index 403fc01081d13..5dc4aa81a98a2 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_uhc.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_uhc.c @@ -69,7 +69,6 @@ const mbfl_encoding mbfl_encoding_uhc = { const struct mbfl_identify_vtbl vtbl_identify_uhc = { mbfl_no_encoding_uhc, mbfl_filt_ident_common_ctor, - mbfl_filt_ident_common_dtor, mbfl_filt_ident_uhc }; diff --git a/ext/mbstring/libmbfl/filters/mbfilter_utf7.c b/ext/mbstring/libmbfl/filters/mbfilter_utf7.c index 744c522807f26..b54bcf2b9ca1f 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_utf7.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_utf7.c @@ -61,7 +61,6 @@ const mbfl_encoding mbfl_encoding_utf7 = { const struct mbfl_identify_vtbl vtbl_identify_utf7 = { mbfl_no_encoding_utf7, mbfl_filt_ident_common_ctor, - mbfl_filt_ident_common_dtor, mbfl_filt_ident_utf7 }; diff --git a/ext/mbstring/libmbfl/filters/mbfilter_utf8.c b/ext/mbstring/libmbfl/filters/mbfilter_utf8.c index 26fd41def1a12..9e97d5b0699c8 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_utf8.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_utf8.c @@ -67,7 +67,6 @@ const mbfl_encoding mbfl_encoding_utf8 = { const struct mbfl_identify_vtbl vtbl_identify_utf8 = { mbfl_no_encoding_utf8, mbfl_filt_ident_common_ctor, - mbfl_filt_ident_common_dtor, mbfl_filt_ident_utf8 }; diff --git a/ext/mbstring/libmbfl/filters/mbfilter_utf8_mobile.c b/ext/mbstring/libmbfl/filters/mbfilter_utf8_mobile.c index 5d23b75d4c5c8..ef8d4cc0759a2 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_utf8_mobile.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_utf8_mobile.c @@ -89,28 +89,24 @@ const mbfl_encoding mbfl_encoding_utf8_sb = { const struct mbfl_identify_vtbl vtbl_identify_utf8_docomo = { mbfl_no_encoding_utf8_docomo, mbfl_filt_ident_common_ctor, - mbfl_filt_ident_common_dtor, mbfl_filt_ident_utf8 }; const struct mbfl_identify_vtbl vtbl_identify_utf8_kddi_a = { mbfl_no_encoding_utf8_kddi_a, mbfl_filt_ident_common_ctor, - mbfl_filt_ident_common_dtor, mbfl_filt_ident_utf8 }; const struct mbfl_identify_vtbl vtbl_identify_utf8_kddi_b = { mbfl_no_encoding_utf8_kddi_b, mbfl_filt_ident_common_ctor, - mbfl_filt_ident_common_dtor, mbfl_filt_ident_utf8 }; const struct mbfl_identify_vtbl vtbl_identify_utf8_sb = { mbfl_no_encoding_utf8_sb, mbfl_filt_ident_common_ctor, - mbfl_filt_ident_common_dtor, mbfl_filt_ident_utf8 }; diff --git a/ext/mbstring/libmbfl/mbfl/mbfilter.c b/ext/mbstring/libmbfl/mbfl/mbfilter.c index b5b760a2bc19e..813b5a6138c65 100644 --- a/ext/mbstring/libmbfl/mbfl/mbfilter.c +++ b/ext/mbstring/libmbfl/mbfl/mbfilter.c @@ -554,13 +554,6 @@ mbfl_identify_encoding(mbfl_string *string, const mbfl_encoding **elist, int eli } } - /* cleanup */ - /* dtors should be called in reverse order */ - i = num; - while (--i >= 0) { - mbfl_identify_filter_cleanup(&flist[i]); - } - efree((void *)flist); return encoding; diff --git a/ext/mbstring/libmbfl/mbfl/mbfl_ident.c b/ext/mbstring/libmbfl/mbfl/mbfl_ident.c index d151f6cc6673f..18144eb030d83 100644 --- a/ext/mbstring/libmbfl/mbfl/mbfl_ident.c +++ b/ext/mbstring/libmbfl/mbfl/mbfl_ident.c @@ -98,9 +98,8 @@ static const struct mbfl_identify_vtbl vtbl_identify_false = { mbfl_no_encoding_pass, mbfl_filt_ident_false_ctor, - mbfl_filt_ident_common_dtor, - mbfl_filt_ident_false }; - + mbfl_filt_ident_false +}; static const struct mbfl_identify_vtbl *mbfl_identify_filter_list[] = { &vtbl_identify_utf8, @@ -164,8 +163,6 @@ static const struct mbfl_identify_vtbl *mbfl_identify_filter_list[] = { NULL }; - - /* * identify filter */ @@ -230,7 +227,6 @@ int mbfl_identify_filter_init2(mbfl_identify_filter *filter, const mbfl_encoding vtbl = &vtbl_identify_false; } filter->filter_ctor = vtbl->filter_ctor; - filter->filter_dtor = vtbl->filter_dtor; filter->filter_function = vtbl->filter_function; /* constructor */ @@ -245,26 +241,15 @@ void mbfl_identify_filter_delete(mbfl_identify_filter *filter) return; } - mbfl_identify_filter_cleanup(filter); efree((void*)filter); } -void mbfl_identify_filter_cleanup(mbfl_identify_filter *filter) -{ - (*filter->filter_dtor)(filter); -} - void mbfl_filt_ident_common_ctor(mbfl_identify_filter *filter) { filter->status = 0; filter->flag = 0; } -void mbfl_filt_ident_common_dtor(mbfl_identify_filter *filter) -{ - filter->status = 0; -} - int mbfl_filt_ident_false(int c, mbfl_identify_filter *filter) { filter->flag = 1; /* bad */ diff --git a/ext/mbstring/libmbfl/mbfl/mbfl_ident.h b/ext/mbstring/libmbfl/mbfl/mbfl_ident.h index 238132f6a775c..c9afd03fb4d98 100644 --- a/ext/mbstring/libmbfl/mbfl/mbfl_ident.h +++ b/ext/mbstring/libmbfl/mbfl/mbfl_ident.h @@ -41,7 +41,6 @@ typedef struct _mbfl_identify_filter mbfl_identify_filter; struct _mbfl_identify_filter { void (*filter_ctor)(mbfl_identify_filter *filter); - void (*filter_dtor)(mbfl_identify_filter *filter); int (*filter_function)(int c, mbfl_identify_filter *filter); int status; int flag; @@ -52,7 +51,6 @@ struct _mbfl_identify_filter { struct mbfl_identify_vtbl { enum mbfl_no_encoding encoding; void (*filter_ctor)(mbfl_identify_filter *filter); - void (*filter_dtor)(mbfl_identify_filter *filter); int (*filter_function)(int c, mbfl_identify_filter *filter); }; @@ -62,10 +60,8 @@ MBFLAPI extern mbfl_identify_filter * mbfl_identify_filter_new2(const mbfl_encod MBFLAPI extern void mbfl_identify_filter_delete(mbfl_identify_filter *filter); MBFLAPI extern int mbfl_identify_filter_init(mbfl_identify_filter *filter, enum mbfl_no_encoding encoding); MBFLAPI extern int mbfl_identify_filter_init2(mbfl_identify_filter *filter, const mbfl_encoding *encoding); -MBFLAPI void mbfl_identify_filter_cleanup(mbfl_identify_filter *filter); MBFLAPI extern void mbfl_filt_ident_common_ctor(mbfl_identify_filter *filter); -MBFLAPI extern void mbfl_filt_ident_common_dtor(mbfl_identify_filter *filter); MBFLAPI extern void mbfl_filt_ident_false_ctor(mbfl_identify_filter *filter); MBFLAPI extern int mbfl_filt_ident_false(int c, mbfl_identify_filter *filter); From f699d65391dd216cb35f9c8248109323a723951f Mon Sep 17 00:00:00 2001 From: Alex Dowad Date: Fri, 17 Jul 2020 22:36:39 +0200 Subject: [PATCH 43/87] Add comment to mbfilter_tl_jisx0201_jisx0208.h Explain the 'ZEN' and 'HAN' in symbolic constant names. --- ext/mbstring/libmbfl/filters/mbfilter_tl_jisx0201_jisx0208.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ext/mbstring/libmbfl/filters/mbfilter_tl_jisx0201_jisx0208.h b/ext/mbstring/libmbfl/filters/mbfilter_tl_jisx0201_jisx0208.h index 922eee168aaff..13a3f11182a92 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_tl_jisx0201_jisx0208.h +++ b/ext/mbstring/libmbfl/filters/mbfilter_tl_jisx0201_jisx0208.h @@ -27,6 +27,8 @@ #include "mbfl_convert.h" +/* "Zen" is 全, or "full"; "Han" is 半, or "half" + * This refers to "fullwidth" or "halfwidth" variants of characters used for writing Japanese */ #define MBFL_FILT_TL_HAN2ZEN_ALL 0x00000001 #define MBFL_FILT_TL_HAN2ZEN_ALPHA 0x00000002 #define MBFL_FILT_TL_HAN2ZEN_NUMERIC 0x00000004 From ec609916dcdef472750a7bc25f9998e3fae99123 Mon Sep 17 00:00:00 2001 From: Alex Dowad Date: Tue, 28 Jul 2020 23:30:16 +0200 Subject: [PATCH 44/87] Remove unused 'from' field from mbfl_buffer_converter struct --- ext/mbstring/libmbfl/mbfl/mbfilter.c | 9 ++++----- ext/mbstring/libmbfl/mbfl/mbfilter.h | 1 - 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/ext/mbstring/libmbfl/mbfl/mbfilter.c b/ext/mbstring/libmbfl/mbfl/mbfilter.c index 813b5a6138c65..755b06871c2c0 100644 --- a/ext/mbstring/libmbfl/mbfl/mbfilter.c +++ b/ext/mbstring/libmbfl/mbfl/mbfilter.c @@ -117,18 +117,17 @@ mbfl_buffer_converter_new( size_t buf_initsz) { mbfl_buffer_converter *convd = emalloc(sizeof(mbfl_buffer_converter)); - convd->from = from; convd->to = to; /* create convert filter */ convd->filter1 = NULL; convd->filter2 = NULL; - if (mbfl_convert_filter_get_vtbl(convd->from, convd->to) != NULL) { - convd->filter1 = mbfl_convert_filter_new(convd->from, convd->to, mbfl_memory_device_output, NULL, &convd->device); + if (mbfl_convert_filter_get_vtbl(from, to) != NULL) { + convd->filter1 = mbfl_convert_filter_new(from, to, mbfl_memory_device_output, NULL, &convd->device); } else { - convd->filter2 = mbfl_convert_filter_new(&mbfl_encoding_wchar, convd->to, mbfl_memory_device_output, NULL, &convd->device); + convd->filter2 = mbfl_convert_filter_new(&mbfl_encoding_wchar, to, mbfl_memory_device_output, NULL, &convd->device); if (convd->filter2 != NULL) { - convd->filter1 = mbfl_convert_filter_new(convd->from, + convd->filter1 = mbfl_convert_filter_new(from, &mbfl_encoding_wchar, (int (*)(int, void*))convd->filter2->filter_function, convd->filter2->filter_flush, diff --git a/ext/mbstring/libmbfl/mbfl/mbfilter.h b/ext/mbstring/libmbfl/mbfl/mbfilter.h index c57d0eac9faf2..16742be96c3da 100644 --- a/ext/mbstring/libmbfl/mbfl/mbfilter.h +++ b/ext/mbstring/libmbfl/mbfl/mbfilter.h @@ -137,7 +137,6 @@ struct _mbfl_buffer_converter { mbfl_convert_filter *filter1; mbfl_convert_filter *filter2; mbfl_memory_device device; - const mbfl_encoding *from; const mbfl_encoding *to; }; From a81061d36c6df35f683d8b063ce7b717868fda74 Mon Sep 17 00:00:00 2001 From: Alex Dowad Date: Fri, 7 Aug 2020 22:29:21 +0200 Subject: [PATCH 45/87] Use symbolic constants in Japanese kana conversion code (not magic numbers) Also correct misspelling of 'hiragana' as 'hirangana' at the same time. --- .../filters/mbfilter_tl_jisx0201_jisx0208.c | 29 ++++++++++--------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/ext/mbstring/libmbfl/filters/mbfilter_tl_jisx0201_jisx0208.c b/ext/mbstring/libmbfl/filters/mbfilter_tl_jisx0201_jisx0208.c index 6831c2d2e7660..9ab3415d15e94 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_tl_jisx0201_jisx0208.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_tl_jisx0201_jisx0208.c @@ -93,7 +93,7 @@ mbfl_filt_tl_jisx0201_jisx0208(int c, mbfl_convert_filter *filt) } } else if ((mode & MBFL_FILT_TL_HAN2ZEN_HIRAGANA) && (mode & MBFL_FILT_TL_HAN2ZEN_GLUE)) { - /* hankaku kana to zenkaku hirangana and glue voiced sound mark */ + /* hankaku kana to zenkaku hiragana and glue voiced sound mark */ if (c >= 0xff61 && c <= 0xff9f) { if (filt->status) { n = (filt->cache - 0xff60) & 0x3f; @@ -126,7 +126,7 @@ mbfl_filt_tl_jisx0201_jisx0208(int c, mbfl_convert_filter *filt) s = 0x3000 + hankana2zenkana_table[c - 0xff60]; } else if ((mode & MBFL_FILT_TL_HAN2ZEN_HIRAGANA) && c >= 0xff61 && c <= 0xff9f) { - /* hankaku kana to zenkaku hirangana */ + /* hankaku kana to zenkaku hiragana */ s = 0x3000 + hankana2zenhira_table[c - 0xff60]; } } @@ -159,16 +159,19 @@ mbfl_filt_tl_jisx0201_jisx0208(int c, mbfl_convert_filter *filt) } } - if (mode & 0xf0) { /* zenkaku to hankaku */ - if ((mode & 0x10) && c >= 0xff01 && c <= 0xff5d && c != 0xff02 && c != 0xff07 && c!= 0xff3c) { /* all except <"> <'> <\> <~> */ + if (mode & (MBFL_FILT_TL_ZEN2HAN_ALL | MBFL_FILT_TL_ZEN2HAN_ALPHA | MBFL_FILT_TL_ZEN2HAN_NUMERIC | MBFL_FILT_TL_ZEN2HAN_SPACE)) { + /* Zenkaku to Hankaku */ + if ((mode & MBFL_FILT_TL_ZEN2HAN_ALL) && c >= 0xff01 && c <= 0xff5d && c != 0xff02 && c != 0xff07 && c!= 0xff3c) { + /* all except <"> <'> <\> <~> */ s = c - 0xfee0; - } else if ((mode & 0x20) && ((c >= 0xff21 && c <= 0xff3a) || (c >= 0xff41 && c <= 0xff5a))) { /* alpha */ + } else if ((mode & MBFL_FILT_TL_ZEN2HAN_ALPHA) && ((c >= 0xff21 && c <= 0xff3a) || (c >= 0xff41 && c <= 0xff5a))) { s = c - 0xfee0; - } else if ((mode & 0x40) && (c >= 0xff10 && c <= 0xff19)) { /* num */ + } else if ((mode & MBFL_FILT_TL_ZEN2HAN_NUMERIC) && (c >= 0xff10 && c <= 0xff19)) { s = c - 0xfee0; - } else if ((mode & 0x80) && (c == 0x3000)) { /* spase */ + } else if ((mode & MBFL_FILT_TL_ZEN2HAN_SPACE) && (c == 0x3000)) { s = 0x20; - } else if ((mode & 0x10) && (c == 0x2212)) { /* MINUS SIGN */ + } else if ((mode & MBFL_FILT_TL_ZEN2HAN_ALL) && (c == 0x2212)) { + /* MINUS SIGN */ s = 0x2d; } } @@ -188,7 +191,7 @@ mbfl_filt_tl_jisx0201_jisx0208(int c, mbfl_convert_filter *filt) } } else if ((mode & MBFL_FILT_TL_ZEN2HAN_HIRAGANA) && c >= 0x3041 && c <= 0x3093) { - /* Zenkaku hirangana to hankaku kana */ + /* Zenkaku hiragana to hankaku kana */ n = c - 0x3041; if (zenkana2hankana_table[n][1] != 0) { (filt->output_function)(0xff00 + zenkana2hankana_table[n][0], filt->data); @@ -217,11 +220,11 @@ mbfl_filt_tl_jisx0201_jisx0208(int c, mbfl_convert_filter *filt) | MBFL_FILT_TL_ZEN2HAN_KANA2HIRA)) { if ((mode & MBFL_FILT_TL_ZEN2HAN_HIRA2KANA) && ((c >= 0x3041 && c <= 0x3093) || c == 0x309d || c == 0x309e)) { - /* Zenkaku hirangana to Zenkaku katakana */ + /* Zenkaku hiragana to Zenkaku katakana */ s = c + 0x60; } else if ((mode & MBFL_FILT_TL_ZEN2HAN_KANA2HIRA) && ((c >= 0x30a1 && c <= 0x30f3) || c == 0x30fd || c == 0x30fe)) { - /* Zenkaku katakana to Zenkaku hirangana */ + /* Zenkaku katakana to Zenkaku hiragana */ s = c - 0x60; } } @@ -270,9 +273,9 @@ mbfl_filt_tl_jisx0201_jisx0208_flush(mbfl_convert_filter *filt) ret = 0; if (filt->status) { n = (filt->cache - 0xff60) & 0x3f; - if (mode & 0x100) { /* hankaku kana to zenkaku katakana */ + if (mode & MBFL_FILT_TL_HAN2ZEN_KATAKANA) { /* hankaku kana to zenkaku katakana */ ret = (*filt->output_function)(0x3000 + hankana2zenkana_table[n], filt->data); - } else if (mode & 0x200) { /* hankaku kana to zenkaku hirangana */ + } else if (mode & MBFL_FILT_TL_HAN2ZEN_HIRAGANA) { /* hankaku kana to zenkaku hiragana */ ret = (*filt->output_function)(0x3000 + hankana2zenhira_table[n], filt->data); } filt->status = 0; From 9dc953463769e16d1705a112c3c8bb82dbd2c9a5 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Thu, 3 Sep 2020 17:12:23 +0300 Subject: [PATCH 46/87] If we don't know the return address, just escape to VM, instead of adding side exit. Remove unnecessary exception checks. --- ext/opcache/jit/zend_jit.c | 2 +- ext/opcache/jit/zend_jit_trace.c | 3 ++- ext/opcache/jit/zend_jit_x86.dasc | 43 +++++++++++++++---------------- 3 files changed, 24 insertions(+), 24 deletions(-) diff --git a/ext/opcache/jit/zend_jit.c b/ext/opcache/jit/zend_jit.c index 7900130bb6e80..92c499e349ef0 100644 --- a/ext/opcache/jit/zend_jit.c +++ b/ext/opcache/jit/zend_jit.c @@ -2740,7 +2740,7 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op } } } - if (!zend_jit_leave_func(&dasm_state, op_array, NULL, NULL, + if (!zend_jit_leave_func(&dasm_state, op_array, opline, op1_info, NULL, NULL, (ssa->cfg.flags & ZEND_FUNC_INDIRECT_VAR_ACCESS) != 0, 1)) { goto jit_failure; } diff --git a/ext/opcache/jit/zend_jit_trace.c b/ext/opcache/jit/zend_jit_trace.c index 5834cbe0e55a6..408e540e0fe88 100644 --- a/ext/opcache/jit/zend_jit_trace.c +++ b/ext/opcache/jit/zend_jit_trace.c @@ -4076,7 +4076,8 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par } } } - if (!zend_jit_leave_func(&dasm_state, op_array, p + 1, &zend_jit_traces[ZEND_JIT_TRACE_NUM], + if (!zend_jit_leave_func(&dasm_state, op_array, opline, op1_info, + p + 1, &zend_jit_traces[ZEND_JIT_TRACE_NUM], (op_array_ssa->cfg.flags & ZEND_FUNC_INDIRECT_VAR_ACCESS) != 0, may_throw)) { goto jit_failure; } diff --git a/ext/opcache/jit/zend_jit_x86.dasc b/ext/opcache/jit/zend_jit_x86.dasc index 74449877ac5fb..58149c902932a 100644 --- a/ext/opcache/jit/zend_jit_x86.dasc +++ b/ext/opcache/jit/zend_jit_x86.dasc @@ -10194,7 +10194,7 @@ static int zend_jit_free_op(dasm_State **Dst, const zend_op *opline, uint32_t in return 1; } -static int zend_jit_leave_func(dasm_State **Dst, const zend_op_array *op_array, zend_jit_trace_rec *trace, zend_jit_trace_info *trace_info, int indirect_var_access, int may_throw) +static int zend_jit_leave_func(dasm_State **Dst, const zend_op_array *op_array, const zend_op *opline, uint32_t op1_info, zend_jit_trace_rec *trace, zend_jit_trace_info *trace_info, int indirect_var_access, int may_throw) { zend_bool may_be_top_frame = JIT_G(trigger) != ZEND_JIT_ON_HOT_TRACE || @@ -10293,50 +10293,49 @@ static int zend_jit_leave_func(dasm_State **Dst, const zend_op_array *op_array, |8: - if ((trace->op != ZEND_JIT_TRACE_END || - trace->stop != ZEND_JIT_TRACE_STOP_RECURSIVE_RET) && - may_throw) { - | // if (EG(exception)) - | MEM_OP2_1_ZTS cmp, aword, executor_globals, exception, 0, r0 - | jne ->leave_throw_handler - } - if (trace->op == ZEND_JIT_TRACE_BACK && (!JIT_G(current_frame) || TRACE_FRAME_IS_UNKNOWN_RETURN(JIT_G(current_frame)))) { const zend_op *next_opline = trace->opline; - uint32_t exit_point; - const void *exit_addr; - zend_jit_trace_stack_frame *current_frame; + if ((opline->op1_type & (IS_VAR|IS_TMP_VAR)) + && (op1_info & MAY_BE_RC1) + && (op1_info & (MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_ARRAY_OF_OBJECT|MAY_BE_ARRAY_OF_RESOURCE|MAY_BE_ARRAY_OF_ARRAY))) { + /* exception might be thrown during destruction of unused return value */ + | // if (EG(exception)) + | MEM_OP2_1_ZTS cmp, aword, executor_globals, exception, 0, r0 + | jne ->leave_throw_handler + } do { trace++; } while (trace->op == ZEND_JIT_TRACE_INIT_CALL); ZEND_ASSERT(trace->op == ZEND_JIT_TRACE_VM || trace->op == ZEND_JIT_TRACE_END); next_opline = trace->opline; ZEND_ASSERT(next_opline != NULL); - current_frame = JIT_G(current_frame); - JIT_G(current_frame) = NULL; - exit_point = zend_jit_trace_get_exit_point(NULL, 0); - JIT_G(current_frame) = current_frame; - exit_addr = zend_jit_trace_get_exit_addr(exit_point); - if (!exit_addr) { - return 0; - } + if (trace->op == ZEND_JIT_TRACE_END && trace->stop == ZEND_JIT_TRACE_STOP_RECURSIVE_RET) { trace_info->flags |= ZEND_JIT_TRACE_LOOP; | CMP_IP next_opline | je =>0 // LOOP - | jmp &exit_addr + | jmp ->trace_escape } else { | CMP_IP next_opline - | jne &exit_addr + | jne ->trace_escape } last_valid_opline = trace->opline; return 1; + } else if (may_throw || + (((opline->op1_type & (IS_VAR|IS_TMP_VAR)) + && (op1_info & MAY_BE_RC1) + && (op1_info & (MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_ARRAY_OF_OBJECT|MAY_BE_ARRAY_OF_RESOURCE|MAY_BE_ARRAY_OF_ARRAY))) + && (!JIT_G(current_frame) || TRACE_FRAME_IS_RETURN_VALUE_UNUSED(JIT_G(current_frame))))) { + | // if (EG(exception)) + | MEM_OP2_1_ZTS cmp, aword, executor_globals, exception, 0, r0 + | jne ->leave_throw_handler } + return 1; } else { | // if (EG(exception)) From 46a49be6c866103ebcb95e03b2b96460bec16b7b Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Thu, 3 Sep 2020 17:10:34 +0200 Subject: [PATCH 47/87] Fixed bug #80049 Type checking may convert to refcounted values, so force freeing of extra args. --- NEWS | 2 ++ Zend/tests/bug80049.phpt | 14 ++++++++++++++ Zend/zend_vm_def.h | 1 + Zend/zend_vm_execute.h | 1 + 4 files changed, 18 insertions(+) create mode 100644 Zend/tests/bug80049.phpt diff --git a/NEWS b/NEWS index 0800e83e0f934..d3e4060478335 100644 --- a/NEWS +++ b/NEWS @@ -4,6 +4,8 @@ PHP NEWS - Core: . Fixed bug #80048 (Bug #69100 has not been fixed for Windows). (cmb) + . Fixed bug #80049 (Memleak when coercing integers to string via variadic + argument). (Nikita) - Calendar: . Fixed bug #80007 (Potential type confusion in unixtojd() parameter parsing). diff --git a/Zend/tests/bug80049.phpt b/Zend/tests/bug80049.phpt new file mode 100644 index 0000000000000..852b71feaab12 --- /dev/null +++ b/Zend/tests/bug80049.phpt @@ -0,0 +1,14 @@ +--TEST-- +Bug #80049: Memleak when coercing integers to string via variadic argument +--FILE-- + +--EXPECT-- +array(1) { + [0]=> + string(3) "123" +} diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 70e33039da0cb..6f9aca4b55166 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -4819,6 +4819,7 @@ ZEND_VM_HANDLER(164, ZEND_RECV_VARIADIC, NUM, UNUSED|CACHE_SLOT) ZEND_HASH_FILL_PACKED(Z_ARRVAL_P(params)) { param = EX_VAR_NUM(EX(func)->op_array.last_var + EX(func)->op_array.T); if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0)) { + ZEND_ADD_CALL_FLAG(execute_data, ZEND_CALL_FREE_EXTRA_ARGS); do { zend_verify_arg_type(EX(func), arg_num, param, NULL, CACHE_ADDR(opline->op2.num)); if (Z_OPT_REFCOUNTED_P(param)) Z_ADDREF_P(param); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 9d7515e9d0527..e5e5a9e1da89e 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -2375,6 +2375,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RECV_VARIADIC_SPEC_UNUSED_HAND ZEND_HASH_FILL_PACKED(Z_ARRVAL_P(params)) { param = EX_VAR_NUM(EX(func)->op_array.last_var + EX(func)->op_array.T); if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0)) { + ZEND_ADD_CALL_FLAG(execute_data, ZEND_CALL_FREE_EXTRA_ARGS); do { zend_verify_arg_type(EX(func), arg_num, param, NULL, CACHE_ADDR(opline->op2.num)); if (Z_OPT_REFCOUNTED_P(param)) Z_ADDREF_P(param); From 4a438b44694d4caf86d8e57266ed2fc2f4ae6213 Mon Sep 17 00:00:00 2001 From: George Peter Banyard Date: Thu, 3 Sep 2020 17:43:57 +0200 Subject: [PATCH 48/87] Warning to Error promotion in ext/standard Those should be the last ones other than set(raw)cookie() Closes GH-5814 --- ext/standard/basic_functions.c | 4 +-- ext/standard/dns.c | 21 +++++++-------- ext/standard/exec.c | 16 ++++++------ ext/standard/ftok.c | 4 +-- ext/standard/iptc.c | 4 +-- ext/standard/streamsfuncs.c | 4 +-- ext/standard/tests/misc/exec_basic1.phpt | 33 ++++++++++++++---------- ext/standard/tests/network/bug68925.phpt | 4 +-- ext/standard/user_filters.c | 6 +---- ext/sysvshm/tests/001.phpt | 10 ++++--- 10 files changed, 54 insertions(+), 52 deletions(-) diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c index 7051e4a456b8e..6ff4c3d573f34 100755 --- a/ext/standard/basic_functions.c +++ b/ext/standard/basic_functions.c @@ -2647,8 +2647,8 @@ PHP_FUNCTION(parse_ini_file) ZEND_PARSE_PARAMETERS_END(); if (filename_len == 0) { - php_error_docref(NULL, E_WARNING, "Filename cannot be empty!"); - RETURN_FALSE; + zend_argument_value_error(1, "cannot be empty"); + RETURN_THROWS(); } /* Set callback function */ diff --git a/ext/standard/dns.c b/ext/standard/dns.c index cb45eeebf3f78..42bc93c41a34a 100644 --- a/ext/standard/dns.c +++ b/ext/standard/dns.c @@ -210,9 +210,9 @@ PHP_FUNCTION(gethostbyname) Z_PARAM_STRING(hostname, hostname_len) ZEND_PARSE_PARAMETERS_END(); - if(hostname_len > MAXFQDNLEN) { + if (hostname_len > MAXFQDNLEN) { /* name too long, protect from CVE-2015-0235 */ - php_error_docref(NULL, E_WARNING, "Host name is too long, the limit is %d characters", MAXFQDNLEN); + php_error_docref(NULL, E_WARNING, "Host name cannot be longer than %d characters", MAXFQDNLEN); RETURN_STRINGL(hostname, hostname_len); } @@ -233,9 +233,9 @@ PHP_FUNCTION(gethostbynamel) Z_PARAM_STRING(hostname, hostname_len) ZEND_PARSE_PARAMETERS_END(); - if(hostname_len > MAXFQDNLEN) { + if (hostname_len > MAXFQDNLEN) { /* name too long, protect from CVE-2015-0235 */ - php_error_docref(NULL, E_WARNING, "Host name is too long, the limit is %d characters", MAXFQDNLEN); + php_error_docref(NULL, E_WARNING, "Host name cannot be longer than %d characters", MAXFQDNLEN); RETURN_FALSE; } @@ -393,8 +393,8 @@ PHP_FUNCTION(dns_check_record) else if (!strcasecmp("NAPTR", rectype)) type = DNS_T_NAPTR; else if (!strcasecmp("A6", rectype)) type = DNS_T_A6; else { - php_error_docref(NULL, E_WARNING, "Type '%s' not supported", rectype); - RETURN_FALSE; + zend_argument_value_error(2, "must be a valid DNS record type"); + RETURN_THROWS(); } } @@ -837,14 +837,13 @@ PHP_FUNCTION(dns_get_record) if (!raw) { if ((type_param & ~PHP_DNS_ALL) && (type_param != PHP_DNS_ANY)) { - php_error_docref(NULL, E_WARNING, "Type '" ZEND_LONG_FMT "' not supported", type_param); - RETURN_FALSE; + zend_argument_value_error(2, "must be a DNS_* constant"); + RETURN_THROWS(); } } else { if ((type_param < 1) || (type_param > 0xFFFF)) { - php_error_docref(NULL, E_WARNING, - "Numeric DNS record type must be between 1 and 65535, '" ZEND_LONG_FMT "' given", type_param); - RETURN_FALSE; + zend_argument_value_error(2, "must be between 1 and 65535 when argument #5 ($raw) is true"); + RETURN_THROWS(); } } diff --git a/ext/standard/exec.c b/ext/standard/exec.c index 81135669f5e9f..0be8df28e82f8 100644 --- a/ext/standard/exec.c +++ b/ext/standard/exec.c @@ -220,12 +220,12 @@ static void php_exec_ex(INTERNAL_FUNCTION_PARAMETERS, int mode) /* {{{ */ ZEND_PARSE_PARAMETERS_END(); if (!cmd_len) { - php_error_docref(NULL, E_WARNING, "Cannot execute a blank command"); - RETURN_FALSE; + zend_argument_value_error(1, "cannot be empty"); + RETURN_THROWS(); } if (strlen(cmd) != cmd_len) { - php_error_docref(NULL, E_WARNING, "NULL byte detected. Possible attack"); - RETURN_FALSE; + zend_argument_type_error(1, "must not contain any null bytes"); + RETURN_THROWS(); } if (!ret_array) { @@ -523,12 +523,12 @@ PHP_FUNCTION(shell_exec) ZEND_PARSE_PARAMETERS_END(); if (!command_len) { - php_error_docref(NULL, E_WARNING, "Cannot execute a blank command"); - RETURN_FALSE; + zend_argument_value_error(1, "cannot be empty"); + RETURN_THROWS(); } if (strlen(command) != command_len) { - php_error_docref(NULL, E_WARNING, "NULL byte detected. Possible attack"); - RETURN_FALSE; + zend_argument_type_error(1, "must not contain any null bytes"); + RETURN_THROWS(); } #ifdef PHP_WIN32 diff --git a/ext/standard/ftok.c b/ext/standard/ftok.c index 616890d283b2c..04830fb6df623 100644 --- a/ext/standard/ftok.c +++ b/ext/standard/ftok.c @@ -40,8 +40,8 @@ PHP_FUNCTION(ftok) ZEND_PARSE_PARAMETERS_END(); if (pathname_len == 0){ - php_error_docref(NULL, E_WARNING, "Pathname is invalid"); - RETURN_LONG(-1); + zend_argument_value_error(1, "cannot be empty"); + RETURN_THROWS(); } if (proj_len != 1){ diff --git a/ext/standard/iptc.c b/ext/standard/iptc.c index d7d7729db88c1..6e9df19c30065 100644 --- a/ext/standard/iptc.c +++ b/ext/standard/iptc.c @@ -193,8 +193,8 @@ PHP_FUNCTION(iptcembed) } if (iptcdata_len >= SIZE_MAX - sizeof(psheader) - 1025) { - php_error_docref(NULL, E_WARNING, "IPTC data too large"); - RETURN_FALSE; + zend_argument_value_error(1, "is too large"); + RETURN_THROWS(); } if ((fp = VCWD_FOPEN(jpeg_file, "rb")) == 0) { diff --git a/ext/standard/streamsfuncs.c b/ext/standard/streamsfuncs.c index affe637e047d7..0bc475498f396 100644 --- a/ext/standard/streamsfuncs.c +++ b/ext/standard/streamsfuncs.c @@ -1698,8 +1698,8 @@ PHP_FUNCTION(stream_socket_shutdown) if (how != STREAM_SHUT_RD && how != STREAM_SHUT_WR && how != STREAM_SHUT_RDWR) { - php_error_docref(NULL, E_WARNING, "Second parameter $how needs to be one of STREAM_SHUT_RD, STREAM_SHUT_WR or STREAM_SHUT_RDWR"); - RETURN_FALSE; + zend_argument_value_error(2, "must be one of STREAM_SHUT_RD, STREAM_SHUT_WR, or STREAM_SHUT_RDWR"); + RETURN_THROWS(); } php_stream_from_zval(stream, zstream); diff --git a/ext/standard/tests/misc/exec_basic1.phpt b/ext/standard/tests/misc/exec_basic1.phpt index 514c116d6853c..61e057b728b3c 100644 --- a/ext/standard/tests/misc/exec_basic1.phpt +++ b/ext/standard/tests/misc/exec_basic1.phpt @@ -8,18 +8,23 @@ exec, system, passthru — Basic command execution functions --FILE-- getMessage() . \PHP_EOL; +} +try { + var_dump(system($cmd, $output)); +} catch (\TypeError $e) { + echo $e->getMessage() . \PHP_EOL; +} +try { + var_dump(passthru($cmd, $output)); +} catch (\TypeError $e) { + echo $e->getMessage() . \PHP_EOL; +} ?> ---EXPECTF-- -Warning: exec(): NULL byte detected. Possible attack in %s on line %d -bool(false) -NULL - -Warning: system(): NULL byte detected. Possible attack in %s on line %d -bool(false) - -Warning: passthru(): NULL byte detected. Possible attack in %s on line %d -bool(false) +--EXPECT-- +exec(): Argument #1 ($command) must not contain any null bytes +system(): Argument #1 ($command) must not contain any null bytes +passthru(): Argument #1 ($command) must not contain any null bytes diff --git a/ext/standard/tests/network/bug68925.phpt b/ext/standard/tests/network/bug68925.phpt index 764e13e0eda38..fc097e25fb301 100644 --- a/ext/standard/tests/network/bug68925.phpt +++ b/ext/standard/tests/network/bug68925.phpt @@ -6,8 +6,8 @@ var_dump(gethostbyname(str_repeat("0", 2501))); var_dump(gethostbynamel(str_repeat("0", 2501))); ?> --EXPECTF-- -Warning: gethostbyname(): Host name is too long, the limit is %d characters in %s%ebug68925.php on line %d +Warning: gethostbyname(): Host name cannot be longer than %d characters in %s%ebug68925.php on line %d string(2501) "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" -Warning: gethostbynamel(): Host name is too long, the limit is %d characters in %s%ebug68925.php on line %d +Warning: gethostbynamel(): Host name cannot be longer than %d characters in %s%ebug68925.php on line %d bool(false) diff --git a/ext/standard/user_filters.c b/ext/standard/user_filters.c index e60bce56be70f..7c8e02fa28f37 100644 --- a/ext/standard/user_filters.c +++ b/ext/standard/user_filters.c @@ -299,11 +299,7 @@ static php_stream_filter *user_filter_factory_create(const char *filtername, } efree(wildcard); } - if (fdat == NULL) { - php_error_docref(NULL, E_WARNING, - "Err, filter \"%s\" is not in the user-filter map, but somehow the user-filter-factory was invoked for it!?", filtername); - return NULL; - } + ZEND_ASSERT(fdat); } /* bind the classname to the actual class */ diff --git a/ext/sysvshm/tests/001.phpt b/ext/sysvshm/tests/001.phpt index 55d5444b98c1e..106f6699ee87a 100644 --- a/ext/sysvshm/tests/001.phpt +++ b/ext/sysvshm/tests/001.phpt @@ -7,8 +7,11 @@ if (!function_exists('ftok')){ print 'skip'; } ?> --FILE-- getMessage() . \PHP_EOL; +} var_dump(ftok(-1, -1)); var_dump(ftok("qwertyu","qwertyu")); @@ -19,8 +22,7 @@ var_dump(ftok(__FILE__,"q")); echo "Done\n"; ?> --EXPECTF-- -Warning: ftok(): Pathname is invalid in %s on line %d -int(-1) +ftok(): Argument #1 ($pathname) cannot be empty Warning: ftok(): Project identifier is invalid in %s on line %d int(-1) From 61c299fe9c0b0d274989c880c9c74fd57c462206 Mon Sep 17 00:00:00 2001 From: George Peter Banyard Date: Thu, 3 Sep 2020 17:17:46 +0200 Subject: [PATCH 49/87] Error promotions in SPL Warning to Error promotion and a Notice to Warning promotion to align with the behaviour specified in the Reclassify Engine Warnings RFC. Closes GH-6072 --- ext/spl/spl_array.c | 6 +++--- ext/spl/spl_directory.c | 19 ++++++++++++------- ext/spl/spl_dllist.c | 5 ++--- ext/spl/spl_fixedarray.c | 4 +--- ext/spl/spl_heap.c | 4 +--- ext/spl/spl_iterators.c | 6 +++--- ext/spl/tests/bug61828.phpt | 14 +++++++++----- ext/spl/tests/bug65545.phpt | 14 ++++++++------ ext/spl/tests/iterator_044.phpt | 16 ++++++++-------- 9 files changed, 47 insertions(+), 41 deletions(-) diff --git a/ext/spl/spl_array.c b/ext/spl/spl_array.c index 5beddc3391929..ce468267d089a 100644 --- a/ext/spl/spl_array.c +++ b/ext/spl/spl_array.c @@ -204,9 +204,9 @@ static zend_object *spl_array_object_new_ex(zend_class_entry *class_type, zend_o parent = parent->parent; inherited = 1; } - if (!parent) { /* this must never happen */ - php_error_docref(NULL, E_COMPILE_ERROR, "Internal compiler error, Class is not child of ArrayObject or ArrayIterator"); - } + + ZEND_ASSERT(parent); + if (inherited) { intern->fptr_offset_get = zend_hash_str_find_ptr(&class_type->function_table, "offsetget", sizeof("offsetget") - 1); if (intern->fptr_offset_get->common.scope == parent) { diff --git a/ext/spl/spl_directory.c b/ext/spl/spl_directory.c index e7bc262da5236..e782b1e70a462 100644 --- a/ext/spl/spl_directory.c +++ b/ext/spl/spl_directory.c @@ -732,7 +732,7 @@ void spl_filesystem_object_construct(INTERNAL_FUNCTION_PARAMETERS, zend_long cto intern = Z_SPLFILESYSTEM_P(ZEND_THIS); if (intern->_path) { /* object is already initialized */ - php_error_docref(NULL, E_WARNING, "Directory object is already initialized"); + zend_throw_error(NULL, "Directory object is already initialized"); return; } intern->flags = flags; @@ -1232,10 +1232,10 @@ PHP_METHOD(SplFileInfo, getLinkTarget) } #if defined(PHP_WIN32) || defined(HAVE_SYMLINK) if (intern->file_name == NULL) { - zend_restore_error_handling(&error_handling); - php_error_docref(NULL, E_WARNING, "Empty filename"); - RETURN_FALSE; - } else if (!IS_ABSOLUTE_PATH(intern->file_name, intern->file_name_len)) { + zend_value_error("Filename cannot be empty"); + RETURN_THROWS(); + } + if (!IS_ABSOLUTE_PATH(intern->file_name, intern->file_name_len)) { char expanded_path[MAXPATHLEN]; if (!expand_filepath_with_mode(intern->file_name, expanded_path, NULL, 0, CWD_EXPAND )) { zend_restore_error_handling(&error_handling); @@ -1577,6 +1577,7 @@ PHP_METHOD(GlobIterator, count) RETURN_LONG(php_glob_stream_get_count(intern->u.dir.dirp, NULL)); } else { /* should not happen */ + // TODO ZEND_ASSERT ? php_error_docref(NULL, E_ERROR, "GlobIterator lost glob state"); } } @@ -2330,6 +2331,7 @@ PHP_METHOD(SplFileObject, fgetcsv) CHECK_SPL_FILE_OBJECT_IS_INITIALIZED(intern); + // TODO Align behaviour on normal fgetcsv() switch(ZEND_NUM_ARGS()) { case 3: @@ -2377,6 +2379,8 @@ PHP_METHOD(SplFileObject, fputcsv) zval *fields = NULL; if (zend_parse_parameters(ZEND_NUM_ARGS(), "a|sss", &fields, &delim, &d_len, &enclo, &e_len, &esc, &esc_len) == SUCCESS) { + + // TODO Align behaviour on normal fputcsv() switch(ZEND_NUM_ARGS()) { case 4: @@ -2429,6 +2433,7 @@ PHP_METHOD(SplFileObject, setCsvControl) size_t d_len = 0, e_len = 0, esc_len = 0; if (zend_parse_parameters(ZEND_NUM_ARGS(), "|sss", &delim, &d_len, &enclo, &e_len, &esc, &esc_len) == SUCCESS) { + // TODO Align behaviour on normal fgetcsv() switch(ZEND_NUM_ARGS()) { case 3: @@ -2685,8 +2690,8 @@ PHP_METHOD(SplFileObject, fread) CHECK_SPL_FILE_OBJECT_IS_INITIALIZED(intern); if (length <= 0) { - php_error_docref(NULL, E_WARNING, "Length parameter must be greater than 0"); - RETURN_FALSE; + zend_argument_value_error(1, "must be greater than 0"); + RETURN_THROWS(); } str = php_stream_read_to_str(intern->u.file.stream, length); diff --git a/ext/spl/spl_dllist.c b/ext/spl/spl_dllist.c index 9d066ecf13216..eb01c09d80fc7 100644 --- a/ext/spl/spl_dllist.c +++ b/ext/spl/spl_dllist.c @@ -413,9 +413,8 @@ static zend_object *spl_dllist_object_new_ex(zend_class_entry *class_type, zend_ inherited = 1; } - if (!parent) { /* this must never happen */ - php_error_docref(NULL, E_COMPILE_ERROR, "Internal compiler error, Class is not child of SplDoublyLinkedList"); - } + ZEND_ASSERT(parent); + if (inherited) { intern->fptr_offset_get = zend_hash_str_find_ptr(&class_type->function_table, "offsetget", sizeof("offsetget") - 1); if (intern->fptr_offset_get->common.scope == parent) { diff --git a/ext/spl/spl_fixedarray.c b/ext/spl/spl_fixedarray.c index 866a0a9a7869c..558514eec1e50 100644 --- a/ext/spl/spl_fixedarray.c +++ b/ext/spl/spl_fixedarray.c @@ -234,9 +234,7 @@ static zend_object *spl_fixedarray_object_new_ex(zend_class_entry *class_type, z inherited = 1; } - if (!parent) { /* this must never happen */ - php_error_docref(NULL, E_COMPILE_ERROR, "Internal compiler error, Class is not child of SplFixedArray"); - } + ZEND_ASSERT(parent); funcs_ptr = class_type->iterator_funcs_ptr; if (!funcs_ptr->zf_current) { diff --git a/ext/spl/spl_heap.c b/ext/spl/spl_heap.c index e23b0f242138d..0beea11da0780 100644 --- a/ext/spl/spl_heap.c +++ b/ext/spl/spl_heap.c @@ -433,9 +433,7 @@ static zend_object *spl_heap_object_new_ex(zend_class_entry *class_type, zend_ob inherited = 1; } - if (!parent) { /* this must never happen */ - php_error_docref(NULL, E_COMPILE_ERROR, "Internal compiler error, Class is not child of SplHeap"); - } + ZEND_ASSERT(parent); if (inherited) { intern->fptr_cmp = zend_hash_str_find_ptr(&class_type->function_table, "compare", sizeof("compare") - 1); diff --git a/ext/spl/spl_iterators.c b/ext/spl/spl_iterators.c index 242fcfbfae88f..d245cc356731b 100644 --- a/ext/spl/spl_iterators.c +++ b/ext/spl/spl_iterators.c @@ -454,8 +454,8 @@ static zend_object_iterator *spl_recursive_it_get_iterator(zend_class_entry *ce, iterator = emalloc(sizeof(spl_recursive_it_iterator)); object = Z_SPLRECURSIVE_IT_P(zobject); if (object->iterators == NULL) { - zend_error(E_ERROR, "The object to be iterated is in an invalid state: " - "the parent constructor has not been called"); + zend_throw_error(NULL, "Object is not initialized"); + return NULL; } zend_iterator_init((zend_object_iterator*)iterator); @@ -2486,7 +2486,7 @@ PHP_METHOD(CachingIterator, offsetGet) } if ((value = zend_symtable_find(Z_ARRVAL(intern->u.caching.zcache), key)) == NULL) { - zend_error(E_NOTICE, "Undefined array key \"%s\"", ZSTR_VAL(key)); + zend_error(E_WARNING, "Undefined array key \"%s\"", ZSTR_VAL(key)); return; } diff --git a/ext/spl/tests/bug61828.phpt b/ext/spl/tests/bug61828.phpt index 04d435e6d6edd..2a11b760bb353 100644 --- a/ext/spl/tests/bug61828.phpt +++ b/ext/spl/tests/bug61828.phpt @@ -3,9 +3,13 @@ Bug #61828 (Memleak when calling Directory(Recursive)Iterator/Spl(Temp)FileObjec --FILE-- __construct('/tmp'); -echo "Okey"; + +try { + $x->__construct('/tmp'); +} catch (\Error $e) { + echo $e->getMessage() . \PHP_EOL; +} + ?> ---EXPECTF-- -Warning: DirectoryIterator::__construct(): Directory object is already initialized in %sbug61828.php on line 3 -Okey +--EXPECT-- +Directory object is already initialized diff --git a/ext/spl/tests/bug65545.phpt b/ext/spl/tests/bug65545.phpt index bd5a7f06dbfd8..8ebbf648c97c5 100644 --- a/ext/spl/tests/bug65545.phpt +++ b/ext/spl/tests/bug65545.phpt @@ -6,17 +6,19 @@ $obj = new SplFileObject(__FILE__, 'r'); $data = $obj->fread(5); var_dump($data); -$data = $obj->fread(0); -var_dump($data); +try { + $data = $obj->fread(0); + var_dump($data); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} // read more data than is available $data = $obj->fread(filesize(__FILE__) + 32); var_dump(strlen($data) === filesize(__FILE__) - 5); ?> ---EXPECTF-- +--EXPECT-- string(5) " Date: Thu, 3 Sep 2020 23:52:24 +0300 Subject: [PATCH 50/87] Reorder DynAsm macros (no other changes) --- ext/opcache/jit/zend_jit_x86.dasc | 148 +++++++++++++++--------------- 1 file changed, 74 insertions(+), 74 deletions(-) diff --git a/ext/opcache/jit/zend_jit_x86.dasc b/ext/opcache/jit/zend_jit_x86.dasc index 58149c902932a..aa3488d8642db 100644 --- a/ext/opcache/jit/zend_jit_x86.dasc +++ b/ext/opcache/jit/zend_jit_x86.dasc @@ -228,80 +228,6 @@ static void* dasm_labels[zend_lb_MAX]; | .endif |.endmacro -|.macro SAVE_OPLINE -|| if (GCC_GLOBAL_REGS) { -| mov aword EX->opline, IP -|| } -|.endmacro - -|.macro LOAD_OPLINE -|| if (GCC_GLOBAL_REGS) { -| mov IP, aword EX->opline -|| } -|.endmacro - -|.macro LOAD_IP_ADDR, addr -|| if (GCC_GLOBAL_REGS) { -| LOAD_ADDR IP, addr -|| } else { -| LOAD_ADDR RX, addr -| mov aword EX->opline, RX -|| } -|.endmacro - -|.macro LOAD_IP_ADDR_ZTS, struct, field -| .if ZTS -|| if (GCC_GLOBAL_REGS) { -| LOAD_TSRM_CACHE IP -| mov IP, aword [IP + (struct.._offset + offsetof(zend_..struct, field))] -|| } else { -| LOAD_TSRM_CACHE RX -| lea RX, aword [RX + (struct.._offset + offsetof(zend_..struct, field))] -| mov aword EX->opline, RX -|| } -| .else -| LOAD_IP_ADDR &struct.field -| .endif -|.endmacro - -|.macro GET_IP, reg -|| if (GCC_GLOBAL_REGS) { -| mov reg, IP -|| } else { -| mov reg, aword EX->opline -|| } -|.endmacro - -|.macro ADD_IP, val -|| if (GCC_GLOBAL_REGS) { -| add IP, val -|| } else { -| add aword EX->opline, val -|| } -|.endmacro - -|.macro JMP_IP -|| if (GCC_GLOBAL_REGS) { -| jmp aword [IP] -|| } else { -| mov r0, aword EX:FCARG1a->opline -| jmp aword [r0] -|| } -|.endmacro - -/* In 64-bit build we compare only low 32-bits. - * x86_64 cmp instruction doesn't support immediate 64-bit operand, and full - * comparison would require an additional load of 64-bit address into register. - * This is not a problem at all, while JIT buffer size is less than 4GB. - */ -|.macro CMP_IP, addr -|| if (GCC_GLOBAL_REGS) { -| cmp IPl, addr -|| } else { -| cmp dword EX->opline, addr -|| } -|.endmacro - |.macro ADDR_OP1, addr_ins, addr, tmp_reg | .if X64 || if (IS_32BIT(addr)) { @@ -455,6 +381,80 @@ static void* dasm_labels[zend_lb_MAX]; | .endif |.endmacro +|.macro SAVE_OPLINE +|| if (GCC_GLOBAL_REGS) { +| mov aword EX->opline, IP +|| } +|.endmacro + +|.macro LOAD_OPLINE +|| if (GCC_GLOBAL_REGS) { +| mov IP, aword EX->opline +|| } +|.endmacro + +|.macro LOAD_IP_ADDR, addr +|| if (GCC_GLOBAL_REGS) { +| LOAD_ADDR IP, addr +|| } else { +| LOAD_ADDR RX, addr +| mov aword EX->opline, RX +|| } +|.endmacro + +|.macro LOAD_IP_ADDR_ZTS, struct, field +| .if ZTS +|| if (GCC_GLOBAL_REGS) { +| LOAD_TSRM_CACHE IP +| mov IP, aword [IP + (struct.._offset + offsetof(zend_..struct, field))] +|| } else { +| LOAD_TSRM_CACHE RX +| lea RX, aword [RX + (struct.._offset + offsetof(zend_..struct, field))] +| mov aword EX->opline, RX +|| } +| .else +| LOAD_IP_ADDR &struct.field +| .endif +|.endmacro + +|.macro GET_IP, reg +|| if (GCC_GLOBAL_REGS) { +| mov reg, IP +|| } else { +| mov reg, aword EX->opline +|| } +|.endmacro + +|.macro ADD_IP, val +|| if (GCC_GLOBAL_REGS) { +| add IP, val +|| } else { +| add aword EX->opline, val +|| } +|.endmacro + +|.macro JMP_IP +|| if (GCC_GLOBAL_REGS) { +| jmp aword [IP] +|| } else { +| mov r0, aword EX:FCARG1a->opline +| jmp aword [r0] +|| } +|.endmacro + +/* In 64-bit build we compare only low 32-bits. + * x86_64 cmp instruction doesn't support immediate 64-bit operand, and full + * comparison would require an additional load of 64-bit address into register. + * This is not a problem at all, while JIT buffer size is less than 4GB. + */ +|.macro CMP_IP, addr +|| if (GCC_GLOBAL_REGS) { +| cmp IPl, addr +|| } else { +| cmp dword EX->opline, addr +|| } +|.endmacro + |.macro LOAD_ZVAL_ADDR, reg, addr || if (Z_MODE(addr) == IS_CONST_ZVAL) { | LOAD_ADDR reg, Z_ZV(addr) From 531d17f0bd29070085398e157d7131aa6727fe18 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Thu, 3 Sep 2020 23:53:02 +0300 Subject: [PATCH 51/87] Load EX(opline) in one instuction if possible --- ext/opcache/jit/zend_jit_x86.dasc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ext/opcache/jit/zend_jit_x86.dasc b/ext/opcache/jit/zend_jit_x86.dasc index aa3488d8642db..54d8864e8e572 100644 --- a/ext/opcache/jit/zend_jit_x86.dasc +++ b/ext/opcache/jit/zend_jit_x86.dasc @@ -397,8 +397,7 @@ static void* dasm_labels[zend_lb_MAX]; || if (GCC_GLOBAL_REGS) { | LOAD_ADDR IP, addr || } else { -| LOAD_ADDR RX, addr -| mov aword EX->opline, RX +| ADDR_OP2_2 mov, aword EX->opline, addr, RX || } |.endmacro From 3f4a5003aa57f6a7de798d88eddcd810d4f1dce8 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 4 Sep 2020 02:10:48 +0300 Subject: [PATCH 52/87] Cleanup macro/function names --- ext/opcache/jit/zend_jit.c | 12 +- ext/opcache/jit/zend_jit_trace.c | 8 +- ext/opcache/jit/zend_jit_x86.dasc | 250 +++++++++++++++--------------- 3 files changed, 136 insertions(+), 134 deletions(-) diff --git a/ext/opcache/jit/zend_jit.c b/ext/opcache/jit/zend_jit.c index 92c499e349ef0..48a37a0e511d6 100644 --- a/ext/opcache/jit/zend_jit.c +++ b/ext/opcache/jit/zend_jit.c @@ -2162,17 +2162,17 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op || op_array->opcodes[ssa->cfg.blocks[b].start - 1].opcode == ZEND_SWITCH_LONG || op_array->opcodes[ssa->cfg.blocks[b].start - 1].opcode == ZEND_SWITCH_STRING || op_array->opcodes[ssa->cfg.blocks[b].start - 1].opcode == ZEND_MATCH)) { - zend_jit_reset_opline(); - if (!zend_jit_set_valid_ip(&dasm_state, op_array->opcodes + ssa->cfg.blocks[b].start)) { + zend_jit_reset_last_valid_opline(); + if (!zend_jit_set_ip(&dasm_state, op_array->opcodes + ssa->cfg.blocks[b].start)) { goto jit_failure; } } else { - zend_jit_set_opline(op_array->opcodes + ssa->cfg.blocks[b].start); + zend_jit_set_last_valid_opline(op_array->opcodes + ssa->cfg.blocks[b].start); } } else if (ssa->cfg.blocks[b].flags & ZEND_BB_TARGET) { - zend_jit_reset_opline(); + zend_jit_reset_last_valid_opline(); } else if (ssa->cfg.blocks[b].flags & (ZEND_BB_START|ZEND_BB_RECV_ENTRY|ZEND_BB_ENTRY)) { - zend_jit_set_opline(op_array->opcodes + ssa->cfg.blocks[b].start); + zend_jit_set_last_valid_opline(op_array->opcodes + ssa->cfg.blocks[b].start); } if (ssa->cfg.blocks[b].flags & ZEND_BB_LOOP_HEADER) { if (!zend_jit_check_timeout(&dasm_state, op_array->opcodes + ssa->cfg.blocks[b].start, NULL)) { @@ -3012,7 +3012,7 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op goto jit_failure; } } - zend_jit_set_opline(opline+1); + zend_jit_set_last_valid_opline(opline+1); break; case ZEND_NOP: case ZEND_OP_DATA: diff --git a/ext/opcache/jit/zend_jit_trace.c b/ext/opcache/jit/zend_jit_trace.c index 408e540e0fe88..b922655e37641 100644 --- a/ext/opcache/jit/zend_jit_trace.c +++ b/ext/opcache/jit/zend_jit_trace.c @@ -3141,12 +3141,12 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par parent_trace ? &zend_jit_traces[parent_trace] : NULL, exit_num); if (!parent_trace) { - zend_jit_set_opline(opline); + zend_jit_set_last_valid_opline(opline); } else { if (zend_jit_traces[parent_trace].exit_info[exit_num].opline == NULL) { zend_jit_trace_opline_guard(&dasm_state, opline); } else { - zend_jit_reset_opline(); + zend_jit_reset_last_valid_opline(); } } @@ -5078,7 +5078,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par || p->stop == ZEND_JIT_TRACE_STOP_RECURSIVE_CALL || p->stop == ZEND_JIT_TRACE_STOP_RECURSIVE_RET) { if (p->stop != ZEND_JIT_TRACE_STOP_RECURSIVE_RET) { - if (!zend_jit_set_valid_ip(&dasm_state, p->opline)) { + if (!zend_jit_set_ip(&dasm_state, p->opline)) { goto jit_failure; } } @@ -5097,7 +5097,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par goto jit_failure; } if (p->stop == ZEND_JIT_TRACE_STOP_LINK) { - if (!zend_jit_set_valid_ip(&dasm_state, p->opline)) { + if (!zend_jit_set_ip(&dasm_state, p->opline)) { goto jit_failure; } t->link = zend_jit_find_trace(p->opline->handler); diff --git a/ext/opcache/jit/zend_jit_x86.dasc b/ext/opcache/jit/zend_jit_x86.dasc index 54d8864e8e572..afb51163dd8ac 100644 --- a/ext/opcache/jit/zend_jit_x86.dasc +++ b/ext/opcache/jit/zend_jit_x86.dasc @@ -381,13 +381,13 @@ static void* dasm_labels[zend_lb_MAX]; | .endif |.endmacro -|.macro SAVE_OPLINE +|.macro SAVE_IP || if (GCC_GLOBAL_REGS) { | mov aword EX->opline, IP || } |.endmacro -|.macro LOAD_OPLINE +|.macro LOAD_IP || if (GCC_GLOBAL_REGS) { | mov IP, aword EX->opline || } @@ -1338,11 +1338,14 @@ static void* dasm_labels[zend_lb_MAX]; || } |.endmacro -|.macro SAVE_VALID_OPLINE, op, tmp_reg +|.macro SET_EX_OPLINE, op, tmp_reg || if (op == last_valid_opline) { -| SAVE_OPLINE +| SAVE_IP || } else { | ADDR_OP2_2 mov, aword EX->opline, op, tmp_reg +|| if (!GCC_GLOBAL_REGS) { +|| last_valid_opline = NULL; +|| } || } |.endmacro @@ -1357,7 +1360,7 @@ static void* dasm_labels[zend_lb_MAX]; || } else if (type == IS_ARRAY) { || if ((var_info) & (MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_STRING|MAY_BE_ARRAY_OF_ARRAY|MAY_BE_ARRAY_OF_OBJECT|MAY_BE_ARRAY_OF_RESOURCE|MAY_BE_ARRAY_OF_REF)) { || if (opline && ((var_info) & (MAY_BE_ARRAY_OF_ARRAY|MAY_BE_ARRAY_OF_OBJECT|MAY_BE_ARRAY_OF_RESOURCE|MAY_BE_ARRAY_OF_REF))) { -| SAVE_VALID_OPLINE opline, r0 +| SET_EX_OPLINE opline, r0 || } | EXT_CALL zend_array_destroy, r0 || } else { @@ -1366,14 +1369,14 @@ static void* dasm_labels[zend_lb_MAX]; || break; || } else if (type == IS_OBJECT) { || if (opline) { -| SAVE_VALID_OPLINE opline, r0 +| SET_EX_OPLINE opline, r0 || } | EXT_CALL zend_objects_store_del, r0 || break; || } || } || if (opline) { -| SAVE_VALID_OPLINE opline, r0 +| SET_EX_OPLINE opline, r0 || } | EXT_CALL rc_dtor_func, r0 || } while(0); @@ -1577,7 +1580,7 @@ static void* dasm_labels[zend_lb_MAX]; || if (opline == last_valid_opline) { | call ->undefined_offset_ex || } else { -| SAVE_VALID_OPLINE opline, r0 +| SET_EX_OPLINE opline, r0 | call ->undefined_offset || } |.endmacro @@ -1586,7 +1589,7 @@ static void* dasm_labels[zend_lb_MAX]; || if (opline == last_valid_opline) { | call ->undefined_index_ex || } else { -| SAVE_VALID_OPLINE opline, r0 +| SET_EX_OPLINE opline, r0 | call ->undefined_index || } |.endmacro @@ -1595,7 +1598,7 @@ static void* dasm_labels[zend_lb_MAX]; || if (opline == last_valid_opline) { | call ->cannot_add_element_ex || } else { -| SAVE_VALID_OPLINE opline, r0 +| SET_EX_OPLINE opline, r0 | call ->cannot_add_element || } |.endmacro @@ -1607,6 +1610,27 @@ static const zend_op *last_valid_opline; static int jit_return_label; static uint32_t current_trace_num; +static void zend_jit_set_last_valid_opline(const zend_op *target_opline) +{ + if (!reuse_ip) { + last_valid_opline = target_opline; + } +} + +static void zend_jit_reset_last_valid_opline(void) +{ + last_valid_opline = NULL; +} + +static void zend_jit_start_reuse_ip(void) { + last_valid_opline = NULL; + reuse_ip = 1; +} + +static void zend_jit_stop_reuse_ip(void) { + reuse_ip = 0; +} + /* bit helpers */ /* from http://aggregate.org/MAGIC/ */ @@ -1654,7 +1678,7 @@ static inline zend_bool is_signed(double d) static int zend_jit_interrupt_handler_stub(dasm_State **Dst) { |->interrupt_handler: - | SAVE_OPLINE + | SAVE_IP | //EG(vm_interrupt) = 0; | MEM_OP2_1_ZTS mov, byte, executor_globals, vm_interrupt, 0, r0 | //if (EG(timed_out)) { @@ -1678,7 +1702,7 @@ static int zend_jit_interrupt_handler_stub(dasm_State **Dst) | //ZEND_VM_ENTER(); | //execute_data = EG(current_execute_data); | MEM_OP2_2_ZTS mov, FP, aword, executor_globals, current_execute_data, r0 - | LOAD_OPLINE + | LOAD_IP } | //ZEND_VM_CONTINUE() if (zend_jit_vm_kind == ZEND_VM_KIND_HYBRID) { @@ -1891,7 +1915,7 @@ static int zend_jit_throw_cannot_pass_by_ref_stub(dasm_State **Dst) static int zend_jit_undefined_offset_ex_stub(dasm_State **Dst) { |->undefined_offset_ex: - | SAVE_OPLINE + | SAVE_IP | jmp ->undefined_offset return 1; @@ -1959,7 +1983,7 @@ static int zend_jit_undefined_offset_stub(dasm_State **Dst) static int zend_jit_undefined_index_ex_stub(dasm_State **Dst) { |->undefined_index_ex: - | SAVE_OPLINE + | SAVE_IP | jmp ->undefined_index return 1; @@ -2031,7 +2055,7 @@ static int zend_jit_undefined_index_stub(dasm_State **Dst) static int zend_jit_cannot_add_element_ex_stub(dasm_State **Dst) { |->cannot_add_element_ex: - | SAVE_OPLINE + | SAVE_IP | jmp ->cannot_add_element return 1; @@ -2330,7 +2354,7 @@ static int zend_jit_hybrid_hot_trace_stub(dasm_State **Dst) | test eax, eax // TODO : remove this check at least for HYBRID VM ??? | jl >1 | MEM_OP2_2_ZTS mov, FP, aword, executor_globals, current_execute_data, r0 - | LOAD_OPLINE + | LOAD_IP | JMP_IP |1: | EXT_JMP zend_jit_halt_op->handler, r0 @@ -2461,7 +2485,7 @@ static int zend_jit_trace_exit_stub(dasm_State **Dst) |.endif | | // EX(opline) = opline - | SAVE_OPLINE + | SAVE_IP | // zend_jit_trace_exit(trace_num, exit_num) | EXT_CALL zend_jit_trace_exit, r0 |.if X64WIN @@ -2478,7 +2502,7 @@ static int zend_jit_trace_exit_stub(dasm_State **Dst) | // execute_data = EG(current_execute_data) | MEM_OP2_2_ZTS mov, FP, aword, executor_globals, current_execute_data, r0 | // opline = EX(opline) - | LOAD_OPLINE + | LOAD_IP if (zend_jit_vm_kind == ZEND_VM_KIND_HYBRID) { | add r4, HYBRID_SPAD @@ -2500,7 +2524,7 @@ static int zend_jit_trace_exit_stub(dasm_State **Dst) | // execute_data = EG(current_execute_data) | MEM_OP2_2_ZTS mov, FP, aword, executor_globals, current_execute_data, r0 | // opline = EX(opline) - | LOAD_OPLINE + | LOAD_IP | // check for interrupt (try to avoid this ???) | MEM_OP2_1_ZTS cmp, byte, executor_globals, vm_interrupt, 0, r0 @@ -2834,6 +2858,8 @@ static int zend_jit_set_ip(dasm_State **Dst, const zend_op *opline) | LOAD_IP_ADDR opline } } + last_valid_opline = opline; + return 1; } @@ -2847,7 +2873,6 @@ static int zend_jit_set_valid_ip(dasm_State **Dst, const zend_op *opline) if (!zend_jit_set_ip(Dst, opline)) { return 0; } - last_valid_opline = opline; reuse_ip = 0; return 1; } @@ -3386,7 +3411,7 @@ static int zend_jit_trace_handler(dasm_State **Dst, const zend_op_array *op_arra } } - last_valid_opline = trace->opline; + zend_jit_set_last_valid_opline(trace->opline); return 1; } @@ -3411,7 +3436,6 @@ static int zend_jit_handler(dasm_State **Dst, const zend_op *opline, int may_thr if (may_throw) { zend_jit_check_exception(Dst); } - last_valid_opline++; /* Skip the following OP_DATA */ switch (opline->opcode) { @@ -3423,9 +3447,10 @@ static int zend_jit_handler(dasm_State **Dst, const zend_op *opline, int may_thr case ZEND_ASSIGN_STATIC_PROP_OP: case ZEND_ASSIGN_STATIC_PROP_REF: case ZEND_ASSIGN_OBJ_REF: - last_valid_opline++; + zend_jit_set_last_valid_opline(opline + 2); break; default: + zend_jit_set_last_valid_opline(opline + 1); break; } @@ -3468,31 +3493,10 @@ static int zend_jit_tail_handler(dasm_State **Dst, const zend_op *opline) } | EXT_JMP handler, r0 } - last_valid_opline = NULL; + zend_jit_reset_last_valid_opline(); return 1; } -static void zend_jit_set_opline(const zend_op *target_opline) -{ - if (!reuse_ip) { - last_valid_opline = target_opline; - } -} - -static void zend_jit_reset_opline(void) -{ - last_valid_opline = NULL; -} - -static void zend_jit_start_reuse_ip(void) { - last_valid_opline = NULL; - reuse_ip = 1; -} - -static void zend_jit_stop_reuse_ip(void) { - reuse_ip = 0; -} - static int zend_jit_trace_opline_guard(dasm_State **Dst, const zend_op *opline) { uint32_t exit_point = zend_jit_trace_get_exit_point(NULL, 0); @@ -3504,7 +3508,7 @@ static int zend_jit_trace_opline_guard(dasm_State **Dst, const zend_op *opline) | CMP_IP opline | jne &exit_addr - zend_jit_set_opline(opline); + zend_jit_set_last_valid_opline(opline); return 1; } @@ -3520,7 +3524,7 @@ static int zend_jit_cond_jmp(dasm_State **Dst, const zend_op *next_opline, unsig | CMP_IP next_opline | jne =>target_label - last_valid_opline = next_opline; + zend_jit_set_last_valid_opline(next_opline); return 1; } @@ -3678,8 +3682,8 @@ static int zend_jit_escape_if_undef_r0(dasm_State **Dst, int var, uint32_t flags } ZEND_ASSERT(opline); - zend_jit_set_ip(Dst, opline - 1); + | LOAD_IP_ADDR (opline - 1) | jmp ->trace_escape |1: @@ -3849,7 +3853,7 @@ static int zend_jit_inc_dec(dasm_State **Dst, const zend_op *opline, uint32_t op |.cold_code |2: if (op1_info & ((MAY_BE_ANY|MAY_BE_UNDEF)-(MAY_BE_LONG|MAY_BE_DOUBLE))) { - | SAVE_VALID_OPLINE opline, r0 + | SET_EX_OPLINE opline, r0 if (op1_info & MAY_BE_UNDEF) { | IF_NOT_ZVAL_TYPE op1_addr, IS_UNDEF, >2 | // zend_error(E_WARNING, "Undefined variable $%s", ZSTR_VAL(CV_DEF_OF(EX_VAR_TO_NUM(opline->op1.var)))); @@ -4485,7 +4489,7 @@ static int zend_jit_math_helper(dasm_State **Dst, | sub r4, 12 | PUSH_ZVAL_ADDR op2_addr, r0 |.endif - | SAVE_VALID_OPLINE opline, r0 + | SET_EX_OPLINE opline, r0 if (opcode == ZEND_ADD) { | EXT_CALL add_function, r0 } else if (opcode == ZEND_SUB) { @@ -4632,7 +4636,7 @@ static int zend_jit_long_math_helper(dasm_State **Dst, if (EXPECTED(op2_lval > 0)) { | xor Ra(result_reg), Ra(result_reg) } else { - | SAVE_VALID_OPLINE opline, r0 + | SET_EX_OPLINE opline, r0 | jmp ->negative_shift } } else if (Z_MODE(op1_addr) == IS_REG && op2_lval == 1) { @@ -4655,7 +4659,7 @@ static int zend_jit_long_math_helper(dasm_State **Dst, | cmp r1, 0 | mov Ra(result_reg), 0 | jg >1 - | SAVE_VALID_OPLINE opline, r0 + | SET_EX_OPLINE opline, r0 | jmp ->negative_shift |.code } @@ -4672,7 +4676,7 @@ static int zend_jit_long_math_helper(dasm_State **Dst, if (EXPECTED(op2_lval > 0)) { | sar Ra(result_reg), (SIZEOF_ZEND_LONG * 8) - 1 } else { - | SAVE_VALID_OPLINE opline, r0 + | SET_EX_OPLINE opline, r0 | jmp ->negative_shift } } else { @@ -4692,7 +4696,7 @@ static int zend_jit_long_math_helper(dasm_State **Dst, | cmp r1, 0 | mov r1, (SIZEOF_ZEND_LONG * 8) - 1 | jg >1 - | SAVE_VALID_OPLINE opline, r0 + | SET_EX_OPLINE opline, r0 | jmp ->negative_shift |.code } @@ -4704,7 +4708,7 @@ static int zend_jit_long_math_helper(dasm_State **Dst, zend_long op2_lval = Z_LVAL_P(Z_ZV(op2_addr)); if (op2_lval == 0) { - | SAVE_VALID_OPLINE opline, r0 + | SET_EX_OPLINE opline, r0 | jmp ->mod_by_zero } else if (op2_lval == -1) { | xor Ra(result_reg), Ra(result_reg) @@ -4729,7 +4733,7 @@ static int zend_jit_long_math_helper(dasm_State **Dst, | jz >1 |.cold_code |1: - | SAVE_VALID_OPLINE opline, r0 + | SET_EX_OPLINE opline, r0 | jmp ->mod_by_zero |.code } @@ -4820,7 +4824,7 @@ static int zend_jit_long_math_helper(dasm_State **Dst, | sub r4, 12 | PUSH_ZVAL_ADDR op2_addr, r0 |.endif - | SAVE_VALID_OPLINE opline, r0 + | SET_EX_OPLINE opline, r0 if (opcode == ZEND_BW_OR) { | EXT_CALL bitwise_or_function, r0 } else if (opcode == ZEND_BW_AND) { @@ -4951,7 +4955,7 @@ static int zend_jit_concat_helper(dasm_State **Dst, | sub r4, 12 | PUSH_ZVAL_ADDR op2_addr, r0 |.endif - | SAVE_VALID_OPLINE opline, r0 + | SET_EX_OPLINE opline, r0 | EXT_CALL concat_function, r0 |.if not(X64) | add r4, 12 @@ -5223,7 +5227,7 @@ static int zend_jit_fetch_dimension_address_inner(dasm_State **Dst, const zend_o | // hval = Z_LVAL_P(dim); | GET_ZVAL_LVAL ZREG_FCARG2a, op2_addr } - | SAVE_VALID_OPLINE opline, r0 + | SET_EX_OPLINE opline, r0 | EXT_CALL zend_jit_hash_index_lookup_rw, r0 | test r0, r0 | jz >9 @@ -5365,7 +5369,7 @@ static int zend_jit_fetch_dimension_address_inner(dasm_State **Dst, const zend_o |.code break; case BP_VAR_RW: - | SAVE_VALID_OPLINE opline, r0 + | SET_EX_OPLINE opline, r0 if (opline->op2_type != IS_CONST) { | EXT_CALL zend_jit_symtable_lookup_rw, r0 } else { @@ -5406,7 +5410,7 @@ static int zend_jit_fetch_dimension_address_inner(dasm_State **Dst, const zend_o |.cold_code |3: } - | SAVE_VALID_OPLINE opline, r0 + | SET_EX_OPLINE opline, r0 | LOAD_ZVAL_ADDR FCARG2a, op2_addr switch (type) { case BP_VAR_R: @@ -5532,7 +5536,7 @@ static int zend_jit_simple_assign(dasm_State **Dst, if (res_addr) { | SET_ZVAL_TYPE_INFO res_addr, IS_NULL } - | SAVE_VALID_OPLINE opline, Ra(tmp_reg) + | SET_EX_OPLINE opline, Ra(tmp_reg) | mov FCARG1d, val.var | EXT_CALL zend_jit_undefined_op_helper, r0 if (save_r1) { @@ -5635,7 +5639,7 @@ static int zend_jit_assign_to_typed_ref(dasm_State **Dst, |.cold_code |2: | LOAD_ZVAL_ADDR FCARG2a, val_addr - | SAVE_VALID_OPLINE opline, r0 + | SET_EX_OPLINE opline, r0 if (val_type == IS_CONST) { | EXT_CALL zend_jit_assign_const_to_typed_ref, r0 } else if (val_type == IS_TMP_VAR) { @@ -5839,7 +5843,7 @@ static int zend_jit_assign_dim(dasm_State **Dst, const zend_op *opline, uint32_t | jmp >3 |.cold_code |2: - | SAVE_VALID_OPLINE opline, r0 + | SET_EX_OPLINE opline, r0 | EXT_CALL zend_jit_prepare_assign_dim_ref, r0 | test r0, r0 | mov FCARG1a, r0 @@ -5951,7 +5955,7 @@ static int zend_jit_assign_dim(dasm_State **Dst, const zend_op *opline, uint32_t } if (op1_info & (MAY_BE_ANY-(MAY_BE_NULL|MAY_BE_FALSE|MAY_BE_ARRAY))) { - | SAVE_VALID_OPLINE opline, r0 + | SET_EX_OPLINE opline, r0 if (Z_REG(op1_addr) != ZREG_FCARG1a || Z_OFFSET(op1_addr) != 0) { | LOAD_ZVAL_ADDR FCARG1a, op1_addr } @@ -6042,7 +6046,7 @@ static int zend_jit_assign_dim_op(dasm_State **Dst, const zend_op *opline, uint3 | jmp >3 |.cold_code |2: - | SAVE_VALID_OPLINE opline, r0 + | SET_EX_OPLINE opline, r0 | EXT_CALL zend_jit_prepare_assign_dim_ref, r0 | test r0, r0 | mov FCARG1a, r0 @@ -6073,7 +6077,7 @@ static int zend_jit_assign_dim_op(dasm_State **Dst, const zend_op *opline, uint3 if (op1_info & (MAY_BE_NULL|MAY_BE_FALSE)) { | IF_NOT_ZVAL_TYPE op1_addr, IS_UNDEF, >1 } - | SAVE_VALID_OPLINE opline, r0 + | SET_EX_OPLINE opline, r0 | mov FCARG1a, opline->op1.var | EXT_CALL zend_jit_undefined_op_helper, r0 |1: @@ -6147,7 +6151,7 @@ static int zend_jit_assign_dim_op(dasm_State **Dst, const zend_op *opline, uint3 | sub r4, 12 | PUSH_ADDR binary_op, r0 |.endif - | SAVE_VALID_OPLINE opline, r0 + | SET_EX_OPLINE opline, r0 | EXT_CALL zend_jit_assign_op_to_typed_ref, r0 |.if not(X64) | add r4, 12 @@ -6203,7 +6207,7 @@ static int zend_jit_assign_dim_op(dasm_State **Dst, const zend_op *opline, uint3 |7: } - | SAVE_VALID_OPLINE opline, r0 + | SET_EX_OPLINE opline, r0 if (Z_REG(op1_addr) != ZREG_FCARG1a || Z_OFFSET(op1_addr) != 0) { | LOAD_ZVAL_ADDR FCARG1a, op1_addr } @@ -6270,7 +6274,7 @@ static int zend_jit_assign_op(dasm_State **Dst, const zend_op *opline, uint32_t | sub r4, 12 | PUSH_ADDR binary_op, r0 |.endif - | SAVE_VALID_OPLINE opline, r0 + | SET_EX_OPLINE opline, r0 | EXT_CALL zend_jit_assign_op_to_typed_ref, r0 |.if not(X64) | add r4, 12 @@ -7236,7 +7240,7 @@ static int zend_jit_cmp(dasm_State **Dst, const zend_op *opline, uint32_t op1_in |.cold_code |9: } - | SAVE_VALID_OPLINE opline, r0 + | SET_EX_OPLINE opline, r0 if (Z_MODE(op1_addr) == IS_REG) { zend_jit_addr real_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FP, opline->op1.var); if (!zend_jit_spill_store(Dst, op1_addr, real_addr, op1_info, 1)) { @@ -7367,7 +7371,7 @@ static int zend_jit_identical(dasm_State **Dst, const zend_op *opline, uint32_t |.cold_code |1: | // zend_error(E_WARNING, "Undefined variable $%s", ZSTR_VAL(CV_DEF_OF(EX_VAR_TO_NUM(opline->op1.var)))); - | SAVE_VALID_OPLINE opline, r0 + | SET_EX_OPLINE opline, r0 | mov FCARG1d, opline->op1.var | EXT_CALL zend_jit_undefined_op_helper, r0 if (may_throw) { @@ -7382,7 +7386,7 @@ static int zend_jit_identical(dasm_State **Dst, const zend_op *opline, uint32_t |.cold_code |1: | // zend_error(E_WARNING, "Undefined variable $%s", ZSTR_VAL(CV_DEF_OF(EX_VAR_TO_NUM(opline->op1.var)))); - | SAVE_VALID_OPLINE opline, r0 + | SET_EX_OPLINE opline, r0 | mov aword T1, FCARG1a // save | mov FCARG1d, opline->op2.var | EXT_CALL zend_jit_undefined_op_helper, r0 @@ -7401,7 +7405,7 @@ static int zend_jit_identical(dasm_State **Dst, const zend_op *opline, uint32_t |.cold_code |1: | // zend_error(E_WARNING, "Undefined variable $%s", ZSTR_VAL(CV_DEF_OF(EX_VAR_TO_NUM(opline->op1.var)))); - | SAVE_VALID_OPLINE opline, r0 + | SET_EX_OPLINE opline, r0 | mov FCARG1d, opline->op1.var | EXT_CALL zend_jit_undefined_op_helper, r0 if (may_throw) { @@ -7421,7 +7425,7 @@ static int zend_jit_identical(dasm_State **Dst, const zend_op *opline, uint32_t |.cold_code |1: | // zend_error(E_WARNING, "Undefined variable $%s", ZSTR_VAL(CV_DEF_OF(EX_VAR_TO_NUM(opline->op1.var)))); - | SAVE_VALID_OPLINE opline, r0 + | SET_EX_OPLINE opline, r0 | mov FCARG1d, opline->op2.var | EXT_CALL zend_jit_undefined_op_helper, r0 if (may_throw) { @@ -7469,7 +7473,7 @@ static int zend_jit_identical(dasm_State **Dst, const zend_op *opline, uint32_t (op1_info & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_REF))) || ((opline->op2_type & (IS_VAR|IS_TMP_VAR)) && (op2_info & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_REF)))) { - | SAVE_VALID_OPLINE opline, r0 + | SET_EX_OPLINE opline, r0 if (opline->opcode != ZEND_CASE_STRICT) { | FREE_OP opline->op1_type, opline->op1, op1_info, 1, opline } @@ -7536,7 +7540,7 @@ static int zend_jit_identical(dasm_State **Dst, const zend_op *opline, uint32_t if (smart_branch_opcode) { if (opline->op2_type == IS_VAR && (op2_info & MAY_BE_REF)) { | jne >8 - | SAVE_VALID_OPLINE opline, r0 + | SET_EX_OPLINE opline, r0 | FREE_OP opline->op2_type, opline->op2, op2_info, 1, opline zend_jit_check_exception_undef_result(Dst, opline); if (exit_addr && smart_branch_opcode == ZEND_JMPNZ) { @@ -7566,7 +7570,7 @@ static int zend_jit_identical(dasm_State **Dst, const zend_op *opline, uint32_t } if ((opline->op2_type & (IS_VAR|IS_TMP_VAR)) && (op2_info & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_REF))) { - | SAVE_VALID_OPLINE opline, r0 + | SET_EX_OPLINE opline, r0 | FREE_OP opline->op2_type, opline->op2, op2_info, 1, opline zend_jit_check_exception_undef_result(Dst, opline); } @@ -7585,7 +7589,7 @@ static int zend_jit_identical(dasm_State **Dst, const zend_op *opline, uint32_t if (opline->opcode != ZEND_CASE_STRICT && opline->op1_type == IS_VAR && (op1_info & MAY_BE_REF)) { | jne >8 - | SAVE_VALID_OPLINE opline, r0 + | SET_EX_OPLINE opline, r0 | FREE_OP opline->op1_type, opline->op1, op1_info, 1, opline zend_jit_check_exception_undef_result(Dst, opline); if (exit_addr && smart_branch_opcode == ZEND_JMPNZ) { @@ -7616,7 +7620,7 @@ static int zend_jit_identical(dasm_State **Dst, const zend_op *opline, uint32_t if (opline->opcode != ZEND_CASE_STRICT && (opline->op1_type & (IS_VAR|IS_TMP_VAR)) && (op1_info & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_REF))) { - | SAVE_VALID_OPLINE opline, r0 + | SET_EX_OPLINE opline, r0 | FREE_OP opline->op1_type, opline->op1, op1_info, 1, opline zend_jit_check_exception_undef_result(Dst, opline); } @@ -7643,7 +7647,7 @@ static int zend_jit_identical(dasm_State **Dst, const zend_op *opline, uint32_t ((opline->op2_type & (IS_VAR|IS_TMP_VAR)) && (op2_info & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_REF)))) { | mov aword T1, r0 // save - | SAVE_VALID_OPLINE opline, r0 + | SET_EX_OPLINE opline, r0 if (opline->opcode != ZEND_CASE_STRICT) { | FREE_OP opline->op1_type, opline->op1, op1_info, 1, opline } @@ -7885,7 +7889,7 @@ static int zend_jit_bool_jmpznz(dasm_State **Dst, const zend_op *opline, uint32_ |1: } | mov FCARG1d, opline->op1.var - | SAVE_VALID_OPLINE opline, r0 + | SET_EX_OPLINE opline, r0 | EXT_CALL zend_jit_undefined_op_helper, r0 if (may_throw) { @@ -8057,7 +8061,7 @@ static int zend_jit_bool_jmpznz(dasm_State **Dst, const zend_op *opline, uint32_ if (Z_REG(op1_addr) != ZREG_FCARG1a || Z_OFFSET(op1_addr) != 0) { | LOAD_ZVAL_ADDR FCARG1a, op1_addr } - | SAVE_VALID_OPLINE opline, r0 + | SET_EX_OPLINE opline, r0 | EXT_CALL zend_is_true, r0 if ((opline->op1_type & (IS_VAR|IS_TMP_VAR)) && @@ -8261,7 +8265,7 @@ static int zend_jit_push_call_frame(dasm_State **Dst, const zend_op *opline, zen | // EG(vm_stack_top) = (zval*)((char*)call + used_stack); |.cold_code |1: - | SAVE_VALID_OPLINE opline, r0 + | SET_EX_OPLINE opline, r0 if (func) { | mov FCARG1d, used_stack } @@ -8680,7 +8684,7 @@ static int zend_jit_init_fcall(dasm_State **Dst, const zend_op *opline, uint32_t | test r0, r0 | jnz >3 | // SAVE_OPLINE(); - | SAVE_VALID_OPLINE opline, r0 + | SET_EX_OPLINE opline, r0 | jmp ->undefined_function } } @@ -8816,7 +8820,7 @@ static int zend_jit_do_fcall(dasm_State **Dst, const zend_op *opline, const zend | // fbc = call->func; | // mov r2, EX:RX->func ??? | // SAVE_OPLINE(); - | SAVE_VALID_OPLINE opline, r0 + | SET_EX_OPLINE opline, r0 if (opline->opcode == ZEND_DO_FCALL) { if (!func) { @@ -9176,7 +9180,7 @@ static int zend_jit_do_fcall(dasm_State **Dst, const zend_op *opline, const zend | // EG(current_execute_data) = execute_data; | MEM_OP2_1_ZTS mov, aword, executor_globals, current_execute_data, RX, r1 - zend_jit_reset_opline(); + zend_jit_reset_last_valid_opline(); | // fbc->internal_function.handler(call, ret); | mov FCARG1a, RX @@ -9337,7 +9341,7 @@ static int zend_jit_send_val(dasm_State **Dst, const zend_op *opline, uint32_t o | jnz >1 |.cold_code |1: - | SAVE_VALID_OPLINE opline, r0 + | SET_EX_OPLINE opline, r0 | jmp ->throw_cannot_pass_by_ref |.code @@ -9367,7 +9371,7 @@ static int zend_jit_check_undef_args(dasm_State **Dst, const zend_op *opline) | jnz >1 |.cold_code |1: - | SAVE_VALID_OPLINE opline, r0 + | SET_EX_OPLINE opline, r0 | EXT_CALL zend_handle_undef_args, r0 | test r0, r0 | jnz ->exception_handler @@ -9551,7 +9555,7 @@ static int zend_jit_send_var(dasm_State **Dst, const zend_op *opline, const zend } | jmp &exit_addr } else { - | SAVE_VALID_OPLINE opline, r0 + | SET_EX_OPLINE opline, r0 | LOAD_ZVAL_ADDR FCARG1a, arg_addr | EXT_CALL zend_jit_only_vars_by_reference, r0 if (!zend_jit_check_exception(Dst)) { @@ -9593,7 +9597,7 @@ static int zend_jit_send_var(dasm_State **Dst, const zend_op *opline, const zend |1: } - | SAVE_VALID_OPLINE opline, r0 + | SET_EX_OPLINE opline, r0 | mov FCARG1d, opline->op1.var | EXT_CALL zend_jit_undefined_op_helper, r0 | SET_ZVAL_TYPE_INFO arg_addr, IS_NULL @@ -9623,7 +9627,7 @@ static int zend_jit_send_var(dasm_State **Dst, const zend_op *opline, const zend } | jmp &exit_addr } else { - | SAVE_VALID_OPLINE opline, r0 + | SET_EX_OPLINE opline, r0 | LOAD_ZVAL_ADDR FCARG1a, arg_addr | EXT_CALL zend_jit_only_vars_by_reference, r0 if (!zend_jit_check_exception(Dst)) { @@ -9839,7 +9843,7 @@ static int zend_jit_defined(dasm_State **Dst, const zend_op *opline, zend_uchar | jz >2 } |1: - | SAVE_VALID_OPLINE opline, r0 + | SET_EX_OPLINE opline, r0 | LOAD_ADDR FCARG1a, zv | EXT_CALL zend_jit_check_constant, r0 | test r0, r0 @@ -9901,7 +9905,7 @@ static int zend_jit_type_check(dasm_State **Dst, const zend_op *opline, uint32_t |.cold_code |1: } - | SAVE_VALID_OPLINE opline, r0 + | SET_EX_OPLINE opline, r0 | mov FCARG1d, opline->op1.var | EXT_CALL zend_jit_undefined_op_helper, r0 zend_jit_check_exception_undef_result(Dst, opline); @@ -10284,9 +10288,9 @@ static int zend_jit_leave_func(dasm_State **Dst, const zend_op_array *op_array, if (trace) { if (trace->op != ZEND_JIT_TRACE_END && (JIT_G(current_frame) && !TRACE_FRAME_IS_UNKNOWN_RETURN(JIT_G(current_frame)))) { - zend_jit_reset_opline(); + zend_jit_reset_last_valid_opline(); } else { - | LOAD_OPLINE + | LOAD_IP | ADD_IP sizeof(zend_op) } @@ -10322,7 +10326,7 @@ static int zend_jit_leave_func(dasm_State **Dst, const zend_op_array *op_array, | jne ->trace_escape } - last_valid_opline = trace->opline; + zend_jit_set_last_valid_opline(trace->opline); return 1; } else if (may_throw || @@ -10339,7 +10343,7 @@ static int zend_jit_leave_func(dasm_State **Dst, const zend_op_array *op_array, } else { | // if (EG(exception)) | MEM_OP2_1_ZTS cmp, aword, executor_globals, exception, 0, r0 - | LOAD_OPLINE + | LOAD_IP | jne ->leave_throw_handler | // opline = EX(opline) + 1 | ADD_IP sizeof(zend_op) @@ -10738,7 +10742,7 @@ static int zend_jit_fetch_dim_read(dasm_State **Dst, | IF_NOT_ZVAL_TYPE op1_addr, IS_STRING, >6 } } - | SAVE_VALID_OPLINE opline, r0 + | SET_EX_OPLINE opline, r0 if (Z_REG(op1_addr) != ZREG_FCARG1a || Z_OFFSET(op1_addr) != 0) { | LOAD_ZVAL_ADDR FCARG1a, op1_addr } @@ -10772,7 +10776,7 @@ static int zend_jit_fetch_dim_read(dasm_State **Dst, | IF_NOT_ZVAL_TYPE op1_addr, IS_OBJECT, >6 } } - | SAVE_VALID_OPLINE opline, r0 + | SET_EX_OPLINE opline, r0 if (Z_REG(op1_addr) != ZREG_FCARG1a || Z_OFFSET(op1_addr) != 0) { | LOAD_ZVAL_ADDR FCARG1a, op1_addr } @@ -10804,7 +10808,7 @@ static int zend_jit_fetch_dim_read(dasm_State **Dst, } if ((opline->opcode != ZEND_FETCH_DIM_IS && (op1_info & MAY_BE_UNDEF)) || (op2_info & MAY_BE_UNDEF)) { - | SAVE_VALID_OPLINE opline, r0 + | SET_EX_OPLINE opline, r0 if (opline->opcode != ZEND_FETCH_DIM_IS && (op1_info & MAY_BE_UNDEF)) { | IF_NOT_ZVAL_TYPE op1_addr, IS_UNDEF, >1 | // zend_error(E_WARNING, "Undefined variable $%s", ZSTR_VAL(CV_DEF_OF(EX_VAR_TO_NUM(opline->op1.var)))); @@ -10827,7 +10831,7 @@ static int zend_jit_fetch_dim_read(dasm_State **Dst, if ((opline->opcode != ZEND_FETCH_DIM_IS && (op1_info & MAY_BE_UNDEF)) || (op2_info & MAY_BE_UNDEF)) { | LOAD_ZVAL_ADDR FCARG1a, orig_op1_addr } else { - | SAVE_VALID_OPLINE opline, r0 + | SET_EX_OPLINE opline, r0 if (Z_MODE(op1_addr) != IS_MEM_ZVAL || Z_REG(op1_addr) != ZREG_FCARG1a || Z_OFFSET(op1_addr) != 0) { @@ -10978,7 +10982,7 @@ static int zend_jit_isset_isempty_dim(dasm_State **Dst, } if (op1_info & (MAY_BE_STRING|MAY_BE_OBJECT)) { - | SAVE_VALID_OPLINE opline, r0 + | SET_EX_OPLINE opline, r0 if (Z_REG(op1_addr) != ZREG_FCARG1a || Z_OFFSET(op1_addr) != 0) { | LOAD_ZVAL_ADDR FCARG1a, op1_addr } @@ -11216,7 +11220,7 @@ static int zend_jit_verify_arg_type(dasm_State **Dst, const zend_op *opline, zen | LOAD_ZVAL_ADDR FCARG1a, res_addr } if (JIT_G(trigger) == ZEND_JIT_ON_HOT_TRACE) { - | SAVE_VALID_OPLINE opline, r0 + | SET_EX_OPLINE opline, r0 } else { | ADDR_OP2_2 mov, aword EX->opline, opline, r0 } @@ -11273,7 +11277,7 @@ static int zend_jit_recv(dasm_State **Dst, const zend_op *opline, const zend_op_ |.cold_code |1: if (JIT_G(trigger) == ZEND_JIT_ON_HOT_TRACE) { - | SAVE_VALID_OPLINE opline, r0 + | SET_EX_OPLINE opline, r0 } else { | ADDR_OP2_2 mov, aword EX->opline, opline, r0 } @@ -11292,10 +11296,8 @@ static int zend_jit_recv(dasm_State **Dst, const zend_op *opline, const zend_op_ if (JIT_G(trigger) != ZEND_JIT_ON_HOT_TRACE) { if ((opline+1)->opcode != ZEND_RECV && (opline+1)->opcode != ZEND_RECV_INIT) { - last_valid_opline = NULL; - if (!zend_jit_set_valid_ip(Dst, opline + 1)) { - return 0; - } + | LOAD_IP_ADDR (opline + 1) + zend_jit_set_last_valid_opline(opline + 1); } } @@ -11320,7 +11322,7 @@ static int zend_jit_recv_init(dasm_State **Dst, const zend_op *opline, const zen if (Z_CONSTANT_P(zv)) { if (JIT_G(trigger) == ZEND_JIT_ON_HOT_TRACE) { - | SAVE_VALID_OPLINE opline, r0 + | SET_EX_OPLINE opline, r0 } else { | ADDR_OP2_2 mov, aword EX->opline, opline, r0 } @@ -11373,7 +11375,7 @@ static int zend_jit_recv_init(dasm_State **Dst, const zend_op *opline, const zen if (JIT_G(trigger) != ZEND_JIT_ON_HOT_TRACE) { if (is_last) { | LOAD_IP_ADDR (opline + 1) - last_valid_opline = (opline + 1); + zend_jit_set_last_valid_opline(opline + 1); } } @@ -11594,7 +11596,7 @@ static int zend_jit_fetch_obj(dasm_State **Dst, |.cold_code |1: if (flags == ZEND_FETCH_DIM_WRITE) { - | SAVE_VALID_OPLINE opline, r0 + | SET_EX_OPLINE opline, r0 | EXT_CALL zend_jit_check_array_promotion, r0 | jmp >9 } else if (flags == ZEND_FETCH_REF) { @@ -11646,7 +11648,7 @@ static int zend_jit_fetch_obj(dasm_State **Dst, | LOAD_ZVAL_ADDR FCARG1a, prop_addr } | LOAD_ADDR FCARG2a, prop_info - | SAVE_VALID_OPLINE opline, r0 + | SET_EX_OPLINE opline, r0 | EXT_CALL zend_jit_check_array_promotion, r0 | jmp >9 |.code @@ -11760,7 +11762,7 @@ static int zend_jit_fetch_obj(dasm_State **Dst, if (JIT_G(trigger) != ZEND_JIT_ON_HOT_TRACE || !prop_info) { |5: - | SAVE_VALID_OPLINE opline, r0 + | SET_EX_OPLINE opline, r0 if (opline->opcode == ZEND_FETCH_OBJ_W) { | EXT_CALL zend_jit_fetch_obj_w_slow, r0 } else if (opline->opcode != ZEND_FETCH_OBJ_IS) { @@ -11774,7 +11776,7 @@ static int zend_jit_fetch_obj(dasm_State **Dst, if ((op1_info & ((MAY_BE_UNDEF|MAY_BE_ANY|MAY_BE_REF)- MAY_BE_OBJECT)) && JIT_G(trigger) != ZEND_JIT_ON_HOT_TRACE) { |7: if (opline->opcode != ZEND_FETCH_OBJ_IS) { - | SAVE_VALID_OPLINE opline, r0 + | SET_EX_OPLINE opline, r0 if (opline->opcode != ZEND_FETCH_OBJ_W && (op1_info & MAY_BE_UNDEF)) { zend_jit_addr orig_op1_addr = OP1_ADDR(); @@ -11809,7 +11811,7 @@ static int zend_jit_fetch_obj(dasm_State **Dst, && opline->opcode != ZEND_FETCH_OBJ_W) { |8: | mov FCARG2a, r0 - | SAVE_VALID_OPLINE opline, r0 + | SET_EX_OPLINE opline, r0 if (opline->opcode != ZEND_FETCH_OBJ_IS) { | EXT_CALL zend_jit_fetch_obj_r_dynamic, r0 } else { @@ -11830,7 +11832,7 @@ static int zend_jit_fetch_obj(dasm_State **Dst, | GET_ZVAL_PTR FCARG1a, orig_op1_addr | GC_DELREF FCARG1a | jnz >1 - | SAVE_VALID_OPLINE opline, r0 + | SET_EX_OPLINE opline, r0 | EXT_CALL zend_jit_extract_helper, r0 |1: } else if (!op1_avoid_refcounting) { @@ -11860,7 +11862,7 @@ static int zend_jit_free(dasm_State **Dst, const zend_op *opline, uint32_t op1_i if (op1_info & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_REF)) { if (may_throw) { - | SAVE_VALID_OPLINE opline, r0 + | SET_EX_OPLINE opline, r0 } if (opline->opcode == ZEND_FE_FREE && (op1_info & (MAY_BE_OBJECT|MAY_BE_REF))) { if (op1_info & MAY_BE_ARRAY) { @@ -11896,7 +11898,7 @@ static int zend_jit_echo(dasm_State **Dst, const zend_op *opline, uint32_t op1_i if (len > 0) { const char *str = Z_STRVAL_P(zv); - | SAVE_VALID_OPLINE opline, r0 + | SET_EX_OPLINE opline, r0 |.if X64 | LOAD_ADDR CARG1, str | LOAD_ADDR CARG2, len @@ -11917,7 +11919,7 @@ static int zend_jit_echo(dasm_State **Dst, const zend_op *opline, uint32_t op1_i ZEND_ASSERT((op1_info & (MAY_BE_UNDEF|MAY_BE_ANY|MAY_BE_REF)) == MAY_BE_STRING); - | SAVE_VALID_OPLINE opline, r0 + | SET_EX_OPLINE opline, r0 | GET_ZVAL_PTR r0, op1_addr |.if X64 | lea CARG1, aword [r0 + offsetof(zend_string, val)] @@ -12006,7 +12008,7 @@ static int zend_jit_fetch_this(dasm_State **Dst, const zend_op *opline, const ze | jne >1 |.cold_code |1: - | SAVE_VALID_OPLINE opline, r0 + | SET_EX_OPLINE opline, r0 | jmp ->invalid_this |.code } @@ -12369,7 +12371,7 @@ static int zend_jit_switch(dasm_State **Dst, const zend_op *opline, const zend_o } } | // zend_error(E_WARNING, "Undefined variable $%s", ZSTR_VAL(CV_DEF_OF(EX_VAR_TO_NUM(opline->op1.var)))); - | SAVE_VALID_OPLINE opline, r0 + | SET_EX_OPLINE opline, r0 | mov FCARG1d, opline->op1.var | EXT_CALL zend_jit_undefined_op_helper, r0 if (!zend_jit_check_exception_undef_result(Dst, opline)) { @@ -12423,7 +12425,7 @@ static zend_bool zend_jit_verify_return_type(dasm_State **Dst, const zend_op *op |.cold_code |7: } - | SAVE_VALID_OPLINE opline, r1 + | SET_EX_OPLINE opline, r1 if (op1_info & MAY_BE_UNDEF) { | IF_NOT_ZVAL_TYPE op1_addr, IS_UNDEF, >8 | mov FCARG1a, opline->op1.var @@ -12705,7 +12707,7 @@ static int zend_jit_fetch_constant(dasm_State **Dst, const zend_op *opline) |.cold_code |9: | // SAVE_OPLINE(); - | SAVE_VALID_OPLINE opline, r0 + | SET_EX_OPLINE opline, r0 | // zend_quick_get_constant(RT_CONSTANT(opline, opline->op2) + 1, opline->op1.num OPLINE_CC EXECUTE_DATA_CC); | LOAD_ADDR FCARG1a, zv | mov FCARG2a, opline->op1.num From 56a9eeda65cf61402cf812880cca97a491512220 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 4 Sep 2020 11:42:13 +0300 Subject: [PATCH 53/87] Avoid unnecessary IP initiliaization on trace linking --- ext/opcache/jit/zend_jit_internal.h | 1 + ext/opcache/jit/zend_jit_trace.c | 83 ++++++++++++++++++++++------- ext/opcache/jit/zend_jit_x86.dasc | 73 +++++++++++++++++-------- 3 files changed, 116 insertions(+), 41 deletions(-) diff --git a/ext/opcache/jit/zend_jit_internal.h b/ext/opcache/jit/zend_jit_internal.h index bcbafad147986..18a3096204959 100644 --- a/ext/opcache/jit/zend_jit_internal.h +++ b/ext/opcache/jit/zend_jit_internal.h @@ -348,6 +348,7 @@ typedef union _zend_jit_trace_stack { /* trace info flags */ #define ZEND_JIT_TRACE_CHECK_INTERRUPT (1<<0) #define ZEND_JIT_TRACE_LOOP (1<<1) +#define ZEND_JIT_TRACE_USES_INITIAL_IP (1<<2) typedef struct _zend_jit_trace_info { uint32_t id; /* trace id */ diff --git a/ext/opcache/jit/zend_jit_trace.c b/ext/opcache/jit/zend_jit_trace.c index b922655e37641..5e09b2dd7c5e5 100644 --- a/ext/opcache/jit/zend_jit_trace.c +++ b/ext/opcache/jit/zend_jit_trace.c @@ -3088,7 +3088,6 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par zend_uchar res_type = IS_UNKNOWN; const zend_op *opline, *orig_opline; const zend_ssa_op *ssa_op, *orig_ssa_op; - const void *timeout_exit_addr = NULL; JIT_G(current_trace) = trace_buffer; @@ -3142,6 +3141,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par if (!parent_trace) { zend_jit_set_last_valid_opline(opline); + zend_jit_track_last_valid_opline(); } else { if (zend_jit_traces[parent_trace].exit_info[exit_num].opline == NULL) { zend_jit_trace_opline_guard(&dasm_state, opline); @@ -3273,18 +3273,16 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par } } - if (trace_buffer->stop != ZEND_JIT_TRACE_STOP_RECURSIVE_RET) { - if (ra && zend_jit_trace_stack_needs_deoptimization(stack, op_array->last_var + op_array->T)) { - uint32_t exit_point = zend_jit_trace_get_exit_point(NULL, ZEND_JIT_EXIT_TO_VM); - - timeout_exit_addr = zend_jit_trace_get_exit_addr(exit_point); - if (!timeout_exit_addr) { - goto jit_failure; - } - } else { - timeout_exit_addr = dasm_labels[zend_lbinterrupt_handler]; - } - } +// if (trace_buffer->stop != ZEND_JIT_TRACE_STOP_RECURSIVE_RET) { +// if (ra && zend_jit_trace_stack_needs_deoptimization(stack, op_array->last_var + op_array->T)) { +// uint32_t exit_point = zend_jit_trace_get_exit_point(opline, ZEND_JIT_EXIT_TO_VM); +// +// timeout_exit_addr = zend_jit_trace_get_exit_addr(exit_point); +// if (!timeout_exit_addr) { +// goto jit_failure; +// } +// } +// } if (ra && trace_buffer->stop != ZEND_JIT_TRACE_STOP_LOOP) { int last_var = op_array->last_var; @@ -5074,11 +5072,17 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par t = &zend_jit_traces[ZEND_JIT_TRACE_NUM]; + if (!parent_trace && zend_jit_trace_uses_initial_ip()) { + t->flags |= ZEND_JIT_TRACE_USES_INITIAL_IP; + } + if (p->stop == ZEND_JIT_TRACE_STOP_LOOP || p->stop == ZEND_JIT_TRACE_STOP_RECURSIVE_CALL || p->stop == ZEND_JIT_TRACE_STOP_RECURSIVE_RET) { if (p->stop != ZEND_JIT_TRACE_STOP_RECURSIVE_RET) { - if (!zend_jit_set_ip(&dasm_state, p->opline)) { + ZEND_ASSERT(!parent_trace); + if ((t->flags & ZEND_JIT_TRACE_USES_INITIAL_IP) + && !zend_jit_set_ip(&dasm_state, p->opline)) { goto jit_failure; } } @@ -5087,7 +5091,25 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par t->flags |= ZEND_JIT_TRACE_CHECK_INTERRUPT; } if (!(t->flags & ZEND_JIT_TRACE_LOOP)) { + const void *timeout_exit_addr = NULL; + t->flags |= ZEND_JIT_TRACE_LOOP; + + if (trace_buffer->stop != ZEND_JIT_TRACE_STOP_RECURSIVE_RET) { + if (!(t->flags & ZEND_JIT_TRACE_USES_INITIAL_IP) + || (ra + && zend_jit_trace_stack_needs_deoptimization(stack, op_array->last_var + op_array->T))) { + uint32_t exit_point = zend_jit_trace_get_exit_point(opline, ZEND_JIT_EXIT_TO_VM); + + timeout_exit_addr = zend_jit_trace_get_exit_addr(exit_point); + if (!timeout_exit_addr) { + goto jit_failure; + } + } else { + timeout_exit_addr = dasm_labels[zend_lbinterrupt_handler]; + } + } + zend_jit_trace_end_loop(&dasm_state, 0, timeout_exit_addr); /* jump back to start of the trace loop */ } } else if (p->stop == ZEND_JIT_TRACE_STOP_LINK @@ -5097,14 +5119,35 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par goto jit_failure; } if (p->stop == ZEND_JIT_TRACE_STOP_LINK) { - if (!zend_jit_set_ip(&dasm_state, p->opline)) { + const void *timeout_exit_addr = NULL; + + t->link = zend_jit_find_trace(p->opline->handler); + if ((zend_jit_traces[t->link].flags & ZEND_JIT_TRACE_USES_INITIAL_IP) + && !zend_jit_set_ip(&dasm_state, p->opline)) { goto jit_failure; } - t->link = zend_jit_find_trace(p->opline->handler); - zend_jit_trace_link_to_root(&dasm_state, &zend_jit_traces[t->link], - parent_trace && - (zend_jit_traces[t->link].flags & ZEND_JIT_TRACE_CHECK_INTERRUPT) && - zend_jit_traces[parent_trace].root == t->link); + if (!parent_trace && zend_jit_trace_uses_initial_ip()) { + t->flags |= ZEND_JIT_TRACE_USES_INITIAL_IP; + } + if (parent_trace + && (zend_jit_traces[t->link].flags & ZEND_JIT_TRACE_CHECK_INTERRUPT) + && zend_jit_traces[parent_trace].root == t->link) { + if (!(zend_jit_traces[t->link].flags & ZEND_JIT_TRACE_USES_INITIAL_IP)) { + uint32_t exit_point; + + for (i = 0; i < op_array->last_var + op_array->T; i++) { + SET_STACK_TYPE(stack, i, IS_UNKNOWN); + } + exit_point = zend_jit_trace_get_exit_point(opline, ZEND_JIT_EXIT_TO_VM); + timeout_exit_addr = zend_jit_trace_get_exit_addr(exit_point); + if (!timeout_exit_addr) { + goto jit_failure; + } + } else { + timeout_exit_addr = dasm_labels[zend_lbinterrupt_handler]; + } + } + zend_jit_trace_link_to_root(&dasm_state, &zend_jit_traces[t->link], timeout_exit_addr); } else { zend_jit_trace_return(&dasm_state, 0); } diff --git a/ext/opcache/jit/zend_jit_x86.dasc b/ext/opcache/jit/zend_jit_x86.dasc index afb51163dd8ac..566c052181378 100644 --- a/ext/opcache/jit/zend_jit_x86.dasc +++ b/ext/opcache/jit/zend_jit_x86.dasc @@ -1340,11 +1340,12 @@ static void* dasm_labels[zend_lb_MAX]; |.macro SET_EX_OPLINE, op, tmp_reg || if (op == last_valid_opline) { +|| zend_jit_use_last_valid_opline(); | SAVE_IP || } else { | ADDR_OP2_2 mov, aword EX->opline, op, tmp_reg || if (!GCC_GLOBAL_REGS) { -|| last_valid_opline = NULL; +|| zend_jit_reset_last_valid_opline(); || } || } |.endmacro @@ -1578,6 +1579,7 @@ static void* dasm_labels[zend_lb_MAX]; |.macro UNDEFINED_OFFSET, opline || if (opline == last_valid_opline) { +|| zend_jit_use_last_valid_opline(); | call ->undefined_offset_ex || } else { | SET_EX_OPLINE opline, r0 @@ -1587,6 +1589,7 @@ static void* dasm_labels[zend_lb_MAX]; |.macro UNDEFINED_INDEX, opline || if (opline == last_valid_opline) { +|| zend_jit_use_last_valid_opline(); | call ->undefined_index_ex || } else { | SET_EX_OPLINE opline, r0 @@ -1596,6 +1599,7 @@ static void* dasm_labels[zend_lb_MAX]; |.macro CANNOT_ADD_ELEMENT, opline || if (opline == last_valid_opline) { +|| zend_jit_use_last_valid_opline(); | call ->cannot_add_element_ex || } else { | SET_EX_OPLINE opline, r0 @@ -1603,31 +1607,56 @@ static void* dasm_labels[zend_lb_MAX]; || } |.endmacro -static zend_bool reuse_ip; -static zend_bool delayed_call_chain; -static uint32_t delayed_call_level; -static const zend_op *last_valid_opline; -static int jit_return_label; -static uint32_t current_trace_num; +static zend_bool reuse_ip = 0; +static zend_bool delayed_call_chain = 0; +static uint32_t delayed_call_level = 0; +static const zend_op *last_valid_opline = NULL; +static zend_bool use_last_vald_opline = 0; +static zend_bool track_last_valid_opline = 0; +static int jit_return_label = -1; +static uint32_t current_trace_num = 0; + +static void zend_jit_track_last_valid_opline(void) +{ + use_last_vald_opline = 0; + track_last_valid_opline = 1; +} + +static void zend_jit_use_last_valid_opline(void) +{ + if (track_last_valid_opline) { + use_last_vald_opline = 1; + track_last_valid_opline = 0; + } +} + +static zend_bool zend_jit_trace_uses_initial_ip(void) +{ + return use_last_vald_opline; +} static void zend_jit_set_last_valid_opline(const zend_op *target_opline) { if (!reuse_ip) { + track_last_valid_opline = 0; last_valid_opline = target_opline; } } static void zend_jit_reset_last_valid_opline(void) { + track_last_valid_opline = 0; last_valid_opline = NULL; } -static void zend_jit_start_reuse_ip(void) { - last_valid_opline = NULL; +static void zend_jit_start_reuse_ip(void) +{ + zend_jit_reset_last_valid_opline(); reuse_ip = 1; } -static void zend_jit_stop_reuse_ip(void) { +static void zend_jit_stop_reuse_ip(void) +{ reuse_ip = 0; } @@ -2804,6 +2833,8 @@ static int zend_jit_align_func(dasm_State **Dst) reuse_ip = 0; delayed_call_chain = 0; last_valid_opline = NULL; + use_last_vald_opline = 0; + track_last_valid_opline = 0; jit_return_label = -1; |.align 16 return 1; @@ -2849,16 +2880,15 @@ static int zend_jit_save_call_chain(dasm_State **Dst, uint32_t call_level) static int zend_jit_set_ip(dasm_State **Dst, const zend_op *opline) { - if (!last_valid_opline) { + if (last_valid_opline == opline) { + zend_jit_use_last_valid_opline(); + } else if (GCC_GLOBAL_REGS && last_valid_opline) { + zend_jit_use_last_valid_opline(); + | ADD_IP (opline - last_valid_opline) * sizeof(zend_op); + } else { | LOAD_IP_ADDR opline - } else if (last_valid_opline != opline) { - if (GCC_GLOBAL_REGS) { - | ADD_IP (opline - last_valid_opline) * sizeof(zend_op); - } else { - | LOAD_IP_ADDR opline - } } - last_valid_opline = opline; + zend_jit_set_last_valid_opline(opline); return 1; } @@ -2890,6 +2920,7 @@ static int zend_jit_check_timeout(dasm_State **Dst, const zend_op *opline, const if (exit_addr) { | jne &exit_addr } else if (last_valid_opline == opline) { + || zend_jit_use_last_valid_opline(); | jne ->interrupt_handler } else { | jne >1 @@ -3154,7 +3185,7 @@ static int zend_jit_link_side_trace(const void *code, size_t size, uint32_t jmp_ return zend_jit_patch(code, size, jmp_table_size, zend_jit_trace_get_exit_addr(exit_num), addr); } -static int zend_jit_trace_link_to_root(dasm_State **Dst, zend_jit_trace_info *t, zend_bool check_interrupt) +static int zend_jit_trace_link_to_root(dasm_State **Dst, zend_jit_trace_info *t, const void *timeout_exit_addr) { const void *link_addr; size_t prologue_size; @@ -3188,11 +3219,11 @@ static int zend_jit_trace_link_to_root(dasm_State **Dst, zend_jit_trace_info *t, } link_addr = (const void*)((const char*)t->code_start + prologue_size); - if (check_interrupt) { + if (timeout_exit_addr) { /* Check timeout for links to LOOP */ | MEM_OP2_1_ZTS cmp, byte, executor_globals, vm_interrupt, 0, r0 | je &link_addr - | jmp ->interrupt_handler + | jmp &timeout_exit_addr } else { | jmp &link_addr } From e8d36ce7622c58100d8559b4603fc95d9d8cbd49 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Fri, 4 Sep 2020 10:58:51 +0200 Subject: [PATCH 54/87] Avoid duplicate octal warning during heredoc scan ahead --- .../warning_during_heredoc_scan_ahead.phpt | 3 + Zend/zend_language_scanner.c | 699 +++++++++--------- Zend/zend_language_scanner.l | 3 +- 3 files changed, 353 insertions(+), 352 deletions(-) diff --git a/Zend/tests/warning_during_heredoc_scan_ahead.phpt b/Zend/tests/warning_during_heredoc_scan_ahead.phpt index 099d1c087ffae..c252be1f4f28c 100644 --- a/Zend/tests/warning_during_heredoc_scan_ahead.phpt +++ b/Zend/tests/warning_during_heredoc_scan_ahead.phpt @@ -6,6 +6,7 @@ No warnings should be thrown during heredoc scan-ahead << '3')) { + if (octal_buf[2] && (octal_buf[0] > '3') && !SCNG(heredoc_scan_ahead)) { /* 3 octit values must not overflow 0xFF (\377) */ zend_error(E_COMPILE_WARNING, "Octal escape sequence overflow \\%s is greater than \\377", octal_buf); } @@ -1247,7 +1246,7 @@ int start_line = CG(zend_lineno); SCNG(yy_text) = YYCURSOR; -#line 1251 "Zend/zend_language_scanner.c" +#line 1250 "Zend/zend_language_scanner.c" { YYCTYPE yych; unsigned int yyaccept = 0; @@ -1455,7 +1454,7 @@ int start_line = CG(zend_lineno); ++YYCURSOR; YYDEBUG(4, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2769 "Zend/zend_language_scanner.l" +#line 2768 "Zend/zend_language_scanner.l" { if (YYCURSOR > YYLIMIT) { RETURN_TOKEN(END); @@ -1466,7 +1465,7 @@ int start_line = CG(zend_lineno); } goto restart; } -#line 1470 "Zend/zend_language_scanner.c" +#line 1469 "Zend/zend_language_scanner.c" yy5: YYDEBUG(5, *YYCURSOR); ++YYCURSOR; @@ -1478,11 +1477,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(7, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1430 "Zend/zend_language_scanner.l" +#line 1429 "Zend/zend_language_scanner.l" { goto return_whitespace; } -#line 1486 "Zend/zend_language_scanner.c" +#line 1485 "Zend/zend_language_scanner.c" yy8: YYDEBUG(8, *YYCURSOR); yych = *++YYCURSOR; @@ -1490,17 +1489,17 @@ int start_line = CG(zend_lineno); yy9: YYDEBUG(9, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1713 "Zend/zend_language_scanner.l" +#line 1712 "Zend/zend_language_scanner.l" { RETURN_TOKEN(yytext[0]); } -#line 1498 "Zend/zend_language_scanner.c" +#line 1497 "Zend/zend_language_scanner.c" yy10: YYDEBUG(10, *YYCURSOR); ++YYCURSOR; YYDEBUG(11, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2225 "Zend/zend_language_scanner.l" +#line 2224 "Zend/zend_language_scanner.l" { int bprefix = (yytext[0] != '"') ? 1 : 0; @@ -1545,13 +1544,13 @@ int start_line = CG(zend_lineno); BEGIN(ST_DOUBLE_QUOTES); RETURN_TOKEN('"'); } -#line 1549 "Zend/zend_language_scanner.c" +#line 1548 "Zend/zend_language_scanner.c" yy12: YYDEBUG(12, *YYCURSOR); ++YYCURSOR; YYDEBUG(13, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2052 "Zend/zend_language_scanner.l" +#line 2051 "Zend/zend_language_scanner.l" { while (YYCURSOR < YYLIMIT) { switch (*YYCURSOR++) { @@ -1583,7 +1582,7 @@ int start_line = CG(zend_lineno); } RETURN_TOKEN(T_COMMENT); } -#line 1587 "Zend/zend_language_scanner.c" +#line 1586 "Zend/zend_language_scanner.c" yy14: YYDEBUG(14, *YYCURSOR); yych = *++YYCURSOR; @@ -1614,7 +1613,7 @@ int start_line = CG(zend_lineno); ++YYCURSOR; YYDEBUG(18, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2135 "Zend/zend_language_scanner.l" +#line 2134 "Zend/zend_language_scanner.l" { register char *s, *t; char *end; @@ -1703,7 +1702,7 @@ int start_line = CG(zend_lineno); } RETURN_TOKEN_WITH_VAL(T_CONSTANT_ENCAPSED_STRING); } -#line 1707 "Zend/zend_language_scanner.c" +#line 1706 "Zend/zend_language_scanner.c" yy19: YYDEBUG(19, *YYCURSOR); yyaccept = 0; @@ -1827,7 +1826,7 @@ int start_line = CG(zend_lineno); yy27: YYDEBUG(27, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1782 "Zend/zend_language_scanner.l" +#line 1781 "Zend/zend_language_scanner.l" { char *end; if (yyleng < MAX_LENGTH_OF_LONG - 1) { /* Won't overflow */ @@ -1879,7 +1878,7 @@ int start_line = CG(zend_lineno); ZEND_ASSERT(!errno); RETURN_TOKEN_WITH_VAL(T_LNUMBER); } -#line 1883 "Zend/zend_language_scanner.c" +#line 1882 "Zend/zend_language_scanner.c" yy28: YYDEBUG(28, *YYCURSOR); yyaccept = 1; @@ -1961,11 +1960,11 @@ int start_line = CG(zend_lineno); yy36: YYDEBUG(36, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2047 "Zend/zend_language_scanner.l" +#line 2046 "Zend/zend_language_scanner.l" { RETURN_TOKEN_WITH_STR(T_STRING, 0); } -#line 1969 "Zend/zend_language_scanner.c" +#line 1968 "Zend/zend_language_scanner.c" yy37: YYDEBUG(37, *YYCURSOR); yyaccept = 2; @@ -2250,11 +2249,11 @@ int start_line = CG(zend_lineno); ++YYCURSOR; YYDEBUG(59, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1453 "Zend/zend_language_scanner.l" +#line 1452 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_NS_SEPARATOR); } -#line 2258 "Zend/zend_language_scanner.c" +#line 2257 "Zend/zend_language_scanner.c" yy60: YYDEBUG(60, *YYCURSOR); yych = *++YYCURSOR; @@ -2270,23 +2269,23 @@ int start_line = CG(zend_lineno); ++YYCURSOR; YYDEBUG(63, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2416 "Zend/zend_language_scanner.l" +#line 2415 "Zend/zend_language_scanner.l" { BEGIN(ST_BACKQUOTE); RETURN_TOKEN('`'); } -#line 2279 "Zend/zend_language_scanner.c" +#line 2278 "Zend/zend_language_scanner.c" yy64: YYDEBUG(64, *YYCURSOR); ++YYCURSOR; YYDEBUG(65, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1718 "Zend/zend_language_scanner.l" +#line 1717 "Zend/zend_language_scanner.l" { yy_push_state(ST_IN_SCRIPTING); RETURN_TOKEN('{'); } -#line 2290 "Zend/zend_language_scanner.c" +#line 2289 "Zend/zend_language_scanner.c" yy66: YYDEBUG(66, *YYCURSOR); yych = *++YYCURSOR; @@ -2298,7 +2297,7 @@ int start_line = CG(zend_lineno); ++YYCURSOR; YYDEBUG(68, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1730 "Zend/zend_language_scanner.l" +#line 1729 "Zend/zend_language_scanner.l" { RESET_DOC_COMMENT(); if (!zend_stack_is_empty(&SCNG(state_stack))) { @@ -2306,7 +2305,7 @@ int start_line = CG(zend_lineno); } RETURN_TOKEN('}'); } -#line 2310 "Zend/zend_language_scanner.c" +#line 2309 "Zend/zend_language_scanner.c" yy69: YYDEBUG(69, *YYCURSOR); yych = *++YYCURSOR; @@ -2314,11 +2313,11 @@ int start_line = CG(zend_lineno); yy70: YYDEBUG(70, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1617 "Zend/zend_language_scanner.l" +#line 1616 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_IS_NOT_EQUAL); } -#line 2322 "Zend/zend_language_scanner.c" +#line 2321 "Zend/zend_language_scanner.c" yy71: YYDEBUG(71, *YYCURSOR); ++YYCURSOR; @@ -2343,41 +2342,41 @@ int start_line = CG(zend_lineno); yy73: YYDEBUG(73, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2025 "Zend/zend_language_scanner.l" +#line 2024 "Zend/zend_language_scanner.l" { RETURN_TOKEN_WITH_STR(T_VARIABLE, 1); } -#line 2351 "Zend/zend_language_scanner.c" +#line 2350 "Zend/zend_language_scanner.c" yy74: YYDEBUG(74, *YYCURSOR); ++YYCURSOR; YYDEBUG(75, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1661 "Zend/zend_language_scanner.l" +#line 1660 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_MOD_EQUAL); } -#line 2361 "Zend/zend_language_scanner.c" +#line 2360 "Zend/zend_language_scanner.c" yy76: YYDEBUG(76, *YYCURSOR); ++YYCURSOR; YYDEBUG(77, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1689 "Zend/zend_language_scanner.l" +#line 1688 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_BOOLEAN_AND); } -#line 2371 "Zend/zend_language_scanner.c" +#line 2370 "Zend/zend_language_scanner.c" yy78: YYDEBUG(78, *YYCURSOR); ++YYCURSOR; YYDEBUG(79, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1673 "Zend/zend_language_scanner.l" +#line 1672 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_AND_EQUAL); } -#line 2381 "Zend/zend_language_scanner.c" +#line 2380 "Zend/zend_language_scanner.c" yy80: YYDEBUG(80, *YYCURSOR); ++YYCURSOR; @@ -2507,72 +2506,72 @@ int start_line = CG(zend_lineno); if (yych == '=') goto yy205; YYDEBUG(93, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1645 "Zend/zend_language_scanner.l" +#line 1644 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_POW); } -#line 2515 "Zend/zend_language_scanner.c" +#line 2514 "Zend/zend_language_scanner.c" yy94: YYDEBUG(94, *YYCURSOR); ++YYCURSOR; YYDEBUG(95, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1641 "Zend/zend_language_scanner.l" +#line 1640 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_MUL_EQUAL); } -#line 2525 "Zend/zend_language_scanner.c" +#line 2524 "Zend/zend_language_scanner.c" yy96: YYDEBUG(96, *YYCURSOR); ++YYCURSOR; YYDEBUG(97, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1597 "Zend/zend_language_scanner.l" +#line 1596 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_INC); } -#line 2535 "Zend/zend_language_scanner.c" +#line 2534 "Zend/zend_language_scanner.c" yy98: YYDEBUG(98, *YYCURSOR); ++YYCURSOR; YYDEBUG(99, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1633 "Zend/zend_language_scanner.l" +#line 1632 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_PLUS_EQUAL); } -#line 2545 "Zend/zend_language_scanner.c" +#line 2544 "Zend/zend_language_scanner.c" yy100: YYDEBUG(100, *YYCURSOR); ++YYCURSOR; YYDEBUG(101, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1601 "Zend/zend_language_scanner.l" +#line 1600 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_DEC); } -#line 2555 "Zend/zend_language_scanner.c" +#line 2554 "Zend/zend_language_scanner.c" yy102: YYDEBUG(102, *YYCURSOR); ++YYCURSOR; YYDEBUG(103, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1637 "Zend/zend_language_scanner.l" +#line 1636 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_MINUS_EQUAL); } -#line 2565 "Zend/zend_language_scanner.c" +#line 2564 "Zend/zend_language_scanner.c" yy104: YYDEBUG(104, *YYCURSOR); ++YYCURSOR; YYDEBUG(105, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1425 "Zend/zend_language_scanner.l" +#line 1424 "Zend/zend_language_scanner.l" { yy_push_state(ST_LOOKING_FOR_PROPERTY); RETURN_TOKEN(T_OBJECT_OPERATOR); } -#line 2576 "Zend/zend_language_scanner.c" +#line 2575 "Zend/zend_language_scanner.c" yy106: YYDEBUG(106, *YYCURSOR); yych = *++YYCURSOR; @@ -2595,7 +2594,7 @@ int start_line = CG(zend_lineno); yy109: YYDEBUG(109, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1887 "Zend/zend_language_scanner.l" +#line 1886 "Zend/zend_language_scanner.l" { const char *end; @@ -2604,17 +2603,17 @@ int start_line = CG(zend_lineno); ZEND_ASSERT(end == yytext + yyleng); RETURN_TOKEN_WITH_VAL(T_DNUMBER); } -#line 2608 "Zend/zend_language_scanner.c" +#line 2607 "Zend/zend_language_scanner.c" yy110: YYDEBUG(110, *YYCURSOR); ++YYCURSOR; YYDEBUG(111, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1657 "Zend/zend_language_scanner.l" +#line 1656 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_CONCAT_EQUAL); } -#line 2618 "Zend/zend_language_scanner.c" +#line 2617 "Zend/zend_language_scanner.c" yy112: YYDEBUG(112, *YYCURSOR); yyaccept = 4; @@ -2623,7 +2622,7 @@ int start_line = CG(zend_lineno); yy113: YYDEBUG(113, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2084 "Zend/zend_language_scanner.l" +#line 2083 "Zend/zend_language_scanner.l" { int doc_com; @@ -2662,17 +2661,17 @@ int start_line = CG(zend_lineno); } RETURN_TOKEN(T_COMMENT); } -#line 2666 "Zend/zend_language_scanner.c" +#line 2665 "Zend/zend_language_scanner.c" yy114: YYDEBUG(114, *YYCURSOR); ++YYCURSOR; YYDEBUG(115, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1653 "Zend/zend_language_scanner.l" +#line 1652 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_DIV_EQUAL); } -#line 2676 "Zend/zend_language_scanner.c" +#line 2675 "Zend/zend_language_scanner.c" yy116: YYDEBUG(116, *YYCURSOR); yych = *++YYCURSOR; @@ -2704,11 +2703,11 @@ int start_line = CG(zend_lineno); ++YYCURSOR; YYDEBUG(120, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1449 "Zend/zend_language_scanner.l" +#line 1448 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_PAAMAYIM_NEKUDOTAYIM); } -#line 2712 "Zend/zend_language_scanner.c" +#line 2711 "Zend/zend_language_scanner.c" yy121: YYDEBUG(121, *YYCURSOR); yyaccept = 5; @@ -2719,22 +2718,22 @@ int start_line = CG(zend_lineno); yy122: YYDEBUG(122, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1705 "Zend/zend_language_scanner.l" +#line 1704 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_SL); } -#line 2727 "Zend/zend_language_scanner.c" +#line 2726 "Zend/zend_language_scanner.c" yy123: YYDEBUG(123, *YYCURSOR); yych = *++YYCURSOR; if (yych == '>') goto yy223; YYDEBUG(124, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1625 "Zend/zend_language_scanner.l" +#line 1624 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_IS_SMALLER_OR_EQUAL); } -#line 2738 "Zend/zend_language_scanner.c" +#line 2737 "Zend/zend_language_scanner.c" yy125: YYDEBUG(125, *YYCURSOR); ++YYCURSOR; @@ -2745,42 +2744,42 @@ int start_line = CG(zend_lineno); if (yych == '=') goto yy225; YYDEBUG(127, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1613 "Zend/zend_language_scanner.l" +#line 1612 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_IS_EQUAL); } -#line 2753 "Zend/zend_language_scanner.c" +#line 2752 "Zend/zend_language_scanner.c" yy128: YYDEBUG(128, *YYCURSOR); ++YYCURSOR; YYDEBUG(129, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1581 "Zend/zend_language_scanner.l" +#line 1580 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_DOUBLE_ARROW); } -#line 2763 "Zend/zend_language_scanner.c" +#line 2762 "Zend/zend_language_scanner.c" yy130: YYDEBUG(130, *YYCURSOR); ++YYCURSOR; YYDEBUG(131, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1629 "Zend/zend_language_scanner.l" +#line 1628 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_IS_GREATER_OR_EQUAL); } -#line 2773 "Zend/zend_language_scanner.c" +#line 2772 "Zend/zend_language_scanner.c" yy132: YYDEBUG(132, *YYCURSOR); yych = *++YYCURSOR; if (yych == '=') goto yy227; YYDEBUG(133, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1709 "Zend/zend_language_scanner.l" +#line 1708 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_SR); } -#line 2784 "Zend/zend_language_scanner.c" +#line 2783 "Zend/zend_language_scanner.c" yy134: YYDEBUG(134, *YYCURSOR); yych = *++YYCURSOR; @@ -2789,7 +2788,7 @@ int start_line = CG(zend_lineno); yy135: YYDEBUG(135, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2123 "Zend/zend_language_scanner.l" +#line 2122 "Zend/zend_language_scanner.l" { BEGIN(INITIAL); if (yytext[yyleng-1] != '>') { @@ -2800,17 +2799,17 @@ int start_line = CG(zend_lineno); } RETURN_TOKEN(T_CLOSE_TAG); } -#line 2804 "Zend/zend_language_scanner.c" +#line 2803 "Zend/zend_language_scanner.c" yy136: YYDEBUG(136, *YYCURSOR); ++YYCURSOR; YYDEBUG(137, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1461 "Zend/zend_language_scanner.l" +#line 1460 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_COALESCE); } -#line 2814 "Zend/zend_language_scanner.c" +#line 2813 "Zend/zend_language_scanner.c" yy138: YYDEBUG(138, *YYCURSOR); yych = *++YYCURSOR; @@ -2837,11 +2836,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(142, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1365 "Zend/zend_language_scanner.l" +#line 1364 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_AS); } -#line 2845 "Zend/zend_language_scanner.c" +#line 2844 "Zend/zend_language_scanner.c" yy143: YYDEBUG(143, *YYCURSOR); yych = *++YYCURSOR; @@ -2927,11 +2926,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(151, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1333 "Zend/zend_language_scanner.l" +#line 1332 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_DO); } -#line 2935 "Zend/zend_language_scanner.c" +#line 2934 "Zend/zend_language_scanner.c" yy152: YYDEBUG(152, *YYCURSOR); yych = *++YYCURSOR; @@ -3016,11 +3015,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(164, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1309 "Zend/zend_language_scanner.l" +#line 1308 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_IF); } -#line 3024 "Zend/zend_language_scanner.c" +#line 3023 "Zend/zend_language_scanner.c" yy165: YYDEBUG(165, *YYCURSOR); yych = *++YYCURSOR; @@ -3081,11 +3080,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(172, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1693 "Zend/zend_language_scanner.l" +#line 1692 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_LOGICAL_OR); } -#line 3089 "Zend/zend_language_scanner.c" +#line 3088 "Zend/zend_language_scanner.c" yy173: YYDEBUG(173, *YYCURSOR); yych = *++YYCURSOR; @@ -3199,11 +3198,11 @@ int start_line = CG(zend_lineno); ++YYCURSOR; YYDEBUG(187, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1681 "Zend/zend_language_scanner.l" +#line 1680 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_XOR_EQUAL); } -#line 3207 "Zend/zend_language_scanner.c" +#line 3206 "Zend/zend_language_scanner.c" yy188: YYDEBUG(188, *YYCURSOR); yych = *++YYCURSOR; @@ -3231,31 +3230,31 @@ int start_line = CG(zend_lineno); ++YYCURSOR; YYDEBUG(190, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1677 "Zend/zend_language_scanner.l" +#line 1676 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_OR_EQUAL); } -#line 3239 "Zend/zend_language_scanner.c" +#line 3238 "Zend/zend_language_scanner.c" yy191: YYDEBUG(191, *YYCURSOR); ++YYCURSOR; YYDEBUG(192, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1685 "Zend/zend_language_scanner.l" +#line 1684 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_BOOLEAN_OR); } -#line 3249 "Zend/zend_language_scanner.c" +#line 3248 "Zend/zend_language_scanner.c" yy193: YYDEBUG(193, *YYCURSOR); ++YYCURSOR; YYDEBUG(194, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1609 "Zend/zend_language_scanner.l" +#line 1608 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_IS_NOT_IDENTICAL); } -#line 3259 "Zend/zend_language_scanner.c" +#line 3258 "Zend/zend_language_scanner.c" yy195: YYDEBUG(195, *YYCURSOR); yych = *++YYCURSOR; @@ -3321,21 +3320,21 @@ int start_line = CG(zend_lineno); ++YYCURSOR; YYDEBUG(206, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1649 "Zend/zend_language_scanner.l" +#line 1648 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_POW_EQUAL); } -#line 3329 "Zend/zend_language_scanner.c" +#line 3328 "Zend/zend_language_scanner.c" yy207: YYDEBUG(207, *YYCURSOR); ++YYCURSOR; YYDEBUG(208, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1457 "Zend/zend_language_scanner.l" +#line 1456 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_ELLIPSIS); } -#line 3339 "Zend/zend_language_scanner.c" +#line 3338 "Zend/zend_language_scanner.c" yy209: YYDEBUG(209, *YYCURSOR); yych = *++YYCURSOR; @@ -3359,7 +3358,7 @@ int start_line = CG(zend_lineno); } YYDEBUG(212, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1754 "Zend/zend_language_scanner.l" +#line 1753 "Zend/zend_language_scanner.l" { char *bin = yytext + 2; /* Skip "0b" */ int len = yyleng - 2; @@ -3387,7 +3386,7 @@ int start_line = CG(zend_lineno); RETURN_TOKEN_WITH_VAL(T_DNUMBER); } } -#line 3391 "Zend/zend_language_scanner.c" +#line 3390 "Zend/zend_language_scanner.c" yy213: YYDEBUG(213, *YYCURSOR); yych = *++YYCURSOR; @@ -3413,7 +3412,7 @@ int start_line = CG(zend_lineno); } YYDEBUG(218, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1834 "Zend/zend_language_scanner.l" +#line 1833 "Zend/zend_language_scanner.l" { char *hex = yytext + 2; /* Skip "0x" */ int len = yyleng - 2; @@ -3441,7 +3440,7 @@ int start_line = CG(zend_lineno); RETURN_TOKEN_WITH_VAL(T_DNUMBER); } } -#line 3445 "Zend/zend_language_scanner.c" +#line 3444 "Zend/zend_language_scanner.c" yy219: YYDEBUG(219, *YYCURSOR); ++YYCURSOR; @@ -3476,41 +3475,41 @@ int start_line = CG(zend_lineno); ++YYCURSOR; YYDEBUG(222, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1665 "Zend/zend_language_scanner.l" +#line 1664 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_SL_EQUAL); } -#line 3484 "Zend/zend_language_scanner.c" +#line 3483 "Zend/zend_language_scanner.c" yy223: YYDEBUG(223, *YYCURSOR); ++YYCURSOR; YYDEBUG(224, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1621 "Zend/zend_language_scanner.l" +#line 1620 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_SPACESHIP); } -#line 3494 "Zend/zend_language_scanner.c" +#line 3493 "Zend/zend_language_scanner.c" yy225: YYDEBUG(225, *YYCURSOR); ++YYCURSOR; YYDEBUG(226, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1605 "Zend/zend_language_scanner.l" +#line 1604 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_IS_IDENTICAL); } -#line 3504 "Zend/zend_language_scanner.c" +#line 3503 "Zend/zend_language_scanner.c" yy227: YYDEBUG(227, *YYCURSOR); ++YYCURSOR; YYDEBUG(228, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1669 "Zend/zend_language_scanner.l" +#line 1668 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_SR_EQUAL); } -#line 3514 "Zend/zend_language_scanner.c" +#line 3513 "Zend/zend_language_scanner.c" yy229: YYDEBUG(229, *YYCURSOR); ++YYCURSOR; @@ -3534,11 +3533,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(233, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1697 "Zend/zend_language_scanner.l" +#line 1696 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_LOGICAL_AND); } -#line 3542 "Zend/zend_language_scanner.c" +#line 3541 "Zend/zend_language_scanner.c" yy234: YYDEBUG(234, *YYCURSOR); yych = *++YYCURSOR; @@ -3619,11 +3618,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(246, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1267 "Zend/zend_language_scanner.l" +#line 1266 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_EXIT); } -#line 3627 "Zend/zend_language_scanner.c" +#line 3626 "Zend/zend_language_scanner.c" yy247: YYDEBUG(247, *YYCURSOR); yych = *++YYCURSOR; @@ -3705,11 +3704,11 @@ int start_line = CG(zend_lineno); yy256: YYDEBUG(256, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1337 "Zend/zend_language_scanner.l" +#line 1336 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_FOR); } -#line 3713 "Zend/zend_language_scanner.c" +#line 3712 "Zend/zend_language_scanner.c" yy257: YYDEBUG(257, *YYCURSOR); yych = *++YYCURSOR; @@ -3778,11 +3777,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(268, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1465 "Zend/zend_language_scanner.l" +#line 1464 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_NEW); } -#line 3786 "Zend/zend_language_scanner.c" +#line 3785 "Zend/zend_language_scanner.c" yy269: YYDEBUG(269, *YYCURSOR); yych = *++YYCURSOR; @@ -3855,11 +3854,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(279, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1293 "Zend/zend_language_scanner.l" +#line 1292 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_TRY); } -#line 3863 "Zend/zend_language_scanner.c" +#line 3862 "Zend/zend_language_scanner.c" yy280: YYDEBUG(280, *YYCURSOR); yych = *++YYCURSOR; @@ -3874,11 +3873,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(282, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1529 "Zend/zend_language_scanner.l" +#line 1528 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_USE); } -#line 3882 "Zend/zend_language_scanner.c" +#line 3881 "Zend/zend_language_scanner.c" yy283: YYDEBUG(283, *YYCURSOR); yych = *++YYCURSOR; @@ -3887,11 +3886,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(284, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1473 "Zend/zend_language_scanner.l" +#line 1472 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_VAR); } -#line 3895 "Zend/zend_language_scanner.c" +#line 3894 "Zend/zend_language_scanner.c" yy285: YYDEBUG(285, *YYCURSOR); yych = *++YYCURSOR; @@ -3906,11 +3905,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(287, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1701 "Zend/zend_language_scanner.l" +#line 1700 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_LOGICAL_XOR); } -#line 3914 "Zend/zend_language_scanner.c" +#line 3913 "Zend/zend_language_scanner.c" yy288: YYDEBUG(288, *YYCURSOR); yych = *++YYCURSOR; @@ -4124,11 +4123,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(318, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1377 "Zend/zend_language_scanner.l" +#line 1376 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_CASE); } -#line 4132 "Zend/zend_language_scanner.c" +#line 4131 "Zend/zend_language_scanner.c" yy319: YYDEBUG(319, *YYCURSOR); yych = *++YYCURSOR; @@ -4179,11 +4178,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(327, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1397 "Zend/zend_language_scanner.l" +#line 1396 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_ECHO); } -#line 4187 "Zend/zend_language_scanner.c" +#line 4186 "Zend/zend_language_scanner.c" yy328: YYDEBUG(328, *YYCURSOR); yych = *++YYCURSOR; @@ -4207,11 +4206,11 @@ int start_line = CG(zend_lineno); yy329: YYDEBUG(329, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1321 "Zend/zend_language_scanner.l" +#line 1320 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_ELSE); } -#line 4215 "Zend/zend_language_scanner.c" +#line 4214 "Zend/zend_language_scanner.c" yy330: YYDEBUG(330, *YYCURSOR); yych = *++YYCURSOR; @@ -4256,11 +4255,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(337, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1505 "Zend/zend_language_scanner.l" +#line 1504 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_EVAL); } -#line 4264 "Zend/zend_language_scanner.c" +#line 4263 "Zend/zend_language_scanner.c" yy338: YYDEBUG(338, *YYCURSOR); yych = *++YYCURSOR; @@ -4269,11 +4268,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(339, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1263 "Zend/zend_language_scanner.l" +#line 1262 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_EXIT); } -#line 4277 "Zend/zend_language_scanner.c" +#line 4276 "Zend/zend_language_scanner.c" yy340: YYDEBUG(340, *YYCURSOR); yych = *++YYCURSOR; @@ -4312,11 +4311,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(346, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1393 "Zend/zend_language_scanner.l" +#line 1392 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_GOTO); } -#line 4320 "Zend/zend_language_scanner.c" +#line 4319 "Zend/zend_language_scanner.c" yy347: YYDEBUG(347, *YYCURSOR); yych = *++YYCURSOR; @@ -4365,11 +4364,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(353, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1585 "Zend/zend_language_scanner.l" +#line 1584 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_LIST); } -#line 4373 "Zend/zend_language_scanner.c" +#line 4372 "Zend/zend_language_scanner.c" yy354: YYDEBUG(354, *YYCURSOR); yych = *++YYCURSOR; @@ -4556,11 +4555,11 @@ int start_line = CG(zend_lineno); ++YYCURSOR; YYDEBUG(385, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1477 "Zend/zend_language_scanner.l" +#line 1476 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_INT_CAST); } -#line 4564 "Zend/zend_language_scanner.c" +#line 4563 "Zend/zend_language_scanner.c" yy386: YYDEBUG(386, *YYCURSOR); yych = *++YYCURSOR; @@ -4657,7 +4656,7 @@ int start_line = CG(zend_lineno); yy397: YYDEBUG(397, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2271 "Zend/zend_language_scanner.l" +#line 2270 "Zend/zend_language_scanner.l" { char *s; unsigned char *saved_cursor; @@ -4801,7 +4800,7 @@ int start_line = CG(zend_lineno); RETURN_TOKEN(T_START_HEREDOC); } -#line 4805 "Zend/zend_language_scanner.c" +#line 4804 "Zend/zend_language_scanner.c" yy398: YYDEBUG(398, *YYCURSOR); yych = *++YYCURSOR; @@ -4821,11 +4820,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(401, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1589 "Zend/zend_language_scanner.l" +#line 1588 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_ARRAY); } -#line 4829 "Zend/zend_language_scanner.c" +#line 4828 "Zend/zend_language_scanner.c" yy402: YYDEBUG(402, *YYCURSOR); yych = *++YYCURSOR; @@ -4834,11 +4833,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(403, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1385 "Zend/zend_language_scanner.l" +#line 1384 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_BREAK); } -#line 4842 "Zend/zend_language_scanner.c" +#line 4841 "Zend/zend_language_scanner.c" yy404: YYDEBUG(404, *YYCURSOR); yych = *++YYCURSOR; @@ -4853,11 +4852,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(406, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1297 "Zend/zend_language_scanner.l" +#line 1296 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_CATCH); } -#line 4861 "Zend/zend_language_scanner.c" +#line 4860 "Zend/zend_language_scanner.c" yy407: YYDEBUG(407, *YYCURSOR); yych = *++YYCURSOR; @@ -4866,11 +4865,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(408, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1405 "Zend/zend_language_scanner.l" +#line 1404 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_CLASS); } -#line 4874 "Zend/zend_language_scanner.c" +#line 4873 "Zend/zend_language_scanner.c" yy409: YYDEBUG(409, *YYCURSOR); yych = *++YYCURSOR; @@ -4879,11 +4878,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(410, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1469 "Zend/zend_language_scanner.l" +#line 1468 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_CLONE); } -#line 4887 "Zend/zend_language_scanner.c" +#line 4886 "Zend/zend_language_scanner.c" yy411: YYDEBUG(411, *YYCURSOR); yych = *++YYCURSOR; @@ -4892,11 +4891,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(412, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1275 "Zend/zend_language_scanner.l" +#line 1274 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_CONST); } -#line 4900 "Zend/zend_language_scanner.c" +#line 4899 "Zend/zend_language_scanner.c" yy413: YYDEBUG(413, *YYCURSOR); yych = *++YYCURSOR; @@ -4929,11 +4928,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(418, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1545 "Zend/zend_language_scanner.l" +#line 1544 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_EMPTY); } -#line 4937 "Zend/zend_language_scanner.c" +#line 4936 "Zend/zend_language_scanner.c" yy419: YYDEBUG(419, *YYCURSOR); yych = *++YYCURSOR; @@ -4954,11 +4953,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(422, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1317 "Zend/zend_language_scanner.l" +#line 1316 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_ENDIF); } -#line 4962 "Zend/zend_language_scanner.c" +#line 4961 "Zend/zend_language_scanner.c" yy423: YYDEBUG(423, *YYCURSOR); yych = *++YYCURSOR; @@ -5000,11 +4999,11 @@ int start_line = CG(zend_lineno); yy427: YYDEBUG(427, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1561 "Zend/zend_language_scanner.l" +#line 1560 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_FINAL); } -#line 5008 "Zend/zend_language_scanner.c" +#line 5007 "Zend/zend_language_scanner.c" yy428: YYDEBUG(428, *YYCURSOR); yych = *++YYCURSOR; @@ -5061,11 +5060,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(437, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1541 "Zend/zend_language_scanner.l" +#line 1540 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_ISSET); } -#line 5069 "Zend/zend_language_scanner.c" +#line 5068 "Zend/zend_language_scanner.c" yy438: YYDEBUG(438, *YYCURSOR); yych = *++YYCURSOR; @@ -5080,11 +5079,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(440, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1401 "Zend/zend_language_scanner.l" +#line 1400 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_PRINT); } -#line 5088 "Zend/zend_language_scanner.c" +#line 5087 "Zend/zend_language_scanner.c" yy441: YYDEBUG(441, *YYCURSOR); yych = *++YYCURSOR; @@ -5135,11 +5134,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(449, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1305 "Zend/zend_language_scanner.l" +#line 1304 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_THROW); } -#line 5143 "Zend/zend_language_scanner.c" +#line 5142 "Zend/zend_language_scanner.c" yy450: YYDEBUG(450, *YYCURSOR); yych = *++YYCURSOR; @@ -5148,11 +5147,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(451, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1413 "Zend/zend_language_scanner.l" +#line 1412 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_TRAIT); } -#line 5156 "Zend/zend_language_scanner.c" +#line 5155 "Zend/zend_language_scanner.c" yy452: YYDEBUG(452, *YYCURSOR); yych = *++YYCURSOR; @@ -5161,11 +5160,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(453, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1577 "Zend/zend_language_scanner.l" +#line 1576 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_UNSET); } -#line 5169 "Zend/zend_language_scanner.c" +#line 5168 "Zend/zend_language_scanner.c" yy454: YYDEBUG(454, *YYCURSOR); yych = *++YYCURSOR; @@ -5174,11 +5173,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(455, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1325 "Zend/zend_language_scanner.l" +#line 1324 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_WHILE); } -#line 5182 "Zend/zend_language_scanner.c" +#line 5181 "Zend/zend_language_scanner.c" yy456: YYDEBUG(456, *YYCURSOR); yyaccept = 6; @@ -5196,11 +5195,11 @@ int start_line = CG(zend_lineno); yy457: YYDEBUG(457, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1289 "Zend/zend_language_scanner.l" +#line 1288 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_YIELD); } -#line 5204 "Zend/zend_language_scanner.c" +#line 5203 "Zend/zend_language_scanner.c" yy458: YYDEBUG(458, *YYCURSOR); yych = *++YYCURSOR; @@ -5292,11 +5291,11 @@ int start_line = CG(zend_lineno); ++YYCURSOR; YYDEBUG(473, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1497 "Zend/zend_language_scanner.l" +#line 1496 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_BOOL_CAST); } -#line 5300 "Zend/zend_language_scanner.c" +#line 5299 "Zend/zend_language_scanner.c" yy474: YYDEBUG(474, *YYCURSOR); yych = *++YYCURSOR; @@ -5326,11 +5325,11 @@ int start_line = CG(zend_lineno); ++YYCURSOR; YYDEBUG(479, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1481 "Zend/zend_language_scanner.l" +#line 1480 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_DOUBLE_CAST); } -#line 5334 "Zend/zend_language_scanner.c" +#line 5333 "Zend/zend_language_scanner.c" yy480: YYDEBUG(480, *YYCURSOR); yych = *++YYCURSOR; @@ -5395,11 +5394,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(490, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1313 "Zend/zend_language_scanner.l" +#line 1312 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_ELSEIF); } -#line 5403 "Zend/zend_language_scanner.c" +#line 5402 "Zend/zend_language_scanner.c" yy491: YYDEBUG(491, *YYCURSOR); yych = *++YYCURSOR; @@ -5429,11 +5428,11 @@ int start_line = CG(zend_lineno); yy493: YYDEBUG(493, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1341 "Zend/zend_language_scanner.l" +#line 1340 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_ENDFOR); } -#line 5437 "Zend/zend_language_scanner.c" +#line 5436 "Zend/zend_language_scanner.c" yy494: YYDEBUG(494, *YYCURSOR); yych = *++YYCURSOR; @@ -5478,11 +5477,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(501, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1537 "Zend/zend_language_scanner.l" +#line 1536 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_GLOBAL); } -#line 5486 "Zend/zend_language_scanner.c" +#line 5485 "Zend/zend_language_scanner.c" yy502: YYDEBUG(502, *YYCURSOR); yych = *++YYCURSOR; @@ -5539,11 +5538,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(511, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1573 "Zend/zend_language_scanner.l" +#line 1572 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_PUBLIC); } -#line 5547 "Zend/zend_language_scanner.c" +#line 5546 "Zend/zend_language_scanner.c" yy512: YYDEBUG(512, *YYCURSOR); yych = *++YYCURSOR; @@ -5558,11 +5557,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(514, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1279 "Zend/zend_language_scanner.l" +#line 1278 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_RETURN); } -#line 5566 "Zend/zend_language_scanner.c" +#line 5565 "Zend/zend_language_scanner.c" yy515: YYDEBUG(515, *YYCURSOR); yych = *++YYCURSOR; @@ -5571,11 +5570,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(516, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1553 "Zend/zend_language_scanner.l" +#line 1552 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_STATIC); } -#line 5579 "Zend/zend_language_scanner.c" +#line 5578 "Zend/zend_language_scanner.c" yy517: YYDEBUG(517, *YYCURSOR); yych = *++YYCURSOR; @@ -5584,11 +5583,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(518, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1369 "Zend/zend_language_scanner.l" +#line 1368 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_SWITCH); } -#line 5592 "Zend/zend_language_scanner.c" +#line 5591 "Zend/zend_language_scanner.c" yy519: YYDEBUG(519, *YYCURSOR); ++YYCURSOR; @@ -5668,11 +5667,11 @@ int start_line = CG(zend_lineno); ++YYCURSOR; YYDEBUG(531, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1489 "Zend/zend_language_scanner.l" +#line 1488 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_ARRAY_CAST); } -#line 5676 "Zend/zend_language_scanner.c" +#line 5675 "Zend/zend_language_scanner.c" yy532: YYDEBUG(532, *YYCURSOR); ++YYCURSOR; @@ -5718,11 +5717,11 @@ int start_line = CG(zend_lineno); ++YYCURSOR; YYDEBUG(539, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1501 "Zend/zend_language_scanner.l" +#line 1500 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_UNSET_CAST); } -#line 5726 "Zend/zend_language_scanner.c" +#line 5725 "Zend/zend_language_scanner.c" yy540: YYDEBUG(540, *YYCURSOR); yych = *++YYCURSOR; @@ -5749,11 +5748,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(544, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1353 "Zend/zend_language_scanner.l" +#line 1352 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_DECLARE); } -#line 5757 "Zend/zend_language_scanner.c" +#line 5756 "Zend/zend_language_scanner.c" yy545: YYDEBUG(545, *YYCURSOR); yych = *++YYCURSOR; @@ -5762,11 +5761,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(546, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1381 "Zend/zend_language_scanner.l" +#line 1380 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_DEFAULT); } -#line 5770 "Zend/zend_language_scanner.c" +#line 5769 "Zend/zend_language_scanner.c" yy547: YYDEBUG(547, *YYCURSOR); yych = *++YYCURSOR; @@ -5799,11 +5798,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(552, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1417 "Zend/zend_language_scanner.l" +#line 1416 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_EXTENDS); } -#line 5807 "Zend/zend_language_scanner.c" +#line 5806 "Zend/zend_language_scanner.c" yy553: YYDEBUG(553, *YYCURSOR); yych = *++YYCURSOR; @@ -5812,11 +5811,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(554, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1301 "Zend/zend_language_scanner.l" +#line 1300 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_FINALLY); } -#line 5820 "Zend/zend_language_scanner.c" +#line 5819 "Zend/zend_language_scanner.c" yy555: YYDEBUG(555, *YYCURSOR); yych = *++YYCURSOR; @@ -5825,11 +5824,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(556, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1345 "Zend/zend_language_scanner.l" +#line 1344 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_FOREACH); } -#line 5833 "Zend/zend_language_scanner.c" +#line 5832 "Zend/zend_language_scanner.c" yy557: YYDEBUG(557, *YYCURSOR); yych = *++YYCURSOR; @@ -5863,11 +5862,11 @@ int start_line = CG(zend_lineno); yy560: YYDEBUG(560, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1509 "Zend/zend_language_scanner.l" +#line 1508 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_INCLUDE); } -#line 5871 "Zend/zend_language_scanner.c" +#line 5870 "Zend/zend_language_scanner.c" yy561: YYDEBUG(561, *YYCURSOR); yych = *++YYCURSOR; @@ -5900,11 +5899,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(566, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1565 "Zend/zend_language_scanner.l" +#line 1564 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_PRIVATE); } -#line 5908 "Zend/zend_language_scanner.c" +#line 5907 "Zend/zend_language_scanner.c" yy567: YYDEBUG(567, *YYCURSOR); yych = *++YYCURSOR; @@ -5932,11 +5931,11 @@ int start_line = CG(zend_lineno); yy569: YYDEBUG(569, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1517 "Zend/zend_language_scanner.l" +#line 1516 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_REQUIRE); } -#line 5940 "Zend/zend_language_scanner.c" +#line 5939 "Zend/zend_language_scanner.c" yy570: YYDEBUG(570, *YYCURSOR); yych = *++YYCURSOR; @@ -5956,11 +5955,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(573, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1920 "Zend/zend_language_scanner.l" +#line 1919 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_DIR); } -#line 5964 "Zend/zend_language_scanner.c" +#line 5963 "Zend/zend_language_scanner.c" yy574: YYDEBUG(574, *YYCURSOR); yych = *++YYCURSOR; @@ -6005,21 +6004,21 @@ int start_line = CG(zend_lineno); ++YYCURSOR; YYDEBUG(582, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1485 "Zend/zend_language_scanner.l" +#line 1484 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_STRING_CAST); } -#line 6013 "Zend/zend_language_scanner.c" +#line 6012 "Zend/zend_language_scanner.c" yy583: YYDEBUG(583, *YYCURSOR); ++YYCURSOR; YYDEBUG(584, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1493 "Zend/zend_language_scanner.l" +#line 1492 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_OBJECT_CAST); } -#line 6023 "Zend/zend_language_scanner.c" +#line 6022 "Zend/zend_language_scanner.c" yy585: YYDEBUG(585, *YYCURSOR); yych = *++YYCURSOR; @@ -6028,11 +6027,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(586, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1557 "Zend/zend_language_scanner.l" +#line 1556 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_ABSTRACT); } -#line 6036 "Zend/zend_language_scanner.c" +#line 6035 "Zend/zend_language_scanner.c" yy587: YYDEBUG(587, *YYCURSOR); yych = *++YYCURSOR; @@ -6041,11 +6040,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(588, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1593 "Zend/zend_language_scanner.l" +#line 1592 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_CALLABLE); } -#line 6049 "Zend/zend_language_scanner.c" +#line 6048 "Zend/zend_language_scanner.c" yy589: YYDEBUG(589, *YYCURSOR); yych = *++YYCURSOR; @@ -6054,11 +6053,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(590, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1389 "Zend/zend_language_scanner.l" +#line 1388 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_CONTINUE); } -#line 6062 "Zend/zend_language_scanner.c" +#line 6061 "Zend/zend_language_scanner.c" yy591: YYDEBUG(591, *YYCURSOR); yych = *++YYCURSOR; @@ -6085,11 +6084,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(595, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1329 "Zend/zend_language_scanner.l" +#line 1328 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_ENDWHILE); } -#line 6093 "Zend/zend_language_scanner.c" +#line 6092 "Zend/zend_language_scanner.c" yy596: YYDEBUG(596, *YYCURSOR); yych = *++YYCURSOR; @@ -6098,11 +6097,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(597, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1271 "Zend/zend_language_scanner.l" +#line 1270 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_FUNCTION); } -#line 6106 "Zend/zend_language_scanner.c" +#line 6105 "Zend/zend_language_scanner.c" yy598: YYDEBUG(598, *YYCURSOR); yych = *++YYCURSOR; @@ -6170,11 +6169,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(609, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1916 "Zend/zend_language_scanner.l" +#line 1915 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_FILE); } -#line 6178 "Zend/zend_language_scanner.c" +#line 6177 "Zend/zend_language_scanner.c" yy610: YYDEBUG(610, *YYCURSOR); yych = *++YYCURSOR; @@ -6195,11 +6194,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(613, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1912 "Zend/zend_language_scanner.l" +#line 1911 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_LINE); } -#line 6203 "Zend/zend_language_scanner.c" +#line 6202 "Zend/zend_language_scanner.c" yy614: YYDEBUG(614, *YYCURSOR); yych = *++YYCURSOR; @@ -6236,11 +6235,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(620, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1373 "Zend/zend_language_scanner.l" +#line 1372 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_ENDSWITCH); } -#line 6244 "Zend/zend_language_scanner.c" +#line 6243 "Zend/zend_language_scanner.c" yy621: YYDEBUG(621, *YYCURSOR); yych = *++YYCURSOR; @@ -6267,11 +6266,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(625, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1533 "Zend/zend_language_scanner.l" +#line 1532 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_INSTEADOF); } -#line 6275 "Zend/zend_language_scanner.c" +#line 6274 "Zend/zend_language_scanner.c" yy626: YYDEBUG(626, *YYCURSOR); yych = *++YYCURSOR; @@ -6280,11 +6279,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(627, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1409 "Zend/zend_language_scanner.l" +#line 1408 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_INTERFACE); } -#line 6288 "Zend/zend_language_scanner.c" +#line 6287 "Zend/zend_language_scanner.c" yy628: YYDEBUG(628, *YYCURSOR); yych = *++YYCURSOR; @@ -6293,11 +6292,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(629, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1525 "Zend/zend_language_scanner.l" +#line 1524 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_NAMESPACE); } -#line 6301 "Zend/zend_language_scanner.c" +#line 6300 "Zend/zend_language_scanner.c" yy630: YYDEBUG(630, *YYCURSOR); yych = *++YYCURSOR; @@ -6306,11 +6305,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(631, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1569 "Zend/zend_language_scanner.l" +#line 1568 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_PROTECTED); } -#line 6314 "Zend/zend_language_scanner.c" +#line 6313 "Zend/zend_language_scanner.c" yy632: YYDEBUG(632, *YYCURSOR); yych = *++YYCURSOR; @@ -6331,11 +6330,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(635, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1896 "Zend/zend_language_scanner.l" +#line 1895 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_CLASS_C); } -#line 6339 "Zend/zend_language_scanner.c" +#line 6338 "Zend/zend_language_scanner.c" yy636: YYDEBUG(636, *YYCURSOR); yych = *++YYCURSOR; @@ -6367,11 +6366,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(641, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1900 "Zend/zend_language_scanner.l" +#line 1899 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_TRAIT_C); } -#line 6375 "Zend/zend_language_scanner.c" +#line 6374 "Zend/zend_language_scanner.c" yy642: YYDEBUG(642, *YYCURSOR); yych = *++YYCURSOR; @@ -6380,11 +6379,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(643, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1357 "Zend/zend_language_scanner.l" +#line 1356 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_ENDDECLARE); } -#line 6388 "Zend/zend_language_scanner.c" +#line 6387 "Zend/zend_language_scanner.c" yy644: YYDEBUG(644, *YYCURSOR); yych = *++YYCURSOR; @@ -6393,11 +6392,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(645, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1349 "Zend/zend_language_scanner.l" +#line 1348 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_ENDFOREACH); } -#line 6401 "Zend/zend_language_scanner.c" +#line 6400 "Zend/zend_language_scanner.c" yy646: YYDEBUG(646, *YYCURSOR); yych = *++YYCURSOR; @@ -6406,11 +6405,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(647, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1421 "Zend/zend_language_scanner.l" +#line 1420 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_IMPLEMENTS); } -#line 6414 "Zend/zend_language_scanner.c" +#line 6413 "Zend/zend_language_scanner.c" yy648: YYDEBUG(648, *YYCURSOR); yych = *++YYCURSOR; @@ -6425,11 +6424,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(650, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1361 "Zend/zend_language_scanner.l" +#line 1360 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_INSTANCEOF); } -#line 6433 "Zend/zend_language_scanner.c" +#line 6432 "Zend/zend_language_scanner.c" yy651: YYDEBUG(651, *YYCURSOR); yych = *++YYCURSOR; @@ -6477,11 +6476,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(656, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1908 "Zend/zend_language_scanner.l" +#line 1907 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_METHOD_C); } -#line 6485 "Zend/zend_language_scanner.c" +#line 6484 "Zend/zend_language_scanner.c" yy657: YYDEBUG(657, *YYCURSOR); yych = *++YYCURSOR; @@ -6505,13 +6504,13 @@ int start_line = CG(zend_lineno); ++YYCURSOR; YYDEBUG(661, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1283 "Zend/zend_language_scanner.l" +#line 1282 "Zend/zend_language_scanner.l" { yyless(yyleng - 1); HANDLE_NEWLINES(yytext, yyleng); RETURN_TOKEN(T_YIELD_FROM); } -#line 6515 "Zend/zend_language_scanner.c" +#line 6514 "Zend/zend_language_scanner.c" yy662: YYDEBUG(662, *YYCURSOR); yych = *++YYCURSOR; @@ -6536,11 +6535,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(666, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1513 "Zend/zend_language_scanner.l" +#line 1512 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_INCLUDE_ONCE); } -#line 6544 "Zend/zend_language_scanner.c" +#line 6543 "Zend/zend_language_scanner.c" yy667: YYDEBUG(667, *YYCURSOR); yych = *++YYCURSOR; @@ -6549,11 +6548,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(668, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1521 "Zend/zend_language_scanner.l" +#line 1520 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_REQUIRE_ONCE); } -#line 6557 "Zend/zend_language_scanner.c" +#line 6556 "Zend/zend_language_scanner.c" yy669: YYDEBUG(669, *YYCURSOR); yych = *++YYCURSOR; @@ -6562,11 +6561,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(670, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1904 "Zend/zend_language_scanner.l" +#line 1903 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_FUNC_C); } -#line 6570 "Zend/zend_language_scanner.c" +#line 6569 "Zend/zend_language_scanner.c" yy671: YYDEBUG(671, *YYCURSOR); yych = *++YYCURSOR; @@ -6592,11 +6591,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(675, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1924 "Zend/zend_language_scanner.l" +#line 1923 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_NS_C); } -#line 6600 "Zend/zend_language_scanner.c" +#line 6599 "Zend/zend_language_scanner.c" yy676: YYDEBUG(676, *YYCURSOR); yych = *++YYCURSOR; @@ -6610,11 +6609,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(678, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1549 "Zend/zend_language_scanner.l" +#line 1548 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_HALT_COMPILER); } -#line 6618 "Zend/zend_language_scanner.c" +#line 6617 "Zend/zend_language_scanner.c" } /* *********************************** */ yyc_ST_LOOKING_FOR_PROPERTY: @@ -6680,13 +6679,13 @@ int start_line = CG(zend_lineno); yy682: YYDEBUG(682, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1443 "Zend/zend_language_scanner.l" +#line 1442 "Zend/zend_language_scanner.l" { yyless(0); yy_pop_state(); goto restart; } -#line 6690 "Zend/zend_language_scanner.c" +#line 6689 "Zend/zend_language_scanner.c" yy683: YYDEBUG(683, *YYCURSOR); ++YYCURSOR; @@ -6698,11 +6697,11 @@ int start_line = CG(zend_lineno); } YYDEBUG(685, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1430 "Zend/zend_language_scanner.l" +#line 1429 "Zend/zend_language_scanner.l" { goto return_whitespace; } -#line 6706 "Zend/zend_language_scanner.c" +#line 6705 "Zend/zend_language_scanner.c" yy686: YYDEBUG(686, *YYCURSOR); yych = *++YYCURSOR; @@ -6719,22 +6718,22 @@ int start_line = CG(zend_lineno); } YYDEBUG(689, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1438 "Zend/zend_language_scanner.l" +#line 1437 "Zend/zend_language_scanner.l" { yy_pop_state(); RETURN_TOKEN_WITH_STR(T_STRING, 0); } -#line 6728 "Zend/zend_language_scanner.c" +#line 6727 "Zend/zend_language_scanner.c" yy690: YYDEBUG(690, *YYCURSOR); ++YYCURSOR; YYDEBUG(691, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1434 "Zend/zend_language_scanner.l" +#line 1433 "Zend/zend_language_scanner.l" { RETURN_TOKEN(T_OBJECT_OPERATOR); } -#line 6738 "Zend/zend_language_scanner.c" +#line 6737 "Zend/zend_language_scanner.c" } /* *********************************** */ yyc_ST_BACKQUOTE: @@ -6787,7 +6786,7 @@ int start_line = CG(zend_lineno); yy695: YYDEBUG(695, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2508 "Zend/zend_language_scanner.l" +#line 2507 "Zend/zend_language_scanner.l" { if (YYCURSOR > YYLIMIT) { RETURN_TOKEN(END); @@ -6832,7 +6831,7 @@ int start_line = CG(zend_lineno); RETURN_TOKEN(T_ERROR); } } -#line 6836 "Zend/zend_language_scanner.c" +#line 6835 "Zend/zend_language_scanner.c" yy696: YYDEBUG(696, *YYCURSOR); yych = *++YYCURSOR; @@ -6856,12 +6855,12 @@ int start_line = CG(zend_lineno); ++YYCURSOR; YYDEBUG(698, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2448 "Zend/zend_language_scanner.l" +#line 2447 "Zend/zend_language_scanner.l" { BEGIN(ST_IN_SCRIPTING); RETURN_TOKEN('`'); } -#line 6865 "Zend/zend_language_scanner.c" +#line 6864 "Zend/zend_language_scanner.c" yy699: YYDEBUG(699, *YYCURSOR); yych = *++YYCURSOR; @@ -6882,34 +6881,34 @@ int start_line = CG(zend_lineno); yy702: YYDEBUG(702, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2025 "Zend/zend_language_scanner.l" +#line 2024 "Zend/zend_language_scanner.l" { RETURN_TOKEN_WITH_STR(T_VARIABLE, 1); } -#line 6890 "Zend/zend_language_scanner.c" +#line 6889 "Zend/zend_language_scanner.c" yy703: YYDEBUG(703, *YYCURSOR); ++YYCURSOR; YYDEBUG(704, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1724 "Zend/zend_language_scanner.l" +#line 1723 "Zend/zend_language_scanner.l" { yy_push_state(ST_LOOKING_FOR_VARNAME); RETURN_TOKEN(T_DOLLAR_OPEN_CURLY_BRACES); } -#line 6901 "Zend/zend_language_scanner.c" +#line 6900 "Zend/zend_language_scanner.c" yy705: YYDEBUG(705, *YYCURSOR); ++YYCURSOR; YYDEBUG(706, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2436 "Zend/zend_language_scanner.l" +#line 2435 "Zend/zend_language_scanner.l" { yy_push_state(ST_IN_SCRIPTING); yyless(1); RETURN_TOKEN(T_CURLY_OPEN); } -#line 6913 "Zend/zend_language_scanner.c" +#line 6912 "Zend/zend_language_scanner.c" yy707: YYDEBUG(707, *YYCURSOR); yych = *++YYCURSOR; @@ -6923,13 +6922,13 @@ int start_line = CG(zend_lineno); ++YYCURSOR; YYDEBUG(710, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2019 "Zend/zend_language_scanner.l" +#line 2018 "Zend/zend_language_scanner.l" { yyless(yyleng - 1); yy_push_state(ST_VAR_OFFSET); RETURN_TOKEN_WITH_STR(T_VARIABLE, 1); } -#line 6933 "Zend/zend_language_scanner.c" +#line 6932 "Zend/zend_language_scanner.c" yy711: YYDEBUG(711, *YYCURSOR); yych = *++YYCURSOR; @@ -6947,13 +6946,13 @@ int start_line = CG(zend_lineno); ++YYCURSOR; YYDEBUG(713, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2011 "Zend/zend_language_scanner.l" +#line 2010 "Zend/zend_language_scanner.l" { yyless(yyleng - 3); yy_push_state(ST_LOOKING_FOR_PROPERTY); RETURN_TOKEN_WITH_STR(T_VARIABLE, 1); } -#line 6957 "Zend/zend_language_scanner.c" +#line 6956 "Zend/zend_language_scanner.c" } /* *********************************** */ yyc_ST_DOUBLE_QUOTES: @@ -7006,7 +7005,7 @@ int start_line = CG(zend_lineno); yy717: YYDEBUG(717, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2454 "Zend/zend_language_scanner.l" +#line 2453 "Zend/zend_language_scanner.l" { if (GET_DOUBLE_QUOTES_SCANNED_LENGTH()) { YYCURSOR += GET_DOUBLE_QUOTES_SCANNED_LENGTH() - 1; @@ -7059,18 +7058,18 @@ int start_line = CG(zend_lineno); RETURN_TOKEN(T_ERROR); } } -#line 7063 "Zend/zend_language_scanner.c" +#line 7062 "Zend/zend_language_scanner.c" yy718: YYDEBUG(718, *YYCURSOR); ++YYCURSOR; YYDEBUG(719, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2443 "Zend/zend_language_scanner.l" +#line 2442 "Zend/zend_language_scanner.l" { BEGIN(ST_IN_SCRIPTING); RETURN_TOKEN('"'); } -#line 7074 "Zend/zend_language_scanner.c" +#line 7073 "Zend/zend_language_scanner.c" yy720: YYDEBUG(720, *YYCURSOR); yych = *++YYCURSOR; @@ -7109,34 +7108,34 @@ int start_line = CG(zend_lineno); yy724: YYDEBUG(724, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2025 "Zend/zend_language_scanner.l" +#line 2024 "Zend/zend_language_scanner.l" { RETURN_TOKEN_WITH_STR(T_VARIABLE, 1); } -#line 7117 "Zend/zend_language_scanner.c" +#line 7116 "Zend/zend_language_scanner.c" yy725: YYDEBUG(725, *YYCURSOR); ++YYCURSOR; YYDEBUG(726, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1724 "Zend/zend_language_scanner.l" +#line 1723 "Zend/zend_language_scanner.l" { yy_push_state(ST_LOOKING_FOR_VARNAME); RETURN_TOKEN(T_DOLLAR_OPEN_CURLY_BRACES); } -#line 7128 "Zend/zend_language_scanner.c" +#line 7127 "Zend/zend_language_scanner.c" yy727: YYDEBUG(727, *YYCURSOR); ++YYCURSOR; YYDEBUG(728, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2436 "Zend/zend_language_scanner.l" +#line 2435 "Zend/zend_language_scanner.l" { yy_push_state(ST_IN_SCRIPTING); yyless(1); RETURN_TOKEN(T_CURLY_OPEN); } -#line 7140 "Zend/zend_language_scanner.c" +#line 7139 "Zend/zend_language_scanner.c" yy729: YYDEBUG(729, *YYCURSOR); yych = *++YYCURSOR; @@ -7150,13 +7149,13 @@ int start_line = CG(zend_lineno); ++YYCURSOR; YYDEBUG(732, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2019 "Zend/zend_language_scanner.l" +#line 2018 "Zend/zend_language_scanner.l" { yyless(yyleng - 1); yy_push_state(ST_VAR_OFFSET); RETURN_TOKEN_WITH_STR(T_VARIABLE, 1); } -#line 7160 "Zend/zend_language_scanner.c" +#line 7159 "Zend/zend_language_scanner.c" yy733: YYDEBUG(733, *YYCURSOR); yych = *++YYCURSOR; @@ -7174,13 +7173,13 @@ int start_line = CG(zend_lineno); ++YYCURSOR; YYDEBUG(735, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2011 "Zend/zend_language_scanner.l" +#line 2010 "Zend/zend_language_scanner.l" { yyless(yyleng - 3); yy_push_state(ST_LOOKING_FOR_PROPERTY); RETURN_TOKEN_WITH_STR(T_VARIABLE, 1); } -#line 7184 "Zend/zend_language_scanner.c" +#line 7183 "Zend/zend_language_scanner.c" } /* *********************************** */ yyc_ST_HEREDOC: @@ -7229,7 +7228,7 @@ int start_line = CG(zend_lineno); yy739: YYDEBUG(739, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2554 "Zend/zend_language_scanner.l" +#line 2553 "Zend/zend_language_scanner.l" { zend_heredoc_label *heredoc_label = zend_ptr_stack_top(&SCNG(heredoc_label_stack)); int newline = 0, indentation = 0, spacing = 0; @@ -7352,7 +7351,7 @@ int start_line = CG(zend_lineno); RETURN_TOKEN_WITH_VAL(T_ENCAPSED_AND_WHITESPACE); } -#line 7356 "Zend/zend_language_scanner.c" +#line 7355 "Zend/zend_language_scanner.c" yy740: YYDEBUG(740, *YYCURSOR); yych = *++YYCURSOR; @@ -7391,34 +7390,34 @@ int start_line = CG(zend_lineno); yy744: YYDEBUG(744, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2025 "Zend/zend_language_scanner.l" +#line 2024 "Zend/zend_language_scanner.l" { RETURN_TOKEN_WITH_STR(T_VARIABLE, 1); } -#line 7399 "Zend/zend_language_scanner.c" +#line 7398 "Zend/zend_language_scanner.c" yy745: YYDEBUG(745, *YYCURSOR); ++YYCURSOR; YYDEBUG(746, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1724 "Zend/zend_language_scanner.l" +#line 1723 "Zend/zend_language_scanner.l" { yy_push_state(ST_LOOKING_FOR_VARNAME); RETURN_TOKEN(T_DOLLAR_OPEN_CURLY_BRACES); } -#line 7410 "Zend/zend_language_scanner.c" +#line 7409 "Zend/zend_language_scanner.c" yy747: YYDEBUG(747, *YYCURSOR); ++YYCURSOR; YYDEBUG(748, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2436 "Zend/zend_language_scanner.l" +#line 2435 "Zend/zend_language_scanner.l" { yy_push_state(ST_IN_SCRIPTING); yyless(1); RETURN_TOKEN(T_CURLY_OPEN); } -#line 7422 "Zend/zend_language_scanner.c" +#line 7421 "Zend/zend_language_scanner.c" yy749: YYDEBUG(749, *YYCURSOR); yych = *++YYCURSOR; @@ -7432,13 +7431,13 @@ int start_line = CG(zend_lineno); ++YYCURSOR; YYDEBUG(752, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2019 "Zend/zend_language_scanner.l" +#line 2018 "Zend/zend_language_scanner.l" { yyless(yyleng - 1); yy_push_state(ST_VAR_OFFSET); RETURN_TOKEN_WITH_STR(T_VARIABLE, 1); } -#line 7442 "Zend/zend_language_scanner.c" +#line 7441 "Zend/zend_language_scanner.c" yy753: YYDEBUG(753, *YYCURSOR); yych = *++YYCURSOR; @@ -7456,13 +7455,13 @@ int start_line = CG(zend_lineno); ++YYCURSOR; YYDEBUG(755, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2011 "Zend/zend_language_scanner.l" +#line 2010 "Zend/zend_language_scanner.l" { yyless(yyleng - 3); yy_push_state(ST_LOOKING_FOR_PROPERTY); RETURN_TOKEN_WITH_STR(T_VARIABLE, 1); } -#line 7466 "Zend/zend_language_scanner.c" +#line 7465 "Zend/zend_language_scanner.c" } /* *********************************** */ yyc_ST_LOOKING_FOR_VARNAME: @@ -7519,14 +7518,14 @@ int start_line = CG(zend_lineno); yy759: YYDEBUG(759, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1747 "Zend/zend_language_scanner.l" +#line 1746 "Zend/zend_language_scanner.l" { yyless(0); yy_pop_state(); yy_push_state(ST_IN_SCRIPTING); goto restart; } -#line 7530 "Zend/zend_language_scanner.c" +#line 7529 "Zend/zend_language_scanner.c" yy760: YYDEBUG(760, *YYCURSOR); yych = *(YYMARKER = ++YYCURSOR); @@ -7573,14 +7572,14 @@ int start_line = CG(zend_lineno); ++YYCURSOR; YYDEBUG(765, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1739 "Zend/zend_language_scanner.l" +#line 1738 "Zend/zend_language_scanner.l" { yyless(yyleng - 1); yy_pop_state(); yy_push_state(ST_IN_SCRIPTING); RETURN_TOKEN_WITH_STR(T_STRING_VARNAME, 0); } -#line 7584 "Zend/zend_language_scanner.c" +#line 7583 "Zend/zend_language_scanner.c" } /* *********************************** */ yyc_ST_VAR_OFFSET: @@ -7669,7 +7668,7 @@ int start_line = CG(zend_lineno); ++YYCURSOR; YYDEBUG(769, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2769 "Zend/zend_language_scanner.l" +#line 2768 "Zend/zend_language_scanner.l" { if (YYCURSOR > YYLIMIT) { RETURN_TOKEN(END); @@ -7680,13 +7679,13 @@ int start_line = CG(zend_lineno); } goto restart; } -#line 7684 "Zend/zend_language_scanner.c" +#line 7683 "Zend/zend_language_scanner.c" yy770: YYDEBUG(770, *YYCURSOR); ++YYCURSOR; YYDEBUG(771, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2039 "Zend/zend_language_scanner.l" +#line 2038 "Zend/zend_language_scanner.l" { /* Invalid rule to return a more explicit parse error with proper line number */ yyless(0); @@ -7694,19 +7693,19 @@ int start_line = CG(zend_lineno); ZVAL_NULL(zendlval); RETURN_TOKEN_WITH_VAL(T_ENCAPSED_AND_WHITESPACE); } -#line 7698 "Zend/zend_language_scanner.c" +#line 7697 "Zend/zend_language_scanner.c" yy772: YYDEBUG(772, *YYCURSOR); ++YYCURSOR; yy773: YYDEBUG(773, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2034 "Zend/zend_language_scanner.l" +#line 2033 "Zend/zend_language_scanner.l" { /* Only '[' or '-' can be valid, but returning other tokens will allow a more explicit parse error */ RETURN_TOKEN(yytext[0]); } -#line 7710 "Zend/zend_language_scanner.c" +#line 7709 "Zend/zend_language_scanner.c" yy774: YYDEBUG(774, *YYCURSOR); yych = *++YYCURSOR; @@ -7741,7 +7740,7 @@ int start_line = CG(zend_lineno); yy776: YYDEBUG(776, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1862 "Zend/zend_language_scanner.l" +#line 1861 "Zend/zend_language_scanner.l" { /* Offset could be treated as a long */ if (yyleng < MAX_LENGTH_OF_LONG - 1 || (yyleng == MAX_LENGTH_OF_LONG - 1 && strcmp(yytext, long_min_digits) < 0)) { char *end; @@ -7757,7 +7756,7 @@ int start_line = CG(zend_lineno); } RETURN_TOKEN_WITH_VAL(T_NUM_STRING); } -#line 7761 "Zend/zend_language_scanner.c" +#line 7760 "Zend/zend_language_scanner.c" yy777: YYDEBUG(777, *YYCURSOR); ++YYCURSOR; @@ -7779,22 +7778,22 @@ int start_line = CG(zend_lineno); } YYDEBUG(781, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2047 "Zend/zend_language_scanner.l" +#line 2046 "Zend/zend_language_scanner.l" { RETURN_TOKEN_WITH_STR(T_STRING, 0); } -#line 7787 "Zend/zend_language_scanner.c" +#line 7786 "Zend/zend_language_scanner.c" yy782: YYDEBUG(782, *YYCURSOR); ++YYCURSOR; YYDEBUG(783, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2029 "Zend/zend_language_scanner.l" +#line 2028 "Zend/zend_language_scanner.l" { yy_pop_state(); RETURN_TOKEN(']'); } -#line 7798 "Zend/zend_language_scanner.c" +#line 7797 "Zend/zend_language_scanner.c" yy784: YYDEBUG(784, *YYCURSOR); ++YYCURSOR; @@ -7819,11 +7818,11 @@ int start_line = CG(zend_lineno); yy786: YYDEBUG(786, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2025 "Zend/zend_language_scanner.l" +#line 2024 "Zend/zend_language_scanner.l" { RETURN_TOKEN_WITH_STR(T_VARIABLE, 1); } -#line 7827 "Zend/zend_language_scanner.c" +#line 7826 "Zend/zend_language_scanner.c" yy787: YYDEBUG(787, *YYCURSOR); ++YYCURSOR; @@ -7835,7 +7834,7 @@ int start_line = CG(zend_lineno); yy789: YYDEBUG(789, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1878 "Zend/zend_language_scanner.l" +#line 1877 "Zend/zend_language_scanner.l" { /* Offset must be treated as a string */ if (yyleng == 1) { ZVAL_INTERNED_STR(zendlval, ZSTR_CHAR((zend_uchar)*(yytext))); @@ -7844,7 +7843,7 @@ int start_line = CG(zend_lineno); } RETURN_TOKEN_WITH_VAL(T_NUM_STRING); } -#line 7848 "Zend/zend_language_scanner.c" +#line 7847 "Zend/zend_language_scanner.c" yy790: YYDEBUG(790, *YYCURSOR); yych = *++YYCURSOR; @@ -7894,7 +7893,7 @@ int start_line = CG(zend_lineno); yy800: YYDEBUG(800, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1960 "Zend/zend_language_scanner.l" +#line 1959 "Zend/zend_language_scanner.l" { if (YYCURSOR > YYLIMIT) { RETURN_TOKEN(END); @@ -7941,7 +7940,7 @@ int start_line = CG(zend_lineno); HANDLE_NEWLINES(yytext, yyleng); RETURN_TOKEN_WITH_VAL(T_INLINE_HTML); } -#line 7945 "Zend/zend_language_scanner.c" +#line 7944 "Zend/zend_language_scanner.c" yy801: YYDEBUG(801, *YYCURSOR); yych = *++YYCURSOR; @@ -7957,7 +7956,7 @@ int start_line = CG(zend_lineno); yy803: YYDEBUG(803, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1948 "Zend/zend_language_scanner.l" +#line 1947 "Zend/zend_language_scanner.l" { if (CG(short_tags)) { BEGIN(ST_IN_SCRIPTING); @@ -7969,13 +7968,13 @@ int start_line = CG(zend_lineno); goto inline_char_handler; } } -#line 7973 "Zend/zend_language_scanner.c" +#line 7972 "Zend/zend_language_scanner.c" yy804: YYDEBUG(804, *YYCURSOR); ++YYCURSOR; YYDEBUG(805, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1929 "Zend/zend_language_scanner.l" +#line 1928 "Zend/zend_language_scanner.l" { BEGIN(ST_IN_SCRIPTING); if (PARSER_MODE()) { @@ -7983,7 +7982,7 @@ int start_line = CG(zend_lineno); } RETURN_TOKEN(T_OPEN_TAG_WITH_ECHO); } -#line 7987 "Zend/zend_language_scanner.c" +#line 7986 "Zend/zend_language_scanner.c" yy806: YYDEBUG(806, *YYCURSOR); yych = *++YYCURSOR; @@ -8014,7 +8013,7 @@ int start_line = CG(zend_lineno); yy811: YYDEBUG(811, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 1938 "Zend/zend_language_scanner.l" +#line 1937 "Zend/zend_language_scanner.l" { HANDLE_NEWLINE(yytext[yyleng-1]); BEGIN(ST_IN_SCRIPTING); @@ -8023,7 +8022,7 @@ int start_line = CG(zend_lineno); } RETURN_TOKEN(T_OPEN_TAG); } -#line 8027 "Zend/zend_language_scanner.c" +#line 8026 "Zend/zend_language_scanner.c" yy812: YYDEBUG(812, *YYCURSOR); yych = *++YYCURSOR; @@ -8038,7 +8037,7 @@ int start_line = CG(zend_lineno); ++YYCURSOR; YYDEBUG(816, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2422 "Zend/zend_language_scanner.l" +#line 2421 "Zend/zend_language_scanner.l" { zend_heredoc_label *heredoc_label = zend_ptr_stack_pop(&SCNG(heredoc_label_stack)); @@ -8051,7 +8050,7 @@ int start_line = CG(zend_lineno); BEGIN(ST_IN_SCRIPTING); RETURN_TOKEN(T_END_HEREDOC); } -#line 8055 "Zend/zend_language_scanner.c" +#line 8054 "Zend/zend_language_scanner.c" /* *********************************** */ yyc_ST_NOWDOC: YYDEBUG(817, *YYCURSOR); @@ -8061,7 +8060,7 @@ int start_line = CG(zend_lineno); ++YYCURSOR; YYDEBUG(820, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 2678 "Zend/zend_language_scanner.l" +#line 2677 "Zend/zend_language_scanner.l" { zend_heredoc_label *heredoc_label = zend_ptr_stack_top(&SCNG(heredoc_label_stack)); int newline = 0, indentation = 0, spacing = -1; @@ -8151,9 +8150,9 @@ int start_line = CG(zend_lineno); HANDLE_NEWLINES(yytext, yyleng - newline); RETURN_TOKEN_WITH_VAL(T_ENCAPSED_AND_WHITESPACE); } -#line 8155 "Zend/zend_language_scanner.c" +#line 8154 "Zend/zend_language_scanner.c" } -#line 2780 "Zend/zend_language_scanner.l" +#line 2779 "Zend/zend_language_scanner.l" emit_token_with_str: diff --git a/Zend/zend_language_scanner.l b/Zend/zend_language_scanner.l index 2c35d38ea48c4..709890a19f9ca 100644 --- a/Zend/zend_language_scanner.l +++ b/Zend/zend_language_scanner.l @@ -1066,8 +1066,7 @@ static int zend_scan_escape_string(zval *zendlval, char *str, int len, char quot octal_buf[2] = *(++s); } } - if (octal_buf[2] && - (octal_buf[0] > '3')) { + if (octal_buf[2] && (octal_buf[0] > '3') && !SCNG(heredoc_scan_ahead)) { /* 3 octit values must not overflow 0xFF (\377) */ zend_error(E_COMPILE_WARNING, "Octal escape sequence overflow \\%s is greater than \\377", octal_buf); } From 2f95af996fc5dee9e445faa10473cdfcc1bc7640 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Fri, 4 Sep 2020 10:15:55 +0200 Subject: [PATCH 55/87] Disable InfiniteIterator class while fuzzing The combination of LimitIterator and InfiniteIterator can cause effectively infinite loops that bypass the executor step limit. --- sapi/fuzzer/fuzzer-sapi.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sapi/fuzzer/fuzzer-sapi.c b/sapi/fuzzer/fuzzer-sapi.c index 3ef0f5fe4ae06..fd429f503e7eb 100644 --- a/sapi/fuzzer/fuzzer-sapi.c +++ b/sapi/fuzzer/fuzzer-sapi.c @@ -56,6 +56,8 @@ const char HARDCODED_INI[] = ",crypt" /* openlog() has a known memory-management issue. */ ",openlog" + /* Can cause long loops that bypass the executor step limit. */ + "\ndisable_classes=InfiniteIterator" ; static int startup(sapi_module_struct *sapi_module) From 67e1f2399980a6e891822329d544338ccfbf6848 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Fri, 4 Sep 2020 12:59:42 +0200 Subject: [PATCH 56/87] Make gethostbyname() test more liberal This returns 127.0.1.1 on travis bionic. --- ext/standard/tests/network/gethostbyname_basic003.phpt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/standard/tests/network/gethostbyname_basic003.phpt b/ext/standard/tests/network/gethostbyname_basic003.phpt index eb7f5c33c57f3..e86a4e92bbe1b 100644 --- a/ext/standard/tests/network/gethostbyname_basic003.phpt +++ b/ext/standard/tests/network/gethostbyname_basic003.phpt @@ -6,6 +6,6 @@ echo "*** Testing gethostbyname() : basic functionality ***\n"; echo gethostbyname("localhost")."\n"; ?> ---EXPECT-- +--EXPECTF-- *** Testing gethostbyname() : basic functionality *** -127.0.0.1 +127.0.%d.1 From c0d6b05b686767fcf6a858d5c039bee764655590 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Fri, 4 Sep 2020 12:34:47 +0200 Subject: [PATCH 57/87] Update travis to bionic --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index e2a328b121f73..5e0e7ccbac99a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,7 @@ git: quiet: true -dist: xenial +dist: bionic language: c os: linux addons: From 2e218180efebeac4fe0fe3f36e39fce8fc513468 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Fri, 4 Sep 2020 09:41:27 +0200 Subject: [PATCH 58/87] Release call trampolines in zpp fcc When using zpp 'f' or Z_PARAM_FUNC, if the fcc points to a call trampoline release it immediately and force zend_call_function to refetch it. This may require additional callability checks if __call is used, but avoids the need to carefully free fcc values in all internal functions -- in some cases this is not simple, as a type error might be triggered by a later argument in the same zpp call. This fixes oss-fuzz #25390. Closes GH-6073. --- Zend/zend_API.c | 6 +++++- Zend/zend_API.h | 4 ++++ Zend/zend_builtin_functions.c | 2 -- ext/spl/php_spl.c | 9 ++++++++- ext/standard/array.c | 14 -------------- ext/standard/tests/array/bug74345.phpt | 13 +++++++++++++ 6 files changed, 30 insertions(+), 18 deletions(-) diff --git a/Zend/zend_API.c b/Zend/zend_API.c index 07ab456d1a97e..cc31a81a1ca58 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -825,6 +825,10 @@ static const char *zend_parse_arg_impl(zval *arg, va_list *va, const char **spec if (zend_fcall_info_init(arg, 0, fci, fcc, NULL, &is_callable_error) == SUCCESS) { ZEND_ASSERT(!is_callable_error); + /* Release call trampolines: The function may not get called, in which case + * the trampoline will leak. Force it to be refetched during + * zend_call_function instead. */ + zend_release_fcall_info_cache(fcc); break; } @@ -2979,8 +2983,8 @@ ZEND_API void zend_release_fcall_info_cache(zend_fcall_info_cache *fcc) { zend_string_release_ex(fcc->function_handler->common.function_name, 0); } zend_free_trampoline(fcc->function_handler); + fcc->function_handler = NULL; } - fcc->function_handler = NULL; } static zend_always_inline bool zend_is_callable_check_func(int check_flags, zval *callable, zend_execute_data *frame, zend_fcall_info_cache *fcc, bool strict_class, char **error) /* {{{ */ diff --git a/Zend/zend_API.h b/Zend/zend_API.h index a81a43f2314de..72cd3856aeae6 100644 --- a/Zend/zend_API.h +++ b/Zend/zend_API.h @@ -2004,6 +2004,10 @@ static zend_always_inline bool zend_parse_arg_func(zval *arg, zend_fcall_info *d } else if (UNEXPECTED(zend_fcall_info_init(arg, 0, dest_fci, dest_fcc, NULL, error) != SUCCESS)) { return 0; } + /* Release call trampolines: The function may not get called, in which case + * the trampoline will leak. Force it to be refetched during + * zend_call_function instead. */ + zend_release_fcall_info_cache(dest_fcc); return 1; } diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c index 906f0666edcff..c3a2a1b63f331 100644 --- a/Zend/zend_builtin_functions.c +++ b/Zend/zend_builtin_functions.c @@ -1198,7 +1198,6 @@ ZEND_FUNCTION(set_error_handler) ZVAL_COPY(&EG(user_error_handler), &(fci.function_name)); EG(user_error_handler_error_reporting) = (int)error_type; - zend_release_fcall_info_cache(&fcc); } /* }}} */ @@ -1254,7 +1253,6 @@ ZEND_FUNCTION(set_exception_handler) } ZVAL_COPY(&EG(user_exception_handler), &(fci.function_name)); - zend_release_fcall_info_cache(&fcc); } /* }}} */ diff --git a/ext/spl/php_spl.c b/ext/spl/php_spl.c index d92f774db4632..09c876b45f7b4 100644 --- a/ext/spl/php_spl.c +++ b/ext/spl/php_spl.c @@ -519,6 +519,13 @@ PHP_FUNCTION(spl_autoload_register) /* If first arg is not null */ if (ZEND_FCI_INITIALIZED(fci)) { + if (!fcc.function_handler) { + /* Call trampoline has been cleared by zpp. Refetch it, because we want to deal + * with it outselves. It is important that it is not refetched on every call, + * because calls may occur from different scopes. */ + zend_is_callable_ex(&fci.function_name, NULL, 0, NULL, &fcc, NULL); + } + if (fcc.function_handler->type == ZEND_INTERNAL_FUNCTION && fcc.function_handler->internal_function.handler == zif_spl_autoload_call) { zend_argument_value_error(1, "must not be the spl_autoload_call() function"); @@ -566,7 +573,7 @@ PHP_FUNCTION(spl_autoload_unregister) RETURN_THROWS(); } - if (zend_string_equals_literal( + if (fcc.function_handler && zend_string_equals_literal( fcc.function_handler->common.function_name, "spl_autoload_call")) { /* Don't destroy the hash table, as we might be iterating over it right now. */ zend_hash_clean(SPL_G(autoload_functions)); diff --git a/ext/standard/array.c b/ext/standard/array.c index 82b34673fffb8..b8996f8a34288 100644 --- a/ext/standard/array.c +++ b/ext/standard/array.c @@ -992,7 +992,6 @@ static int php_array_user_compare(Bucket *a, Bucket *b) /* {{{ */ BG(user_compare_fci_cache) = empty_fcall_info_cache; \ #define PHP_ARRAY_CMP_FUNC_RESTORE() \ - zend_release_fcall_info_cache(&BG(user_compare_fci_cache)); \ BG(user_compare_fci) = old_user_compare_fci; \ BG(user_compare_fci_cache) = old_user_compare_fci_cache; \ @@ -1515,7 +1514,6 @@ PHP_FUNCTION(array_walk) ); php_array_walk(array, userdata, 0); - zend_release_fcall_info_cache(&BG(array_walk_fci_cache)); BG(array_walk_fci) = orig_array_walk_fci; BG(array_walk_fci_cache) = orig_array_walk_fci_cache; RETURN_TRUE; @@ -1545,7 +1543,6 @@ PHP_FUNCTION(array_walk_recursive) ); php_array_walk(array, userdata, 1); - zend_release_fcall_info_cache(&BG(array_walk_fci_cache)); BG(array_walk_fci) = orig_array_walk_fci; BG(array_walk_fci_cache) = orig_array_walk_fci_cache; RETURN_TRUE; @@ -5951,7 +5948,6 @@ PHP_FUNCTION(array_reduce) htbl = Z_ARRVAL_P(input); if (zend_hash_num_elements(htbl) == 0) { - zend_release_fcall_info_cache(&fci_cache); return; } @@ -5973,8 +5969,6 @@ PHP_FUNCTION(array_reduce) RETURN_NULL(); } } ZEND_HASH_FOREACH_END(); - - zend_release_fcall_info_cache(&fci_cache); } /* }}} */ @@ -6002,7 +5996,6 @@ PHP_FUNCTION(array_filter) if (zend_hash_num_elements(Z_ARRVAL_P(array)) == 0) { RETVAL_EMPTY_ARRAY(); - zend_release_fcall_info_cache(&fci_cache); return; } array_init(return_value); @@ -6064,8 +6057,6 @@ PHP_FUNCTION(array_filter) } zval_add_ref(operand); } ZEND_HASH_FOREACH_END(); - - zend_release_fcall_info_cache(&fci_cache); } /* }}} */ @@ -6092,7 +6083,6 @@ PHP_FUNCTION(array_map) int ret; if (Z_TYPE(arrays[0]) != IS_ARRAY) { - zend_release_fcall_info_cache(&fci_cache); zend_argument_type_error(2, "must be of type array, %s given", zend_zval_type_name(&arrays[0])); RETURN_THROWS(); } @@ -6101,7 +6091,6 @@ PHP_FUNCTION(array_map) /* Short-circuit: if no callback and only one array, just return it. */ if (!ZEND_FCI_INITIALIZED(fci) || !maxlen) { ZVAL_COPY(return_value, &arrays[0]); - zend_release_fcall_info_cache(&fci_cache); return; } @@ -6126,8 +6115,6 @@ PHP_FUNCTION(array_map) zend_hash_index_add_new(Z_ARRVAL_P(return_value), num_key, &result); } } ZEND_HASH_FOREACH_END(); - - zend_release_fcall_info_cache(&fci_cache); } else { uint32_t *array_pos = (HashPosition *)ecalloc(n_arrays, sizeof(HashPosition)); @@ -6219,7 +6206,6 @@ PHP_FUNCTION(array_map) } efree(params); - zend_release_fcall_info_cache(&fci_cache); } efree(array_pos); } diff --git a/ext/standard/tests/array/bug74345.phpt b/ext/standard/tests/array/bug74345.phpt index 5b2bdba95f612..0916e17a54e1a 100644 --- a/ext/standard/tests/array/bug74345.phpt +++ b/ext/standard/tests/array/bug74345.phpt @@ -18,6 +18,11 @@ try { } catch (Error $e) { echo $e->getMessage(), "\n"; } +try { + array_map($cb, null, null); +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} array_filter([], $cb); array_reduce([], $cb); @@ -26,8 +31,16 @@ array_walk($array, $cb); array_walk_recursive($array, $cb); usort($array, $cb); +try { + preg_replace_callback('/./', $cb, new stdClass); +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} + ?> ===DONE=== --EXPECT-- array_map(): Argument #2 ($array1) must be of type array, null given +array_map(): Argument #2 ($array1) must be of type array, null given +preg_replace_callback(): Argument #3 ($subject) must be of type string|array, stdClass given ===DONE=== From 7805b97720d03b5f3b9f0296c26a56cce4c77cea Mon Sep 17 00:00:00 2001 From: George Peter Banyard Date: Thu, 3 Sep 2020 15:49:28 +0200 Subject: [PATCH 59/87] Extract common flock code As SPL is currently a copie of the code in file.c Closes GH-6069 --- ext/spl/spl_directory.c | 26 ++------------------------ ext/standard/file.c | 40 +++++++++++++++++++++++----------------- ext/standard/file.h | 2 ++ 3 files changed, 27 insertions(+), 41 deletions(-) diff --git a/ext/spl/spl_directory.c b/ext/spl/spl_directory.c index e782b1e70a462..3f3391334aa7f 100644 --- a/ext/spl/spl_directory.c +++ b/ext/spl/spl_directory.c @@ -2498,15 +2498,11 @@ PHP_METHOD(SplFileObject, getCsvControl) } /* }}} */ -static int flock_values[] = { LOCK_SH, LOCK_EX, LOCK_UN }; - -/* {{{ Portable file locking, copy pasted from ext/standard/file.c flock() function. - * This is done to prevent this to fail if flock is disabled via disable_functions */ +/* {{{ Portable file locking */ PHP_METHOD(SplFileObject, flock) { spl_filesystem_object *intern = Z_SPLFILESYSTEM_P(ZEND_THIS); zval *wouldblock = NULL; - int act; zend_long operation = 0; if (zend_parse_parameters(ZEND_NUM_ARGS(), "l|z", &operation, &wouldblock) == FAILURE) { @@ -2515,25 +2511,7 @@ PHP_METHOD(SplFileObject, flock) CHECK_SPL_FILE_OBJECT_IS_INITIALIZED(intern); - act = operation & PHP_LOCK_UN; - if (act < 1 || act > 3) { - zend_argument_value_error(1, "must be either LOCK_SH, LOCK_EX, or LOCK_UN"); - RETURN_THROWS(); - } - - if (wouldblock) { - ZEND_TRY_ASSIGN_REF_LONG(wouldblock, 0); - } - - /* flock_values contains all possible actions if (operation & PHP_LOCK_NB) we won't block on the lock */ - act = flock_values[act - 1] | (operation & PHP_LOCK_NB ? LOCK_NB : 0); - if (php_stream_lock(intern->u.file.stream, act)) { - if (operation && errno == EWOULDBLOCK && wouldblock) { - ZEND_TRY_ASSIGN_REF_LONG(wouldblock, 1); - } - RETURN_FALSE; - } - RETURN_TRUE; + php_flock_common(intern->u.file.stream, operation, 1, wouldblock, return_value); } /* }}} */ diff --git a/ext/standard/file.c b/ext/standard/file.c index d402c60acf48e..9883973c5dc33 100644 --- a/ext/standard/file.c +++ b/ext/standard/file.c @@ -325,28 +325,15 @@ PHP_MSHUTDOWN_FUNCTION(file) /* {{{ */ } /* }}} */ -static int flock_values[] = { LOCK_SH, LOCK_EX, LOCK_UN }; - -/* {{{ Portable file locking */ -PHP_FUNCTION(flock) +PHPAPI void php_flock_common(php_stream *stream, zend_long operation, + uint32_t operation_arg_num, zval *wouldblock, zval *return_value) { - zval *res, *wouldblock = NULL; + int flock_values[] = { LOCK_SH, LOCK_EX, LOCK_UN }; int act; - php_stream *stream; - zend_long operation = 0; - - ZEND_PARSE_PARAMETERS_START(2, 3) - Z_PARAM_RESOURCE(res) - Z_PARAM_LONG(operation) - Z_PARAM_OPTIONAL - Z_PARAM_ZVAL(wouldblock) - ZEND_PARSE_PARAMETERS_END(); - - PHP_STREAM_TO_ZVAL(stream, res); act = operation & PHP_LOCK_UN; if (act < 1 || act > 3) { - zend_argument_value_error(2, "must be either LOCK_SH, LOCK_EX, or LOCK_UN"); + zend_argument_value_error(operation_arg_num, "must be either LOCK_SH, LOCK_EX, or LOCK_UN"); RETURN_THROWS(); } @@ -364,6 +351,25 @@ PHP_FUNCTION(flock) } RETURN_TRUE; } + +/* {{{ Portable file locking */ +PHP_FUNCTION(flock) +{ + zval *res, *wouldblock = NULL; + php_stream *stream; + zend_long operation = 0; + + ZEND_PARSE_PARAMETERS_START(2, 3) + Z_PARAM_RESOURCE(res) + Z_PARAM_LONG(operation) + Z_PARAM_OPTIONAL + Z_PARAM_ZVAL(wouldblock) + ZEND_PARSE_PARAMETERS_END(); + + PHP_STREAM_TO_ZVAL(stream, res); + + php_flock_common(stream, operation, 2, wouldblock, return_value); +} /* }}} */ #define PHP_META_UNSAFE ".\\+*?[^]$() " diff --git a/ext/standard/file.h b/ext/standard/file.h index 1faf667a00be5..c51a953086eee 100644 --- a/ext/standard/file.h +++ b/ext/standard/file.h @@ -44,6 +44,8 @@ PHPAPI int php_copy_file_ctx(const char *src, const char *dest, int src_chk, php PHPAPI int php_mkdir_ex(const char *dir, zend_long mode, int options); PHPAPI int php_mkdir(const char *dir, zend_long mode); PHPAPI void php_fstat(php_stream *stream, zval *return_value); +PHPAPI void php_flock_common(php_stream *stream, zend_long operation, uint32_t operation_arg_num, + zval *wouldblock, zval *return_value); #define PHP_CSV_NO_ESCAPE EOF PHPAPI void php_fgetcsv(php_stream *stream, char delimiter, char enclosure, int escape_char, size_t buf_len, char *buf, zval *return_value); From e50cb320b4424e68490b0340c841d8971c6aff04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1t=C3=A9=20Kocsis?= Date: Fri, 4 Sep 2020 14:15:17 +0200 Subject: [PATCH 60/87] Add the Z_PARAM_ARRAY_HT_OR_NULL and Z_PARAM_OBJ macros --- Zend/zend_API.h | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/Zend/zend_API.h b/Zend/zend_API.h index 72cd3856aeae6..264b67764572e 100644 --- a/Zend/zend_API.h +++ b/Zend/zend_API.h @@ -1527,6 +1527,9 @@ ZEND_API ZEND_COLD void zend_argument_value_error(uint32_t arg_num, const char * #define Z_PARAM_ARRAY_HT(dest) \ Z_PARAM_ARRAY_HT_EX(dest, 0, 0) +#define Z_PARAM_ARRAY_HT_OR_NULL(dest) \ + Z_PARAM_ARRAY_HT_EX(dest, 1, 0) + /* old "H" */ #define Z_PARAM_ARRAY_OR_OBJECT_HT_EX2(dest, check_null, deref, separate) \ Z_PARAM_PROLOGUE(deref, separate); \ @@ -1593,6 +1596,24 @@ ZEND_API ZEND_COLD void zend_argument_value_error(uint32_t arg_num, const char * #define Z_PARAM_OBJECT_OR_NULL(dest) \ Z_PARAM_OBJECT_EX(dest, 1, 0) +/* The same as Z_PARAM_OBJECT_EX2 except that dest is a zend_object rather than a zval */ +#define Z_PARAM_OBJ_EX2(dest, check_null, deref, separate) \ + Z_PARAM_PROLOGUE(deref, separate); \ + if (UNEXPECTED(!zend_parse_arg_obj(_arg, &dest, NULL, check_null))) { \ + _expected_type = check_null ? Z_EXPECTED_OBJECT_OR_NULL : Z_EXPECTED_OBJECT; \ + _error_code = ZPP_ERROR_WRONG_ARG; \ + break; \ + } + +#define Z_PARAM_OBJ_EX(dest, check_null, separate) \ + Z_PARAM_OBJ_EX2(dest, check_null, separate, separate) + +#define Z_PARAM_OBJ(dest) \ + Z_PARAM_OBJ_EX(dest, 0, 0) + +#define Z_PARAM_OBJ_OR_NULL(dest) \ + Z_PARAM_OBJ_EX(dest, 1, 0) + /* old "O" */ #define Z_PARAM_OBJECT_OF_CLASS_EX2(dest, _ce, check_null, deref, separate) \ Z_PARAM_PROLOGUE(deref, separate); \ @@ -1983,6 +2004,19 @@ static zend_always_inline bool zend_parse_arg_object(zval *arg, zval **dest, zen return 1; } +static zend_always_inline bool zend_parse_arg_obj(zval *arg, zend_object **dest, zend_class_entry *ce, bool check_null) +{ + if (EXPECTED(Z_TYPE_P(arg) == IS_OBJECT) && + (!ce || EXPECTED(instanceof_function(Z_OBJCE_P(arg), ce) != 0))) { + *dest = Z_OBJ_P(arg); + } else if (check_null && EXPECTED(Z_TYPE_P(arg) == IS_NULL)) { + *dest = NULL; + } else { + return 0; + } + return 1; +} + static zend_always_inline bool zend_parse_arg_resource(zval *arg, zval **dest, bool check_null) { if (EXPECTED(Z_TYPE_P(arg) == IS_RESOURCE)) { From e50449bcb4c72f13577aecc195baf691a8341a29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1t=C3=A9=20Kocsis?= Date: Fri, 4 Sep 2020 14:20:15 +0200 Subject: [PATCH 61/87] Use the canonical order of types in array|string ZPP error messages --- Zend/zend_API.h | 4 ++-- ext/pcre/tests/preg_replace_error1.phpt | 2 +- ext/pcre/tests/preg_replace_error2.phpt | 2 +- ext/phar/tests/phar_extract.phpt | 2 +- ext/soap/tests/fault_warning.phpt | 2 +- ext/standard/tests/array/bug74345.phpt | 2 +- ext/standard/tests/streams/bug61115.phpt | 2 +- ext/standard/tests/strings/join_variation1.phpt | 2 +- ext/standard/tests/strings/strtr_variation6.phpt | 2 +- ext/standard/tests/strings/strtr_variation8.phpt | 2 +- 10 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Zend/zend_API.h b/Zend/zend_API.h index 264b67764572e..336060e5765bd 100644 --- a/Zend/zend_API.h +++ b/Zend/zend_API.h @@ -1223,8 +1223,8 @@ static zend_always_inline zval *zend_try_array_init(zval *zv) _(Z_EXPECTED_DOUBLE_OR_NULL, "of type ?float") \ _(Z_EXPECTED_NUMBER, "of type int|float") \ _(Z_EXPECTED_NUMBER_OR_NULL, "of type int|float|null") \ - _(Z_EXPECTED_STRING_OR_ARRAY, "of type string|array") \ - _(Z_EXPECTED_STRING_OR_ARRAY_OR_NULL, "of type string|array|null") \ + _(Z_EXPECTED_STRING_OR_ARRAY, "of type array|string") \ + _(Z_EXPECTED_STRING_OR_ARRAY_OR_NULL, "of type array|string|null") \ _(Z_EXPECTED_STRING_OR_LONG, "of type string|int") \ _(Z_EXPECTED_STRING_OR_LONG_OR_NULL, "of type string|int|null") \ _(Z_EXPECTED_CLASS_NAME_OR_OBJECT, "a valid class name or object") \ diff --git a/ext/pcre/tests/preg_replace_error1.phpt b/ext/pcre/tests/preg_replace_error1.phpt index 58cd049691a97..e654240f37f84 100644 --- a/ext/pcre/tests/preg_replace_error1.phpt +++ b/ext/pcre/tests/preg_replace_error1.phpt @@ -56,4 +56,4 @@ string(1) "a" Arg value is /[a-zA-Z]/ string(1) "1" -preg_replace(): Argument #1 ($regex) must be of type string|array, stdClass given +preg_replace(): Argument #1 ($regex) must be of type array|string, stdClass given diff --git a/ext/pcre/tests/preg_replace_error2.phpt b/ext/pcre/tests/preg_replace_error2.phpt index 9a3056ab882ad..c4503aafd198d 100644 --- a/ext/pcre/tests/preg_replace_error2.phpt +++ b/ext/pcre/tests/preg_replace_error2.phpt @@ -36,5 +36,5 @@ string(64) "this is a stringthis is a stringthis is a stringthis is a string" Arg value is: Array preg_replace(): Argument #1 ($regex) must be of type array when argument #2 ($replace) is an array, string given -preg_replace(): Argument #2 ($replace) must be of type string|array, stdClass given +preg_replace(): Argument #2 ($replace) must be of type array|string, stdClass given Done diff --git a/ext/phar/tests/phar_extract.phpt b/ext/phar/tests/phar_extract.phpt index 0ccd9d50d5603..65a96b0aab05e 100644 --- a/ext/phar/tests/phar_extract.phpt +++ b/ext/phar/tests/phar_extract.phpt @@ -141,7 +141,7 @@ string(2) "hi" string(3) "hi3" string(3) "hi2" bool(false) -Phar::extractTo(): Argument #2 ($files) must be of type string|array|null, stdClass given +Phar::extractTo(): Argument #2 ($files) must be of type array|string|null, stdClass given Phar::extractTo(): Argument #1 ($pathto) must be a valid path, array given Invalid argument, extraction path must be non-zero length Unable to use path "%soops" for extraction, it is a file, must be a directory diff --git a/ext/soap/tests/fault_warning.phpt b/ext/soap/tests/fault_warning.phpt index 77b5154b9a5e9..3a9fec6710d4a 100644 --- a/ext/soap/tests/fault_warning.phpt +++ b/ext/soap/tests/fault_warning.phpt @@ -40,7 +40,7 @@ echo get_class($fault); ?> --EXPECT-- SoapFault::__construct(): Argument #1 ($faultcode) is not a valid fault code -SoapFault::__construct(): Argument #1 ($faultcode) must be of type string|array|null, stdClass given +SoapFault::__construct(): Argument #1 ($faultcode) must be of type array|string|null, stdClass given SoapFault SoapFault SoapFault::__construct(): Argument #1 ($faultcode) is not a valid fault code diff --git a/ext/standard/tests/array/bug74345.phpt b/ext/standard/tests/array/bug74345.phpt index 0916e17a54e1a..cc5520676089a 100644 --- a/ext/standard/tests/array/bug74345.phpt +++ b/ext/standard/tests/array/bug74345.phpt @@ -42,5 +42,5 @@ try { --EXPECT-- array_map(): Argument #2 ($array1) must be of type array, null given array_map(): Argument #2 ($array1) must be of type array, null given -preg_replace_callback(): Argument #3 ($subject) must be of type string|array, stdClass given +preg_replace_callback(): Argument #3 ($subject) must be of type array|string, stdClass given ===DONE=== diff --git a/ext/standard/tests/streams/bug61115.phpt b/ext/standard/tests/streams/bug61115.phpt index 28a1838c1638a..cb11e23d38014 100644 --- a/ext/standard/tests/streams/bug61115.phpt +++ b/ext/standard/tests/streams/bug61115.phpt @@ -14,4 +14,4 @@ try { } ?> --EXPECT-- -preg_replace(): Argument #2 ($replace) must be of type string|array, Closure given +preg_replace(): Argument #2 ($replace) must be of type array|string, Closure given diff --git a/ext/standard/tests/strings/join_variation1.phpt b/ext/standard/tests/strings/join_variation1.phpt index 2e394c08a8907..a21251aec2a28 100644 --- a/ext/standard/tests/strings/join_variation1.phpt +++ b/ext/standard/tests/strings/join_variation1.phpt @@ -147,7 +147,7 @@ string(16) "element1element2" -- Iteration 23 -- string(16) "element1element2" -- Iteration 24 -- -join(): Argument #1 ($glue) must be of type string|array, resource given +join(): Argument #1 ($glue) must be of type array|string, resource given -- Iteration 25 -- string(16) "element1element2" -- Iteration 26 -- diff --git a/ext/standard/tests/strings/strtr_variation6.phpt b/ext/standard/tests/strings/strtr_variation6.phpt index 46902e5929d1f..fcc903d6377f4 100644 --- a/ext/standard/tests/strings/strtr_variation6.phpt +++ b/ext/standard/tests/strings/strtr_variation6.phpt @@ -119,7 +119,7 @@ string(6) "012atm" -- Iteration 16 -- string(6) "012ttm" -- Iteration 17 -- -strtr(): Argument #2 ($from) must be of type string|array, resource given +strtr(): Argument #2 ($from) must be of type array|string, resource given -- Iteration 18 -- string(6) "012atm" -- Iteration 19 -- diff --git a/ext/standard/tests/strings/strtr_variation8.phpt b/ext/standard/tests/strings/strtr_variation8.phpt index 65aba9c51b6e7..7ac60532f8b5b 100644 --- a/ext/standard/tests/strings/strtr_variation8.phpt +++ b/ext/standard/tests/strings/strtr_variation8.phpt @@ -136,7 +136,7 @@ strtr(): Argument #2 ($from) must be of type array, string given strtr(): Argument #2 ($from) must be of type array, string given -- Iteration 17 -- -strtr(): Argument #2 ($from) must be of type string|array, resource given +strtr(): Argument #2 ($from) must be of type array|string, resource given -- Iteration 18 -- strtr(): Argument #2 ($from) must be of type array, string given From 8107a1da5af480839b226882e5c27fd76b191ee1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1t=C3=A9=20Kocsis?= Date: Fri, 4 Sep 2020 14:23:43 +0200 Subject: [PATCH 62/87] Use ZPP instead of custom type checks We can add these types as a native type declaration to stubs as a side-effect. Closes GH-6068 --- ext/intl/formatter/formatter.stub.php | 3 +- ext/intl/formatter/formatter_arginfo.h | 4 +- ext/intl/formatter/formatter_attr.c | 2 +- ext/intl/php_intl.stub.php | 3 +- ext/intl/php_intl_arginfo.h | 4 +- ext/ldap/ldap.c | 66 +++++++------- ext/ldap/ldap.stub.php | 12 +-- ext/ldap/ldap_arginfo.h | 6 +- ext/reflection/php_reflection.c | 23 +++-- ext/reflection/php_reflection.stub.php | 3 +- ext/reflection/php_reflection_arginfo.h | 4 +- .../ReflectionClass_constructor_002.phpt | 8 +- .../tests/ReflectionClass_toString_001.phpt | 2 +- ext/snmp/snmp.c | 60 ++++++------- ext/snmp/snmp.stub.php | 30 ++----- ext/snmp/snmp_arginfo.h | 18 ++-- ext/snmp/tests/reflection.phpt | 89 ------------------- ext/spl/spl_observer.c | 35 +++++--- ext/spl/spl_observer.stub.php | 7 +- ext/spl/spl_observer_arginfo.h | 4 +- ext/spl/tests/multiple_iterator_001.phpt | 6 +- ext/standard/basic_functions.stub.php | 54 ++++------- ext/standard/basic_functions_arginfo.h | 18 ++-- ext/standard/password.c | 78 ++++++++-------- ext/standard/streamsfuncs.c | 84 +++++++++-------- ext/standard/string.c | 71 ++++++++------- .../tests/password/password_hash_error.phpt | 8 +- .../password/password_needs_rehash_error.phpt | 9 +- .../tests/strings/str_replace_basic.phpt | 2 +- .../tests/strings/str_replace_variation3.phpt | 19 ++-- 30 files changed, 302 insertions(+), 430 deletions(-) delete mode 100644 ext/snmp/tests/reflection.phpt diff --git a/ext/intl/formatter/formatter.stub.php b/ext/intl/formatter/formatter.stub.php index 4608c1917d57d..8c4694e4ecf50 100644 --- a/ext/intl/formatter/formatter.stub.php +++ b/ext/intl/formatter/formatter.stub.php @@ -40,11 +40,10 @@ public function formatCurrency(float $value, string $currency) {} public function parseCurrency(string $value, &$currency, &$position = null) {} /** - * @param int|float $value * @return bool * @alias numfmt_set_attribute */ - public function setAttribute(int $attr, $value) {} + public function setAttribute(int $attr, int|float $value) {} /** * @return int|float|false diff --git a/ext/intl/formatter/formatter_arginfo.h b/ext/intl/formatter/formatter_arginfo.h index ffc4eb5018646..e0531bcc20b27 100644 --- a/ext/intl/formatter/formatter_arginfo.h +++ b/ext/intl/formatter/formatter_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 041569278b83b65f67fb4848d00d5423e6728165 */ + * Stub hash: 60a05cccb434edadeec01cb7d43f919c276ce24d */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_NumberFormatter___construct, 0, 0, 2) ZEND_ARG_TYPE_INFO(0, locale, IS_STRING, 0) @@ -33,7 +33,7 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_class_NumberFormatter_setAttribute, 0, 0, 2) ZEND_ARG_TYPE_INFO(0, attr, IS_LONG, 0) - ZEND_ARG_INFO(0, value) + ZEND_ARG_TYPE_MASK(0, value, MAY_BE_LONG|MAY_BE_DOUBLE, NULL) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_class_NumberFormatter_getAttribute, 0, 0, 1) diff --git a/ext/intl/formatter/formatter_attr.c b/ext/intl/formatter/formatter_attr.c index 44a2bb15ff37f..a90fc4caaa327 100644 --- a/ext/intl/formatter/formatter_attr.c +++ b/ext/intl/formatter/formatter_attr.c @@ -129,7 +129,7 @@ PHP_FUNCTION( numfmt_set_attribute ) FORMATTER_METHOD_INIT_VARS; /* Parse parameters. */ - if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "Olz", + if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "Oln", &object, NumberFormatter_ce_ptr, &attribute, &value ) == FAILURE) { RETURN_THROWS(); diff --git a/ext/intl/php_intl.stub.php b/ext/intl/php_intl.stub.php index bf5e631ba4b4f..7662004f304bd 100644 --- a/ext/intl/php_intl.stub.php +++ b/ext/intl/php_intl.stub.php @@ -223,8 +223,7 @@ function numfmt_format_currency(NumberFormatter $fmt, float $value, string $curr */ function numfmt_parse_currency(NumberFormatter $fmt, string $value, &$currency, &$position = null): float|false {} -/** @param int|float $value */ -function numfmt_set_attribute(NumberFormatter $fmt, int $attr, $value): bool {} +function numfmt_set_attribute(NumberFormatter $fmt, int $attr, int|float $value): bool {} function numfmt_get_attribute(NumberFormatter $fmt, int $attr): int|float|false {} diff --git a/ext/intl/php_intl_arginfo.h b/ext/intl/php_intl_arginfo.h index cdead236438ed..3917187a5cc2d 100644 --- a/ext/intl/php_intl_arginfo.h +++ b/ext/intl/php_intl_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 9284fbafde8c7430a30a8fff5537bf9e6d9c6125 */ + * Stub hash: fdc7c500ddc5bc560ec54b7ce12d5961a4697a63 */ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_intlcal_create_instance, 0, 0, IntlCalendar, 1) ZEND_ARG_INFO_WITH_DEFAULT_VALUE(0, timeZone, "null") @@ -402,7 +402,7 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_numfmt_set_attribute, 0, 3, _IS_BOOL, 0) ZEND_ARG_OBJ_INFO(0, fmt, NumberFormatter, 0) ZEND_ARG_TYPE_INFO(0, attr, IS_LONG, 0) - ZEND_ARG_INFO(0, value) + ZEND_ARG_TYPE_MASK(0, value, MAY_BE_LONG|MAY_BE_DOUBLE, NULL) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_numfmt_get_attribute, 0, 2, MAY_BE_LONG|MAY_BE_DOUBLE|MAY_BE_FALSE) diff --git a/ext/ldap/ldap.c b/ext/ldap/ldap.c index c095749b6c8f8..977e35e4c3b3e 100644 --- a/ext/ldap/ldap.c +++ b/ext/ldap/ldap.c @@ -1423,7 +1423,9 @@ static void php_set_opts(LDAP *ldap, int sizelimit, int timelimit, int deref, in /* {{{ php_ldap_do_search */ static void php_ldap_do_search(INTERNAL_FUNCTION_PARAMETERS, int scope) { - zval *link, *base_dn, *filter, *attrs = NULL, *attr, *serverctrls = NULL; + zval *link, *attrs = NULL, *attr, *serverctrls = NULL; + zend_string *base_dn_str, *filter_str; + HashTable *base_dn_ht, *filter_ht; zend_long attrsonly, sizelimit, timelimit, deref; zend_string *ldap_filter = NULL, *ldap_base_dn = NULL; char **ldap_attrs = NULL; @@ -1434,10 +1436,18 @@ static void php_ldap_do_search(INTERNAL_FUNCTION_PARAMETERS, int scope) int old_ldap_sizelimit = -1, old_ldap_timelimit = -1, old_ldap_deref = -1; int num_attribs = 0, ret = 1, i, errno, argcount = ZEND_NUM_ARGS(); - if (zend_parse_parameters(argcount, "zzz|a/lllla/", &link, &base_dn, &filter, &attrs, &attrsonly, - &sizelimit, &timelimit, &deref, &serverctrls) == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_START(3, 9) + Z_PARAM_ZVAL(link) + Z_PARAM_STR_OR_ARRAY_HT(base_dn_str, base_dn_ht) + Z_PARAM_STR_OR_ARRAY_HT(filter_str, filter_ht) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_EX(attrs, 0, 1) + Z_PARAM_LONG(attrsonly) + Z_PARAM_LONG(sizelimit) + Z_PARAM_LONG(timelimit) + Z_PARAM_LONG(deref) + Z_PARAM_ARRAY_EX(serverctrls, 0, 1) + ZEND_PARSE_PARAMETERS_END(); /* Reverse -> fall through */ switch (argcount) { @@ -1486,38 +1496,34 @@ static void php_ldap_do_search(INTERNAL_FUNCTION_PARAMETERS, int scope) goto cleanup; } - if (Z_TYPE_P(base_dn) == IS_ARRAY) { - nbases = zend_hash_num_elements(Z_ARRVAL_P(base_dn)); + if (base_dn_ht) { + nbases = zend_hash_num_elements(base_dn_ht); if (nbases != nlinks) { php_error_docref(NULL, E_WARNING, "Base must either be a string, or an array with the same number of elements as the links array"); ret = 0; goto cleanup; } - zend_hash_internal_pointer_reset(Z_ARRVAL_P(base_dn)); + zend_hash_internal_pointer_reset(base_dn_ht); } else { nbases = 0; /* this means string, not array */ - ldap_base_dn = zval_get_string(base_dn); + ldap_base_dn = zend_string_copy(base_dn_str); if (EG(exception)) { ret = 0; goto cleanup; } } - if (Z_TYPE_P(filter) == IS_ARRAY) { - nfilters = zend_hash_num_elements(Z_ARRVAL_P(filter)); + if (filter_ht) { + nfilters = zend_hash_num_elements(filter_ht); if (nfilters != nlinks) { php_error_docref(NULL, E_WARNING, "Filter must either be a string, or an array with the same number of elements as the links array"); ret = 0; goto cleanup; } - zend_hash_internal_pointer_reset(Z_ARRVAL_P(filter)); + zend_hash_internal_pointer_reset(filter_ht); } else { nfilters = 0; /* this means string, not array */ - ldap_filter = zval_get_string(filter); - if (EG(exception)) { - ret = 0; - goto cleanup; - } + ldap_filter = zend_string_copy(filter_str); } lds = safe_emalloc(nlinks, sizeof(ldap_linkdata), 0); @@ -1533,8 +1539,8 @@ static void php_ldap_do_search(INTERNAL_FUNCTION_PARAMETERS, int scope) goto cleanup_parallel; } if (nbases != 0) { /* base_dn an array? */ - entry = zend_hash_get_current_data(Z_ARRVAL_P(base_dn)); - zend_hash_move_forward(Z_ARRVAL_P(base_dn)); + entry = zend_hash_get_current_data(base_dn_ht); + zend_hash_move_forward(base_dn_ht); ldap_base_dn = zval_get_string(entry); if (EG(exception)) { ret = 0; @@ -1542,8 +1548,8 @@ static void php_ldap_do_search(INTERNAL_FUNCTION_PARAMETERS, int scope) } } if (nfilters != 0) { /* filter an array? */ - entry = zend_hash_get_current_data(Z_ARRVAL_P(filter)); - zend_hash_move_forward(Z_ARRVAL_P(filter)); + entry = zend_hash_get_current_data(filter_ht); + zend_hash_move_forward(filter_ht); ldap_filter = zval_get_string(entry); if (EG(exception)) { ret = 0; @@ -1588,23 +1594,21 @@ static void php_ldap_do_search(INTERNAL_FUNCTION_PARAMETERS, int scope) efree(lds); efree(rcs); } else { - ldap_filter = zval_get_string(filter); - if (EG(exception)) { + ld = (ldap_linkdata *) zend_fetch_resource_ex(link, "ldap link", le_link); + if (ld == NULL) { ret = 0; goto cleanup; } - ldap_base_dn = zval_get_string(base_dn); - if (EG(exception)) { - ret = 0; - goto cleanup; + if (!base_dn_str) { + zend_argument_type_error(2, "must be of type string when argument #1 ($link_identifier) is a resource"); } + ldap_base_dn = zend_string_copy(base_dn_str); - ld = (ldap_linkdata *) zend_fetch_resource_ex(link, "ldap link", le_link); - if (ld == NULL) { - ret = 0; - goto cleanup; + if (!filter_str) { + zend_argument_type_error(3, "must be of type string when argument #1 ($link_identifier) is a resource"); } + ldap_filter = zend_string_copy(filter_str); if (argcount > 8) { lserverctrls = _php_ldap_controls_from_array(ld->link, serverctrls); diff --git a/ext/ldap/ldap.stub.php b/ext/ldap/ldap.stub.php index d8851b3314129..e46d1405453e8 100644 --- a/ext/ldap/ldap.stub.php +++ b/ext/ldap/ldap.stub.php @@ -35,27 +35,21 @@ function ldap_sasl_bind($link, string $binddn = UNKNOWN, string $password = UNKN /** * @param resource|array $link_identifier - * @param string|array $base_dn - * @param string|array $filter * @return resource|false */ -function ldap_read($link_identifier, $base_dn, $filter, array $attributes = [], int $attrsonly = 0, int $sizelimit = -1, int $timelimit = -1, int $deref = LDAP_DEREF_NEVER, array $servercontrols = []) {} +function ldap_read($link_identifier, array|string $base_dn, array|string $filter, array $attributes = [], int $attrsonly = 0, int $sizelimit = -1, int $timelimit = -1, int $deref = LDAP_DEREF_NEVER, array $servercontrols = []) {} /** * @param resource|array $link_identifier - * @param string|array $base_dn - * @param string|array $filter * @return resource|false */ -function ldap_list($link_identifier, $base_dn, $filter, array $attributes = [], int $attrsonly = 0, int $sizelimit = -1, int $timelimit = -1, int $deref = LDAP_DEREF_NEVER, array $servercontrols = []) {} +function ldap_list($link_identifier, array|string $base_dn, array|string $filter, array $attributes = [], int $attrsonly = 0, int $sizelimit = -1, int $timelimit = -1, int $deref = LDAP_DEREF_NEVER, array $servercontrols = []) {} /** * @param resource|array $link_identifier - * @param string|array $base_dn - * @param string|array $filter * @return resource|false */ -function ldap_search($link_identifier, $base_dn, $filter, array $attributes = [], int $attrsonly = 0, int $sizelimit = -1, int $timelimit = -1, int $deref = LDAP_DEREF_NEVER, array $servercontrols = []) {} +function ldap_search($link_identifier, array|string $base_dn, array|string $filter, array $attributes = [], int $attrsonly = 0, int $sizelimit = -1, int $timelimit = -1, int $deref = LDAP_DEREF_NEVER, array $servercontrols = []) {} /** @param resource $link_identifier */ function ldap_free_result($link_identifier): bool {} diff --git a/ext/ldap/ldap_arginfo.h b/ext/ldap/ldap_arginfo.h index 078fe220cd4fe..5e4cd4281c16d 100644 --- a/ext/ldap/ldap_arginfo.h +++ b/ext/ldap/ldap_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 6b5e8ddfbdc436fab3a263d6922146ca7c2f3845 */ + * Stub hash: c247d438a69d40353a629b09c5200d33ed8218ee */ #if defined(HAVE_ORALDAP) ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_connect, 0, 0, 0) @@ -52,8 +52,8 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_read, 0, 0, 3) ZEND_ARG_INFO(0, link_identifier) - ZEND_ARG_INFO(0, base_dn) - ZEND_ARG_INFO(0, filter) + ZEND_ARG_TYPE_MASK(0, base_dn, MAY_BE_ARRAY|MAY_BE_STRING, NULL) + ZEND_ARG_TYPE_MASK(0, filter, MAY_BE_ARRAY|MAY_BE_STRING, NULL) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, attributes, IS_ARRAY, 0, "[]") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, attrsonly, IS_LONG, 0, "0") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, sizelimit, IS_LONG, 0, "-1") diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index 11b834503bd9f..3b7c29b087ef9 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -3684,38 +3684,35 @@ ZEND_METHOD(ReflectionClassConstant, getAttributes) /* {{{ reflection_class_object_ctor */ static void reflection_class_object_ctor(INTERNAL_FUNCTION_PARAMETERS, int is_object) { - zval *argument; zval *object; + zend_string *arg_class = NULL; + zend_object *arg_obj; reflection_object *intern; zend_class_entry *ce; if (is_object) { ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_OBJECT(argument) + Z_PARAM_OBJ(arg_obj) ZEND_PARSE_PARAMETERS_END(); } else { ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_ZVAL(argument) + Z_PARAM_STR_OR_OBJ(arg_class, arg_obj) ZEND_PARSE_PARAMETERS_END(); } object = ZEND_THIS; intern = Z_REFLECTION_P(object); - if (Z_TYPE_P(argument) == IS_OBJECT) { - ZVAL_STR_COPY(reflection_prop_name(object), Z_OBJCE_P(argument)->name); - intern->ptr = Z_OBJCE_P(argument); + if (arg_obj) { + ZVAL_STR_COPY(reflection_prop_name(object), arg_obj->ce->name); + intern->ptr = arg_obj->ce; if (is_object) { - ZVAL_COPY(&intern->obj, argument); + ZVAL_OBJ_COPY(&intern->obj, arg_obj); } } else { - if (!try_convert_to_string(argument)) { - RETURN_THROWS(); - } - - if ((ce = zend_lookup_class(Z_STR_P(argument))) == NULL) { + if ((ce = zend_lookup_class(arg_class)) == NULL) { if (!EG(exception)) { - zend_throw_exception_ex(reflection_exception_ptr, -1, "Class \"%s\" does not exist", Z_STRVAL_P(argument)); + zend_throw_exception_ex(reflection_exception_ptr, -1, "Class \"%s\" does not exist", ZSTR_VAL(arg_class)); } RETURN_THROWS(); } diff --git a/ext/reflection/php_reflection.stub.php b/ext/reflection/php_reflection.stub.php index 539520597f0b9..311e748e9b3b9 100644 --- a/ext/reflection/php_reflection.stub.php +++ b/ext/reflection/php_reflection.stub.php @@ -202,8 +202,7 @@ class ReflectionClass implements Reflector { final private function __clone() {} - /** @param object|string $objectOrClass */ - public function __construct($objectOrClass) {} + public function __construct(object|string $objectOrClass) {} public function __toString(): string {} diff --git a/ext/reflection/php_reflection_arginfo.h b/ext/reflection/php_reflection_arginfo.h index 00013c7a507e6..c0ff2d75e2b25 100644 --- a/ext/reflection/php_reflection_arginfo.h +++ b/ext/reflection/php_reflection_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: beaf79270ab56d2e87a301a4a5d4444b2cc520d8 */ + * Stub hash: 1311fc5c498d6f16afb5a18aee2d60e72048174f */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Reflection_getModifierNames, 0, 0, 1) ZEND_ARG_TYPE_INFO(0, modifiers, IS_LONG, 0) @@ -150,7 +150,7 @@ ZEND_END_ARG_INFO() #define arginfo_class_ReflectionClass___clone arginfo_class_ReflectionFunctionAbstract___clone ZEND_BEGIN_ARG_INFO_EX(arginfo_class_ReflectionClass___construct, 0, 0, 1) - ZEND_ARG_INFO(0, objectOrClass) + ZEND_ARG_TYPE_MASK(0, objectOrClass, MAY_BE_OBJECT|MAY_BE_STRING, NULL) ZEND_END_ARG_INFO() #define arginfo_class_ReflectionClass___toString arginfo_class_ReflectionFunction___toString diff --git a/ext/reflection/tests/ReflectionClass_constructor_002.phpt b/ext/reflection/tests/ReflectionClass_constructor_002.phpt index 54f4b8eda2cc4..44ff37a96202e 100644 --- a/ext/reflection/tests/ReflectionClass_constructor_002.phpt +++ b/ext/reflection/tests/ReflectionClass_constructor_002.phpt @@ -28,7 +28,7 @@ try { try { var_dump(new ReflectionClass(array(1,2,3))); -} catch (Exception $e) { +} catch (TypeError $e) { echo $e->getMessage() . "\n"; } @@ -45,13 +45,11 @@ try { } ?> ---EXPECTF-- +--EXPECT-- ReflectionClass::__construct() expects exactly 1 parameter, 0 given Class "" does not exist Class "1" does not exist Class "1" does not exist - -Warning: Array to string conversion in %s on line %d -Class "Array" does not exist +ReflectionClass::__construct(): Argument #1 ($objectOrClass) must be of type object|string, array given ReflectionClass::__construct() expects exactly 1 parameter, 2 given Class "X" does not exist diff --git a/ext/reflection/tests/ReflectionClass_toString_001.phpt b/ext/reflection/tests/ReflectionClass_toString_001.phpt index bb9ead8ce3519..00e41bfcc9f68 100644 --- a/ext/reflection/tests/ReflectionClass_toString_001.phpt +++ b/ext/reflection/tests/ReflectionClass_toString_001.phpt @@ -37,7 +37,7 @@ Class [ class ReflectionClass implements Reflector, String Method [ public method __construct ] { - Parameters [1] { - Parameter #0 [ $objectOrClass ] + Parameter #0 [ object|string $objectOrClass ] } } diff --git a/ext/snmp/snmp.c b/ext/snmp/snmp.c index ab512c68d0deb..e7f3076c12d8f 100644 --- a/ext/snmp/snmp.c +++ b/ext/snmp/snmp.c @@ -659,8 +659,10 @@ static void php_snmp_internal(INTERNAL_FUNCTION_PARAMETERS, int st, * OID parser (and type, value for SNMP_SET command) */ -static int php_snmp_parse_oid(zval *object, int st, struct objid_query *objid_query, zend_string *oid_str, HashTable *oid_ht, zval *type, zval *value) -{ +static int php_snmp_parse_oid( + zval *object, int st, struct objid_query *objid_query, zend_string *oid_str, HashTable *oid_ht, + zend_string *type_str, HashTable *type_ht, zend_string *value_str, HashTable *value_ht +) { char *pptr; uint32_t idx_type = 0, idx_value = 0; zval *tmp_oid, *tmp_type, *tmp_value; @@ -671,15 +673,15 @@ static int php_snmp_parse_oid(zval *object, int st, struct objid_query *objid_qu objid_query->vars = (snmpobjarg *)emalloc(sizeof(snmpobjarg)); objid_query->vars[objid_query->count].oid = ZSTR_VAL(oid_str); if (st & SNMP_CMD_SET) { - if (Z_TYPE_P(type) == IS_STRING && Z_TYPE_P(value) == IS_STRING) { - if (Z_STRLEN_P(type) != 1) { - php_error_docref(NULL, E_WARNING, "Bogus type '%s', should be single char, got %zu", Z_STRVAL_P(type), Z_STRLEN_P(type)); + if (type_str && value_str) { + if (ZSTR_LEN(type_str) != 1) { + php_error_docref(NULL, E_WARNING, "Bogus type '%s', should be single char, got %zu", ZSTR_VAL(type_str), ZSTR_LEN(type_str)); efree(objid_query->vars); return FALSE; } - pptr = Z_STRVAL_P(type); + pptr = ZSTR_VAL(type_str); objid_query->vars[objid_query->count].type = *pptr; - objid_query->vars[objid_query->count].value = Z_STRVAL_P(value); + objid_query->vars[objid_query->count].value = ZSTR_VAL(value_str); } else { php_error_docref(NULL, E_WARNING, "Single objid and multiple type or values are not supported"); efree(objid_query->vars); @@ -698,18 +700,18 @@ static int php_snmp_parse_oid(zval *object, int st, struct objid_query *objid_qu convert_to_string_ex(tmp_oid); objid_query->vars[objid_query->count].oid = Z_STRVAL_P(tmp_oid); if (st & SNMP_CMD_SET) { - if (Z_TYPE_P(type) == IS_STRING) { - pptr = Z_STRVAL_P(type); + if (type_str) { + pptr = ZSTR_VAL(type_str); objid_query->vars[objid_query->count].type = *pptr; - } else if (Z_TYPE_P(type) == IS_ARRAY) { - while (idx_type < Z_ARRVAL_P(type)->nNumUsed) { - tmp_type = &Z_ARRVAL_P(type)->arData[idx_type].val; + } else if (type_ht) { + while (idx_type < type_ht->nNumUsed) { + tmp_type = &type_ht->arData[idx_type].val; if (Z_TYPE_P(tmp_type) != IS_UNDEF) { break; } idx_type++; } - if (idx_type < Z_ARRVAL_P(type)->nNumUsed) { + if (idx_type < type_ht->nNumUsed) { convert_to_string_ex(tmp_type); if (Z_STRLEN_P(tmp_type) != 1) { php_error_docref(NULL, E_WARNING, "'%s': bogus type '%s', should be single char, got %zu", Z_STRVAL_P(tmp_oid), Z_STRVAL_P(tmp_type), Z_STRLEN_P(tmp_type)); @@ -726,17 +728,17 @@ static int php_snmp_parse_oid(zval *object, int st, struct objid_query *objid_qu } } - if (Z_TYPE_P(value) == IS_STRING) { - objid_query->vars[objid_query->count].value = Z_STRVAL_P(value); - } else if (Z_TYPE_P(value) == IS_ARRAY) { - while (idx_value < Z_ARRVAL_P(value)->nNumUsed) { - tmp_value = &Z_ARRVAL_P(value)->arData[idx_value].val; + if (value_str) { + objid_query->vars[objid_query->count].value = ZSTR_VAL(value_str); + } else if (value_ht) { + while (idx_value < value_ht->nNumUsed) { + tmp_value = &value_ht->arData[idx_value].val; if (Z_TYPE_P(tmp_value) != IS_UNDEF) { break; } idx_value++; } - if (idx_value < Z_ARRVAL_P(value)->nNumUsed) { + if (idx_value < value_ht->nNumUsed) { convert_to_string_ex(tmp_value); objid_query->vars[objid_query->count].value = Z_STRVAL_P(tmp_value); idx_value++; @@ -1077,15 +1079,13 @@ static int netsnmp_session_set_security(struct snmp_session *session, char *sec_ */ static void php_snmp(INTERNAL_FUNCTION_PARAMETERS, int st, int version) { - zend_string *oid_str; - HashTable *oid_ht; - zval *value = NULL, *type = NULL; + zend_string *oid_str, *type_str = NULL, *value_str = NULL; + HashTable *oid_ht, *type_ht = NULL, *value_ht = NULL; char *a1, *a2, *a3, *a4, *a5, *a6, *a7; size_t a1_len, a2_len, a3_len, a4_len, a5_len, a6_len, a7_len; zend_bool use_orignames = 0, suffix_keys = 0; zend_long timeout = SNMP_DEFAULT_TIMEOUT; zend_long retries = SNMP_DEFAULT_RETRIES; - int argc = ZEND_NUM_ARGS(); struct objid_query objid_query; php_snmp_session *session; int session_less_mode = (getThis() == NULL); @@ -1109,8 +1109,8 @@ static void php_snmp(INTERNAL_FUNCTION_PARAMETERS, int st, int version) Z_PARAM_STRING(a6, a6_len) Z_PARAM_STRING(a7, a7_len) Z_PARAM_STR_OR_ARRAY_HT(oid_str, oid_ht) - Z_PARAM_ZVAL(type) - Z_PARAM_ZVAL(value) + Z_PARAM_STR_OR_ARRAY_HT(type_str, type_ht) + Z_PARAM_STR_OR_ARRAY_HT(value_str, value_ht) Z_PARAM_OPTIONAL Z_PARAM_LONG(timeout) Z_PARAM_LONG(retries) @@ -1140,8 +1140,8 @@ static void php_snmp(INTERNAL_FUNCTION_PARAMETERS, int st, int version) Z_PARAM_STRING(a1, a1_len) Z_PARAM_STRING(a2, a2_len) Z_PARAM_STR_OR_ARRAY_HT(oid_str, oid_ht) - Z_PARAM_ZVAL(type) - Z_PARAM_ZVAL(value) + Z_PARAM_STR_OR_ARRAY_HT(type_str, type_ht) + Z_PARAM_STR_OR_ARRAY_HT(value_str, value_ht) Z_PARAM_OPTIONAL Z_PARAM_LONG(timeout) Z_PARAM_LONG(retries) @@ -1165,8 +1165,8 @@ static void php_snmp(INTERNAL_FUNCTION_PARAMETERS, int st, int version) if (st & SNMP_CMD_SET) { ZEND_PARSE_PARAMETERS_START(3, 3) Z_PARAM_STR_OR_ARRAY_HT(oid_str, oid_ht) - Z_PARAM_ZVAL(type) - Z_PARAM_ZVAL(value) + Z_PARAM_STR_OR_ARRAY_HT(type_str, type_ht) + Z_PARAM_STR_OR_ARRAY_HT(value_str, value_ht) ZEND_PARSE_PARAMETERS_END(); } else if (st & SNMP_CMD_WALK) { ZEND_PARSE_PARAMETERS_START(1, 4) @@ -1197,7 +1197,7 @@ static void php_snmp(INTERNAL_FUNCTION_PARAMETERS, int st, int version) } } - if (!php_snmp_parse_oid(getThis(), st, &objid_query, oid_str, oid_ht, type, value)) { + if (!php_snmp_parse_oid(getThis(), st, &objid_query, oid_str, oid_ht, type_str, type_ht, value_str, value_ht)) { RETURN_FALSE; } diff --git a/ext/snmp/snmp.stub.php b/ext/snmp/snmp.stub.php index 72d42e34613ae..1b7c1ac20ef69 100644 --- a/ext/snmp/snmp.stub.php +++ b/ext/snmp/snmp.stub.php @@ -13,11 +13,7 @@ function snmprealwalk(string $host, string $community, array|string $object_id, /** @alias snmprealwalk */ function snmpwalkoid(string $host, string $community, array|string $object_id, int $timeout = -1, int $retries = -1): array|bool {} -/** - * @param array|string $type - * @param array|string $value - */ -function snmpset(string $host, string $community, array|string $object_id, $type, $value, int $timeout = -1, int $retries = -1): array|bool {} +function snmpset(string $host, string $community, array|string $object_id, array|string $type, array|string $value, int $timeout = -1, int $retries = -1): array|bool {} function snmp_get_quick_print(): bool {} @@ -38,11 +34,7 @@ function snmp2_walk(string $host, string $community, array|string $object_id, in function snmp2_real_walk(string $host, string $community, array|string $object_id, int $timeout = -1, int $retries = -1): array|bool {} -/** - * @param array|string $type - * @param array|string $value - */ -function snmp2_set(string $host, string $community, array|string $object_id, $type, $value, int $timeout = -1, int $retries = -1): array|bool {} +function snmp2_set(string $host, string $community, array|string $object_id, array|string $type, array|string $value, int $timeout = -1, int $retries = -1): array|bool {} function snmp3_get(string $host, string $sec_name, string $sec_level, string $auth_protocol, string $auth_passphrase, string $priv_protocol, string $priv_passphrase, array|string $object_id, int $timeout = -1, int $retries = -1): array|bool {} @@ -52,11 +44,7 @@ function snmp3_walk(string $host, string $sec_name, string $sec_level, string $a function snmp3_real_walk(string $host, string $sec_name, string $sec_level, string $auth_protocol, string $auth_passphrase, string $priv_protocol, string $priv_passphrase, array|string $object_id, int $timeout = -1, int $retries = -1): array|bool {} -/** - * @param array|string $type - * @param array|string $value - */ -function snmp3_set(string $host, string $sec_name, string $sec_level, string $auth_protocol, string $auth_passphrase, string $priv_protocol, string $priv_passphrase, array|string $object_id, $type, $value, int $timeout = -1, int $retries = -1): array|bool {} +function snmp3_set(string $host, string $sec_name, string $sec_level, string $auth_protocol, string $auth_passphrase, string $priv_protocol, string $priv_passphrase, array|string $object_id, array|string $type, array|string $value, int $timeout = -1, int $retries = -1): array|bool {} function snmp_set_valueretrieval(int $method): bool {} @@ -81,14 +69,10 @@ public function get(array|string $object_id, bool $use_orignames = false) {} public function getnext(array|string $object_id) {} /** @return array|bool */ - public function walk(array|string $object_id, bool $suffix_keys = false, int $max_repetitions = UNKNOWN, int $non_repeaters = UNKNOWN) {} - - /** - * @param array|string $type - * @param array|string $value - * @return array|bool - */ - public function set(array|string $object_id, $type, $value) {} + public function walk(array|string $object_id, bool $suffix_keys = false, int $max_repetitions = -1, int $non_repeaters = -1) {} + + /** @return array|bool */ + public function set(array|string $object_id, array|string $type, array|string $value) {} /** @return int */ public function getErrno() {} diff --git a/ext/snmp/snmp_arginfo.h b/ext/snmp/snmp_arginfo.h index 8a734fd573693..5c4a0c35a8df0 100644 --- a/ext/snmp/snmp_arginfo.h +++ b/ext/snmp/snmp_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 02b1dd87856dfdb43039f4544f3e5225a1fb1a6e */ + * Stub hash: c9906ff8ef879e567cf8aed9a34dcff850f3e949 */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_snmpget, 0, 3, MAY_BE_ARRAY|MAY_BE_BOOL) ZEND_ARG_TYPE_INFO(0, host, IS_STRING, 0) @@ -21,8 +21,8 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_snmpset, 0, 5, MAY_BE_ARRAY|MAY_ ZEND_ARG_TYPE_INFO(0, host, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, community, IS_STRING, 0) ZEND_ARG_TYPE_MASK(0, object_id, MAY_BE_ARRAY|MAY_BE_STRING, NULL) - ZEND_ARG_INFO(0, type) - ZEND_ARG_INFO(0, value) + ZEND_ARG_TYPE_MASK(0, type, MAY_BE_ARRAY|MAY_BE_STRING, NULL) + ZEND_ARG_TYPE_MASK(0, value, MAY_BE_ARRAY|MAY_BE_STRING, NULL) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, timeout, IS_LONG, 0, "-1") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, retries, IS_LONG, 0, "-1") ZEND_END_ARG_INFO() @@ -82,8 +82,8 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_snmp3_set, 0, 10, MAY_BE_ARRAY|M ZEND_ARG_TYPE_INFO(0, priv_protocol, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, priv_passphrase, IS_STRING, 0) ZEND_ARG_TYPE_MASK(0, object_id, MAY_BE_ARRAY|MAY_BE_STRING, NULL) - ZEND_ARG_INFO(0, type) - ZEND_ARG_INFO(0, value) + ZEND_ARG_TYPE_MASK(0, type, MAY_BE_ARRAY|MAY_BE_STRING, NULL) + ZEND_ARG_TYPE_MASK(0, value, MAY_BE_ARRAY|MAY_BE_STRING, NULL) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, timeout, IS_LONG, 0, "-1") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, retries, IS_LONG, 0, "-1") ZEND_END_ARG_INFO() @@ -132,14 +132,14 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_class_SNMP_walk, 0, 0, 1) ZEND_ARG_TYPE_MASK(0, object_id, MAY_BE_ARRAY|MAY_BE_STRING, NULL) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, suffix_keys, _IS_BOOL, 0, "false") - ZEND_ARG_TYPE_INFO(0, max_repetitions, IS_LONG, 0) - ZEND_ARG_TYPE_INFO(0, non_repeaters, IS_LONG, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, max_repetitions, IS_LONG, 0, "-1") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, non_repeaters, IS_LONG, 0, "-1") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_class_SNMP_set, 0, 0, 3) ZEND_ARG_TYPE_MASK(0, object_id, MAY_BE_ARRAY|MAY_BE_STRING, NULL) - ZEND_ARG_INFO(0, type) - ZEND_ARG_INFO(0, value) + ZEND_ARG_TYPE_MASK(0, type, MAY_BE_ARRAY|MAY_BE_STRING, NULL) + ZEND_ARG_TYPE_MASK(0, value, MAY_BE_ARRAY|MAY_BE_STRING, NULL) ZEND_END_ARG_INFO() #define arginfo_class_SNMP_getErrno arginfo_class_SNMP_close diff --git a/ext/snmp/tests/reflection.phpt b/ext/snmp/tests/reflection.phpt deleted file mode 100644 index 53fc063be6c33..0000000000000 --- a/ext/snmp/tests/reflection.phpt +++ /dev/null @@ -1,89 +0,0 @@ ---TEST-- -Test SNMP Reflection ---SKIPIF-- - ---FILE-- - ---EXPECT-- -Method [ public method __construct ] { - - - Parameters [5] { - Parameter #0 [ int $version ] - Parameter #1 [ string $host ] - Parameter #2 [ string $community ] - Parameter #3 [ int $timeout ] - Parameter #4 [ int $retries ] - } -} -Method [ public method close ] { - - - Parameters [0] { - } -} -Method [ public method setSecurity ] { - - - Parameters [7] { - Parameter #0 [ string $sec_level ] - Parameter #1 [ string $auth_protocol ] - Parameter #2 [ string $auth_passphrase ] - Parameter #3 [ string $priv_protocol ] - Parameter #4 [ string $priv_passphrase ] - Parameter #5 [ string $contextName ] - Parameter #6 [ string $contextEngineID ] - } -} -Method [ public method get ] { - - - Parameters [2] { - Parameter #0 [ $object_id ] - Parameter #1 [ bool $use_orignames ] - } -} -Method [ public method getnext ] { - - - Parameters [1] { - Parameter #0 [ $object_id ] - } -} -Method [ public method walk ] { - - - Parameters [4] { - Parameter #0 [ $object_id ] - Parameter #1 [ bool $suffix_keys ] - Parameter #2 [ int $max_repetitions ] - Parameter #3 [ int $non_repeaters ] - } -} -Method [ public method set ] { - - - Parameters [3] { - Parameter #0 [ $object_id ] - Parameter #1 [ $type ] - Parameter #2 [ $value ] - } -} -Method [ public method getErrno ] { - - - Parameters [0] { - } -} -Method [ public method getError ] { - - - Parameters [0] { - } -} diff --git a/ext/spl/spl_observer.c b/ext/spl/spl_observer.c index eaad4db815c11..3f134b77dbad1 100644 --- a/ext/spl/spl_observer.c +++ b/ext/spl/spl_observer.c @@ -935,34 +935,43 @@ PHP_METHOD(MultipleIterator, setFlags) /* {{{ Attach a new iterator */ PHP_METHOD(MultipleIterator, attachIterator) { - spl_SplObjectStorage *intern; - zval *iterator = NULL, *info = NULL; - - if (zend_parse_parameters(ZEND_NUM_ARGS(), "O|z!", &iterator, zend_ce_iterator, &info) == FAILURE) { - RETURN_THROWS(); - } + spl_SplObjectStorage *intern; + zval *iterator = NULL; + zval zinfo; + zend_string *info_str; + zend_long info_long; + zend_bool info_is_null = 1; + + ZEND_PARSE_PARAMETERS_START(1, 2) + Z_PARAM_OBJECT_OF_CLASS(iterator, zend_ce_iterator) + Z_PARAM_OPTIONAL + Z_PARAM_STR_OR_LONG_OR_NULL(info_str, info_long, info_is_null) + ZEND_PARSE_PARAMETERS_END(); intern = Z_SPLOBJSTORAGE_P(ZEND_THIS); - if (info != NULL) { + if (!info_is_null) { spl_SplObjectStorageElement *element; - if (Z_TYPE_P(info) != IS_LONG && Z_TYPE_P(info) != IS_STRING) { - zend_throw_exception(spl_ce_InvalidArgumentException, "Info must be NULL, integer or string", 0); - RETURN_THROWS(); + if (info_str) { + ZVAL_STR(&zinfo, info_str); + } else { + ZVAL_LONG(&zinfo, info_long); } zend_hash_internal_pointer_reset_ex(&intern->storage, &intern->pos); while ((element = zend_hash_get_current_data_ptr_ex(&intern->storage, &intern->pos)) != NULL) { - if (fast_is_identical_function(info, &element->inf)) { + if (fast_is_identical_function(&zinfo, &element->inf)) { zend_throw_exception(spl_ce_InvalidArgumentException, "Key duplication error", 0); RETURN_THROWS(); } zend_hash_move_forward_ex(&intern->storage, &intern->pos); } - } - spl_object_storage_attach(intern, iterator, info); + spl_object_storage_attach(intern, iterator, &zinfo); + } else { + spl_object_storage_attach(intern, iterator, NULL); + } } /* }}} */ diff --git a/ext/spl/spl_observer.stub.php b/ext/spl/spl_observer.stub.php index e399b13c98808..475f3b8dc7210 100644 --- a/ext/spl/spl_observer.stub.php +++ b/ext/spl/spl_observer.stub.php @@ -120,11 +120,8 @@ public function getFlags() {} /** @return void */ public function setFlags(int $flags) {} - /** - * @param int|string|null $info - * @return void - */ - public function attachIterator(Iterator $iterator, $info = null) {} + /** @return void */ + public function attachIterator(Iterator $iterator, string|int|null $info = null) {} /** @return void */ public function detachIterator(Iterator $iterator) {} diff --git a/ext/spl/spl_observer_arginfo.h b/ext/spl/spl_observer_arginfo.h index 3c08a44268553..eed972b2830e4 100644 --- a/ext/spl/spl_observer_arginfo.h +++ b/ext/spl/spl_observer_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: f795244462fc7b6aed3f38f6b2e1985b3a2ab7c1 */ + * Stub hash: aab6134fb2223ffe4d686f3a601e66da17c99511 */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_SplObserver_update, 0, 0, 1) ZEND_ARG_OBJ_INFO(0, subject, SplSubject, 0) @@ -94,7 +94,7 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_class_MultipleIterator_attachIterator, 0, 0, 1) ZEND_ARG_OBJ_INFO(0, iterator, Iterator, 0) - ZEND_ARG_INFO_WITH_DEFAULT_VALUE(0, info, "null") + ZEND_ARG_TYPE_MASK(0, info, MAY_BE_STRING|MAY_BE_LONG|MAY_BE_NULL, "null") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_class_MultipleIterator_detachIterator, 0, 0, 1) diff --git a/ext/spl/tests/multiple_iterator_001.phpt b/ext/spl/tests/multiple_iterator_001.phpt index 56a08da272dd6..7f2b971b556e9 100644 --- a/ext/spl/tests/multiple_iterator_001.phpt +++ b/ext/spl/tests/multiple_iterator_001.phpt @@ -79,8 +79,8 @@ echo "-- Associate with invalid value --\n"; try { $m->attachIterator($iter3, new stdClass()); -} catch(InvalidArgumentException $e) { - echo "InvalidArgumentException thrown: " . $e->getMessage() . "\n"; +} catch(TypeError $e) { + echo "TypeError thrown: " . $e->getMessage() . "\n"; } echo "-- Associate with duplicate value --\n"; @@ -297,7 +297,7 @@ array(3) { int(3) } -- Associate with invalid value -- -InvalidArgumentException thrown: Info must be NULL, integer or string +TypeError thrown: MultipleIterator::attachIterator(): Argument #2 ($info) must be of type string|int|null, stdClass given -- Associate with duplicate value -- InvalidArgumentException thrown: Key duplication error -- Count, contains, detach, count, contains, iterate -- diff --git a/ext/standard/basic_functions.stub.php b/ext/standard/basic_functions.stub.php index 73a82b627d7c3..75819c7fb556b 100755 --- a/ext/standard/basic_functions.stub.php +++ b/ext/standard/basic_functions.stub.php @@ -121,8 +121,8 @@ function array_search(mixed $needle, array $haystack, bool $strict = false): int function extract(array &$array, int $extract_type = EXTR_OVERWRITE, string $prefix = ""): int {} /** - * @param string|array $var_name - * @param string|array $var_names + * @param array|string $var_name + * @param array|string $var_names */ function compact($var_name, ...$var_names): array {} @@ -131,11 +131,10 @@ function array_fill(int $start_key, int $num, mixed $val): array {} function array_fill_keys(array $keys, mixed $val): array {} /** - * @param int|float|string $low - * @param int|float|string $high - * @param int|float $step + * @param string|int|float $low + * @param string|int|float $high */ -function range($low, $high, $step = 1): array {} +function range($low, $high, int|float $step = 1): array {} function shuffle(array &$array): bool {} @@ -245,11 +244,11 @@ function array_filter(array $array, ?callable $callback = null, int $use_keys = function array_map(?callable $callback, array $array1, array ...$arrays): array {} -/** @param int|string $key */ +/** @param string|int $key */ function array_key_exists($key, array $search): bool {} /** - * @param int|string $key + * @param string|int $key * @alias array_key_exists */ function key_exists($key, array $search): bool {} @@ -507,10 +506,10 @@ function header(string $string, bool $replace = true, int $http_response_code = function header_remove(string $name = UNKNOWN): void {} -/** @param int|array $expires_or_options */ +/** @param array|int $expires_or_options */ function setrawcookie(string $name, string $value = '', $expires_or_options = 0, string $path = '', string $domain = '', bool $secure = false, bool $httponly = false): bool {} -/** @param int|array $expires_or_options */ +/** @param array|int $expires_or_options */ function setcookie(string $name, string $value = '', $expires_or_options = 0, string $path = '', string $domain = '', bool $secure = false, bool $httponly = false): bool {} function http_response_code(int $response_code = 0): int|bool {} @@ -621,8 +620,7 @@ function substr(string $str, int $start, ?int $length = null): string|false {} * @param mixed $start * @param mixed $length */ -function substr_replace( - string|array $str, string|array $replace, $start, $length = UNKNOWN): string|array|false {} +function substr_replace(array|string $str, string|array $replace, $start, $length = UNKNOWN): string|array|false {} function quotemeta(string $str): string {} @@ -651,21 +649,11 @@ function stripcslashes(string $str): string {} function stripslashes(string $str): string {} -/** - * @param string|array $search - * @param string|array $replace - * @param int $replace_count - */ -function str_replace( - $search, $replace, string|array $subject, &$replace_count = UNKNOWN): string|array {} +/** @param int $replace_count */ +function str_replace(array|string $search, array|string $replace, string|array $subject, &$replace_count = UNKNOWN): string|array {} -/** - * @param string|array $search - * @param string|array $replace - * @param int $replace_count - */ -function str_ireplace( - $search, $replace, string|array $subject, &$replace_count = UNKNOWN): string|array {} +/** @param int $replace_count */ +function str_ireplace(array|string $search, array|string $replace, string|array $subject, &$replace_count = UNKNOWN): string|array {} function hebrev(string $str, int $max_chars_per_line = 0): string {} @@ -1166,11 +1154,9 @@ function unpack(string $format, string $data, int $offset = 0): array|false {} function password_get_info(string $hash): ?array {} -/** @param string|int $algo */ -function password_hash(string $password, $algo, array $options = []): string {} +function password_hash(string $password, string|int|null $algo, array $options = []): string {} -/** @param string|int $algo */ -function password_needs_rehash(string $hash, $algo, array $options = []): bool {} +function password_needs_rehash(string $hash, string|int $algo, array $options = []): bool {} function password_verify(string $password, string $hash): bool {} @@ -1240,12 +1226,8 @@ function stream_context_set_params($context, array $params): bool {} /** @param resource $context */ function stream_context_get_params($context): array {} -/** - * @param resource $context - * @param array|string $param2 - * @param mixed $value - */ -function stream_context_set_option($context, $param2, string $option_name = UNKNOWN, mixed $value = UNKNOWN): bool {} +/** @param resource $context */ +function stream_context_set_option($context, array|string $wrapper_or_options, ?string $option_name = null, mixed $value = UNKNOWN): bool {} /** @param resource $stream_or_context */ function stream_context_get_options($stream_or_context): array {} diff --git a/ext/standard/basic_functions_arginfo.h b/ext/standard/basic_functions_arginfo.h index 31200dbb92d3f..9d13b25b855bd 100755 --- a/ext/standard/basic_functions_arginfo.h +++ b/ext/standard/basic_functions_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 8b6ef365e9635c92ef86adb40b2aba077867f3b2 */ + * Stub hash: 010a6e0dee6d5e419e66eeefadd4dfabbbddfaca */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_set_time_limit, 0, 1, _IS_BOOL, 0) ZEND_ARG_TYPE_INFO(0, seconds, IS_LONG, 0) @@ -183,7 +183,7 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_range, 0, 2, IS_ARRAY, 0) ZEND_ARG_INFO(0, low) ZEND_ARG_INFO(0, high) - ZEND_ARG_INFO_WITH_DEFAULT_VALUE(0, step, "1") + ZEND_ARG_TYPE_MASK(0, step, MAY_BE_LONG|MAY_BE_DOUBLE, "1") ZEND_END_ARG_INFO() #define arginfo_shuffle arginfo_natsort @@ -938,7 +938,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_substr, 0, 2, MAY_BE_STRING|MAY_ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_substr_replace, 0, 3, MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_FALSE) - ZEND_ARG_TYPE_MASK(0, str, MAY_BE_STRING|MAY_BE_ARRAY, NULL) + ZEND_ARG_TYPE_MASK(0, str, MAY_BE_ARRAY|MAY_BE_STRING, NULL) ZEND_ARG_TYPE_MASK(0, replace, MAY_BE_STRING|MAY_BE_ARRAY, NULL) ZEND_ARG_INFO(0, start) ZEND_ARG_INFO(0, length) @@ -989,8 +989,8 @@ ZEND_END_ARG_INFO() #define arginfo_stripslashes arginfo_base64_encode ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_str_replace, 0, 3, MAY_BE_STRING|MAY_BE_ARRAY) - ZEND_ARG_INFO(0, search) - ZEND_ARG_INFO(0, replace) + ZEND_ARG_TYPE_MASK(0, search, MAY_BE_ARRAY|MAY_BE_STRING, NULL) + ZEND_ARG_TYPE_MASK(0, replace, MAY_BE_ARRAY|MAY_BE_STRING, NULL) ZEND_ARG_TYPE_MASK(0, subject, MAY_BE_STRING|MAY_BE_ARRAY, NULL) ZEND_ARG_INFO(1, replace_count) ZEND_END_ARG_INFO() @@ -1771,13 +1771,13 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_password_hash, 0, 2, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, password, IS_STRING, 0) - ZEND_ARG_INFO(0, algo) + ZEND_ARG_TYPE_MASK(0, algo, MAY_BE_STRING|MAY_BE_LONG|MAY_BE_NULL, NULL) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, options, IS_ARRAY, 0, "[]") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_password_needs_rehash, 0, 2, _IS_BOOL, 0) ZEND_ARG_TYPE_INFO(0, hash, IS_STRING, 0) - ZEND_ARG_INFO(0, algo) + ZEND_ARG_TYPE_MASK(0, algo, MAY_BE_STRING|MAY_BE_LONG, NULL) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, options, IS_ARRAY, 0, "[]") ZEND_END_ARG_INFO() @@ -1877,8 +1877,8 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_stream_context_set_option, 0, 2, _IS_BOOL, 0) ZEND_ARG_INFO(0, context) - ZEND_ARG_INFO(0, param2) - ZEND_ARG_TYPE_INFO(0, option_name, IS_STRING, 0) + ZEND_ARG_TYPE_MASK(0, wrapper_or_options, MAY_BE_ARRAY|MAY_BE_STRING, NULL) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, option_name, IS_STRING, 1, "null") ZEND_ARG_TYPE_INFO(0, value, IS_MIXED, 0) ZEND_END_ARG_INFO() diff --git a/ext/standard/password.c b/ext/standard/password.c index de21569a44c8a..687a780d1d556 100644 --- a/ext/standard/password.c +++ b/ext/standard/password.c @@ -487,46 +487,40 @@ const php_password_algo* php_password_algo_find(const zend_string *ident) { return Z_PTR_P(tmp); } -static const php_password_algo* php_password_algo_find_zval_ex(zval *arg, const php_password_algo* default_algo) { - if (!arg || (Z_TYPE_P(arg) == IS_NULL)) { - return default_algo; +static const php_password_algo* php_password_algo_find_zval(zend_string *arg_str, zend_long arg_long, zend_bool arg_is_null) { + if (arg_is_null) { + return php_password_algo_default(); + } + + if (arg_str) { + return php_password_algo_find(arg_str); } - if (Z_TYPE_P(arg) == IS_LONG) { - switch (Z_LVAL_P(arg)) { - case 0: return default_algo; - case 1: return &php_password_algo_bcrypt; + switch (arg_long) { + case 0: return php_password_algo_default(); + case 1: return &php_password_algo_bcrypt; #if HAVE_ARGON2LIB - case 2: return &php_password_algo_argon2i; - case 3: return &php_password_algo_argon2id; + case 2: return &php_password_algo_argon2i; + case 3: return &php_password_algo_argon2id; #else - case 2: - { - zend_string *n = zend_string_init("argon2i", sizeof("argon2i")-1, 0); - const php_password_algo* ret = php_password_algo_find(n); - zend_string_release(n); - return ret; - } - case 3: - { - zend_string *n = zend_string_init("argon2id", sizeof("argon2id")-1, 0); - const php_password_algo* ret = php_password_algo_find(n); - zend_string_release(n); - return ret; - } + case 2: + { + zend_string *n = zend_string_init("argon2i", sizeof("argon2i")-1, 0); + const php_password_algo* ret = php_password_algo_find(n); + zend_string_release(n); + return ret; + } + case 3: + { + zend_string *n = zend_string_init("argon2id", sizeof("argon2id")-1, 0); + const php_password_algo* ret = php_password_algo_find(n); + zend_string_release(n); + return ret; + } #endif - } - return NULL; } - if (Z_TYPE_P(arg) != IS_STRING) { - return NULL; - } - - return php_password_algo_find(Z_STR_P(arg)); -} -static const php_password_algo* php_password_algo_find_zval(zval *arg) { - return php_password_algo_find_zval_ex(arg, php_password_algo_default()); + return NULL; } zend_string *php_password_algo_extract_ident(const zend_string* hash) { @@ -605,17 +599,19 @@ PHP_FUNCTION(password_needs_rehash) { const php_password_algo *old_algo, *new_algo; zend_string *hash; - zval *znew_algo; + zend_string *new_algo_str; + zend_long new_algo_long; + zend_bool new_algo_is_null; zend_array *options = 0; ZEND_PARSE_PARAMETERS_START(2, 3) Z_PARAM_STR(hash) - Z_PARAM_ZVAL(znew_algo) + Z_PARAM_STR_OR_LONG_OR_NULL(new_algo_str, new_algo_long, new_algo_is_null) Z_PARAM_OPTIONAL Z_PARAM_ARRAY_HT(options) ZEND_PARSE_PARAMETERS_END(); - new_algo = php_password_algo_find_zval(znew_algo); + new_algo = php_password_algo_find_zval(new_algo_str, new_algo_long, new_algo_is_null); if (!new_algo) { /* Unknown new algorithm, never prompt to rehash. */ RETURN_FALSE; @@ -651,22 +647,22 @@ PHP_FUNCTION(password_verify) PHP_FUNCTION(password_hash) { zend_string *password, *digest = NULL; - zval *zalgo; + zend_string *algo_str; + zend_long algo_long; + zend_bool algo_is_null; const php_password_algo *algo; zend_array *options = NULL; ZEND_PARSE_PARAMETERS_START(2, 3) Z_PARAM_STR(password) - Z_PARAM_ZVAL(zalgo) + Z_PARAM_STR_OR_LONG_OR_NULL(algo_str, algo_long, algo_is_null) Z_PARAM_OPTIONAL Z_PARAM_ARRAY_HT(options) ZEND_PARSE_PARAMETERS_END(); - algo = php_password_algo_find_zval(zalgo); + algo = php_password_algo_find_zval(algo_str, algo_long, algo_is_null); if (!algo) { - zend_string *algostr = zval_get_string(zalgo); zend_argument_value_error(2, "must be a valid password hashing algorithm"); - zend_string_release(algostr); RETURN_THROWS(); } diff --git a/ext/standard/streamsfuncs.c b/ext/standard/streamsfuncs.c index 0bc475498f396..f56f52930cbfb 100644 --- a/ext/standard/streamsfuncs.c +++ b/ext/standard/streamsfuncs.c @@ -868,13 +868,13 @@ static void user_space_stream_notifier_dtor(php_stream_notifier *notifier) } } -static int parse_context_options(php_stream_context *context, zval *options) +static int parse_context_options(php_stream_context *context, HashTable *options) { zval *wval, *oval; zend_string *wkey, *okey; int ret = SUCCESS; - ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(options), wkey, wval) { + ZEND_HASH_FOREACH_STR_KEY_VAL(options, wkey, wval) { ZVAL_DEREF(wval); if (wkey && Z_TYPE_P(wval) == IS_ARRAY) { ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(wval), okey, oval) { @@ -891,12 +891,12 @@ static int parse_context_options(php_stream_context *context, zval *options) return ret; } -static int parse_context_params(php_stream_context *context, zval *params) +static int parse_context_params(php_stream_context *context, HashTable *params) { int ret = SUCCESS; zval *tmp; - if (NULL != (tmp = zend_hash_str_find(Z_ARRVAL_P(params), "notification", sizeof("notification")-1))) { + if (NULL != (tmp = zend_hash_str_find(params, "notification", sizeof("notification")-1))) { if (context->notifier) { php_stream_notification_free(context->notifier); @@ -908,9 +908,9 @@ static int parse_context_params(php_stream_context *context, zval *params) ZVAL_COPY(&context->notifier->ptr, tmp); context->notifier->dtor = user_space_stream_notifier_dtor; } - if (NULL != (tmp = zend_hash_str_find(Z_ARRVAL_P(params), "options", sizeof("options")-1))) { + if (NULL != (tmp = zend_hash_str_find(params, "options", sizeof("options")-1))) { if (Z_TYPE_P(tmp) == IS_ARRAY) { - return parse_context_options(context, tmp); + return parse_context_options(context, Z_ARRVAL_P(tmp)); } else { zend_type_error("Invalid stream/context parameter"); return FAILURE; @@ -975,41 +975,45 @@ PHP_FUNCTION(stream_context_set_option) { zval *zcontext = NULL; php_stream_context *context; + zend_string *wrappername; + HashTable *options; + char *optionname = NULL; + size_t optionname_len; + zval *zvalue = NULL; - if (ZEND_NUM_ARGS() == 2) { - zval *options; + ZEND_PARSE_PARAMETERS_START(2, 4) + Z_PARAM_RESOURCE(zcontext) + Z_PARAM_STR_OR_ARRAY_HT(wrappername, options) + Z_PARAM_OPTIONAL + Z_PARAM_STRING_OR_NULL(optionname, optionname_len) + Z_PARAM_ZVAL(zvalue) + ZEND_PARSE_PARAMETERS_END(); + + /* figure out where the context is coming from exactly */ + if (!(context = decode_context_param(zcontext))) { + zend_argument_type_error(1, "must be a valid stream/context"); + RETURN_THROWS(); + } - ZEND_PARSE_PARAMETERS_START(2, 2) - Z_PARAM_RESOURCE(zcontext) - Z_PARAM_ARRAY(options) - ZEND_PARSE_PARAMETERS_END(); + if (options) { + if (optionname) { + zend_argument_value_error(3, "must be null when argument #2 ($wrapper_or_options) is an array"); + RETURN_THROWS(); + } - /* figure out where the context is coming from exactly */ - if (!(context = decode_context_param(zcontext))) { - zend_argument_type_error(1, "must be a valid stream/context"); + if (zvalue) { + zend_argument_value_error(4, "cannot be provided when argument #2 ($wrapper_or_options) is an array"); RETURN_THROWS(); } RETURN_BOOL(parse_context_options(context, options) == SUCCESS); } else { - zval *zvalue; - char *wrappername, *optionname; - size_t wrapperlen, optionlen; - - ZEND_PARSE_PARAMETERS_START(4, 4) - Z_PARAM_RESOURCE(zcontext) - Z_PARAM_STRING(wrappername, wrapperlen) - Z_PARAM_STRING(optionname, optionlen) - Z_PARAM_ZVAL(zvalue) - ZEND_PARSE_PARAMETERS_END(); - - /* figure out where the context is coming from exactly */ - if (!(context = decode_context_param(zcontext))) { - zend_argument_type_error(1, "must be a valid stream/context"); + if (!optionname) { + zend_argument_value_error(3, "cannot be null when argument #2 ($wrapper_or_options) is a string"); RETURN_THROWS(); } - RETURN_BOOL(php_stream_context_set_option(context, wrappername, optionname, zvalue) == SUCCESS); + RETURN_BOOL(php_stream_context_set_option(context, ZSTR_VAL(wrappername), optionname, zvalue) == SUCCESS); } } /* }}} */ @@ -1017,12 +1021,13 @@ PHP_FUNCTION(stream_context_set_option) /* {{{ Set parameters for a file context */ PHP_FUNCTION(stream_context_set_params) { - zval *params, *zcontext; + HashTable *params; + zval *zcontext; php_stream_context *context; ZEND_PARSE_PARAMETERS_START(2, 2) Z_PARAM_RESOURCE(zcontext) - Z_PARAM_ARRAY(params) + Z_PARAM_ARRAY_HT(params) ZEND_PARSE_PARAMETERS_END(); context = decode_context_param(zcontext); @@ -1064,12 +1069,12 @@ PHP_FUNCTION(stream_context_get_params) /* {{{ Get a handle on the default file/stream context and optionally set parameters */ PHP_FUNCTION(stream_context_get_default) { - zval *params = NULL; + HashTable *params = NULL; php_stream_context *context; ZEND_PARSE_PARAMETERS_START(0, 1) Z_PARAM_OPTIONAL - Z_PARAM_ARRAY(params) + Z_PARAM_ARRAY_HT(params) ZEND_PARSE_PARAMETERS_END(); if (FG(default_context) == NULL) { @@ -1090,11 +1095,11 @@ PHP_FUNCTION(stream_context_get_default) /* {{{ Set default file/stream context, returns the context as a resource */ PHP_FUNCTION(stream_context_set_default) { - zval *options = NULL; + HashTable *options; php_stream_context *context; ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_ARRAY(options) + Z_PARAM_ARRAY_HT(options) ZEND_PARSE_PARAMETERS_END(); if (FG(default_context) == NULL) { @@ -1113,13 +1118,14 @@ PHP_FUNCTION(stream_context_set_default) /* {{{ Create a file context and optionally set parameters */ PHP_FUNCTION(stream_context_create) { - zval *options = NULL, *params = NULL; + HashTable *options = NULL; + HashTable *params = NULL; php_stream_context *context; ZEND_PARSE_PARAMETERS_START(0, 2) Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(options) - Z_PARAM_ARRAY_OR_NULL(params) + Z_PARAM_ARRAY_HT_OR_NULL(options) + Z_PARAM_ARRAY_HT_OR_NULL(params) ZEND_PARSE_PARAMETERS_END(); context = php_stream_context_alloc(); diff --git a/ext/standard/string.c b/ext/standard/string.c index bdaaeea47f666..5631ce4ac0e45 100644 --- a/ext/standard/string.c +++ b/ext/standard/string.c @@ -4083,8 +4083,10 @@ PHPAPI void php_stripslashes(zend_string *str) #define _isnewline(c) (((((unsigned char) c) == '\n' || ((unsigned char) c) == '\r')) ? 1 : 0) /* {{{ php_str_replace_in_subject */ -static zend_long php_str_replace_in_subject(zval *search, zval *replace, zend_string *subject_str, zval *result, int case_sensitivity) -{ +static zend_long php_str_replace_in_subject( + zend_string *search_str, HashTable *search_ht, zend_string *replace_str, HashTable *replace_ht, + zend_string *subject_str, zval *result, int case_sensitivity +) { zval *search_entry; zend_string *tmp_result; char *replace_value = NULL; @@ -4099,37 +4101,37 @@ static zend_long php_str_replace_in_subject(zval *search, zval *replace, zend_st } /* If search is an array */ - if (Z_TYPE_P(search) == IS_ARRAY) { + if (search_ht) { /* Duplicate subject string for repeated replacement */ zend_string_addref(subject_str); - if (Z_TYPE_P(replace) == IS_ARRAY) { + if (replace_ht) { replace_idx = 0; } else { /* Set replacement value to the passed one */ - replace_value = Z_STRVAL_P(replace); - replace_len = Z_STRLEN_P(replace); + replace_value = ZSTR_VAL(replace_str); + replace_len = ZSTR_LEN(replace_str); } /* For each entry in the search array, get the entry */ - ZEND_HASH_FOREACH_VAL_IND(Z_ARRVAL_P(search), search_entry) { + ZEND_HASH_FOREACH_VAL_IND(search_ht, search_entry) { /* Make sure we're dealing with strings. */ zend_string *tmp_search_str; zend_string *search_str = zval_get_tmp_string(search_entry, &tmp_search_str); zend_string *replace_entry_str, *tmp_replace_entry_str = NULL; /* If replace is an array. */ - if (Z_TYPE_P(replace) == IS_ARRAY) { + if (replace_ht) { /* Get current entry */ zval *replace_entry = NULL; - while (replace_idx < Z_ARRVAL_P(replace)->nNumUsed) { - replace_entry = &Z_ARRVAL_P(replace)->arData[replace_idx].val; + while (replace_idx < replace_ht->nNumUsed) { + replace_entry = &replace_ht->arData[replace_idx].val; if (Z_TYPE_P(replace_entry) != IS_UNDEF) { break; } replace_idx++; } - if (replace_idx < Z_ARRVAL_P(replace)->nNumUsed) { + if (replace_idx < replace_ht->nNumUsed) { /* Make sure we're dealing with strings. */ replace_entry_str = zval_get_tmp_string(replace_entry, &tmp_replace_entry_str); @@ -4205,25 +4207,24 @@ static zend_long php_str_replace_in_subject(zval *search, zval *replace, zend_st zend_string_release_ex(lc_subject_str, 0); } } else { - ZEND_ASSERT(Z_TYPE_P(search) == IS_STRING); - if (Z_STRLEN_P(search) == 1) { + ZEND_ASSERT(search_str); + if (ZSTR_LEN(search_str) == 1) { ZVAL_STR(result, php_char_to_str_ex(subject_str, - Z_STRVAL_P(search)[0], - Z_STRVAL_P(replace), - Z_STRLEN_P(replace), + ZSTR_VAL(search_str)[0], + ZSTR_VAL(replace_str), + ZSTR_LEN(replace_str), case_sensitivity, &replace_count)); - } else if (Z_STRLEN_P(search) > 1) { + } else if (ZSTR_LEN(search_str) > 1) { if (case_sensitivity) { ZVAL_STR(result, php_str_to_str_ex(subject_str, - Z_STRVAL_P(search), Z_STRLEN_P(search), - Z_STRVAL_P(replace), Z_STRLEN_P(replace), &replace_count)); + ZSTR_VAL(search_str), ZSTR_LEN(search_str), + ZSTR_VAL(replace_str), ZSTR_LEN(replace_str), &replace_count)); } else { lc_subject_str = php_string_tolower(subject_str); ZVAL_STR(result, php_str_to_str_i_ex(subject_str, ZSTR_VAL(lc_subject_str), - Z_STR_P(search), - Z_STRVAL_P(replace), Z_STRLEN_P(replace), &replace_count)); + search_str, ZSTR_VAL(replace_str), ZSTR_LEN(replace_str), &replace_count)); zend_string_release_ex(lc_subject_str, 0); } } else { @@ -4237,9 +4238,13 @@ static zend_long php_str_replace_in_subject(zval *search, zval *replace, zend_st /* {{{ php_str_replace_common */ static void php_str_replace_common(INTERNAL_FUNCTION_PARAMETERS, int case_sensitivity) { + zend_string *search_str; + HashTable *search_ht; + zend_string *replace_str; + HashTable *replace_ht; zend_string *subject_str; HashTable *subject_ht; - zval *search, *replace, *subject_entry, *zcount = NULL; + zval *subject_entry, *zcount = NULL; zval result; zend_string *string_key; zend_ulong num_key; @@ -4247,24 +4252,18 @@ static void php_str_replace_common(INTERNAL_FUNCTION_PARAMETERS, int case_sensit int argc = ZEND_NUM_ARGS(); ZEND_PARSE_PARAMETERS_START(3, 4) - Z_PARAM_ZVAL(search) - Z_PARAM_ZVAL(replace) + Z_PARAM_STR_OR_ARRAY_HT(search_str, search_ht) + Z_PARAM_STR_OR_ARRAY_HT(replace_str, replace_ht) Z_PARAM_STR_OR_ARRAY_HT(subject_str, subject_ht) Z_PARAM_OPTIONAL Z_PARAM_ZVAL(zcount) ZEND_PARSE_PARAMETERS_END(); /* Make sure we're dealing with strings and do the replacement. */ - if (Z_TYPE_P(search) != IS_ARRAY) { - convert_to_string_ex(search); - if (Z_TYPE_P(replace) != IS_STRING) { - convert_to_string_ex(replace); - } - } else if (Z_TYPE_P(replace) != IS_ARRAY) { - convert_to_string_ex(replace); - } - - if (EG(exception)) { + if (search_str && replace_ht) { + zend_argument_type_error(2, "must be of type %s when argument #1 ($search) is %s", + search_str ? "string" : "array", search_str ? "a string" : "an array" + ); RETURN_THROWS(); } @@ -4278,7 +4277,7 @@ static void php_str_replace_common(INTERNAL_FUNCTION_PARAMETERS, int case_sensit zend_string *tmp_subject_str; ZVAL_DEREF(subject_entry); subject_str = zval_get_tmp_string(subject_entry, &tmp_subject_str); - count += php_str_replace_in_subject(search, replace, subject_str, &result, case_sensitivity); + count += php_str_replace_in_subject(search_str, search_ht, replace_str, replace_ht, subject_str, &result, case_sensitivity); zend_tmp_string_release(tmp_subject_str); /* Add to return array */ @@ -4289,7 +4288,7 @@ static void php_str_replace_common(INTERNAL_FUNCTION_PARAMETERS, int case_sensit } } ZEND_HASH_FOREACH_END(); } else { /* if subject is not an array */ - count = php_str_replace_in_subject(search, replace, subject_str, return_value, case_sensitivity); + count = php_str_replace_in_subject(search_str, search_ht, replace_str, replace_ht, subject_str, return_value, case_sensitivity); } if (argc > 3) { ZEND_TRY_ASSIGN_REF_LONG(zcount, count); diff --git a/ext/standard/tests/password/password_hash_error.phpt b/ext/standard/tests/password/password_hash_error.phpt index 0dc056ea34b21..ddb5793c815c8 100644 --- a/ext/standard/tests/password/password_hash_error.phpt +++ b/ext/standard/tests/password/password_hash_error.phpt @@ -12,7 +12,7 @@ try { try { password_hash("foo", array()); -} catch (ValueError $exception) { +} catch (TypeError $exception) { echo $exception->getMessage() . "\n"; } @@ -35,11 +35,9 @@ try { } ?> ---EXPECTF-- +--EXPECT-- password_hash() expects at least 2 parameters, 1 given - -Warning: Array to string conversion in %s on line %d -password_hash(): Argument #2 ($algo) must be a valid password hashing algorithm +password_hash(): Argument #2 ($algo) must be of type string|int|null, array given password_hash(): Argument #3 ($options) must be of type array, stdClass given password_hash(): Argument #3 ($options) must be of type array, string given password_hash(): Argument #1 ($password) must be of type string, array given diff --git a/ext/standard/tests/password/password_needs_rehash_error.phpt b/ext/standard/tests/password/password_needs_rehash_error.phpt index 0b64b0c82ee38..aef86ee1247c8 100644 --- a/ext/standard/tests/password/password_needs_rehash_error.phpt +++ b/ext/standard/tests/password/password_needs_rehash_error.phpt @@ -2,7 +2,6 @@ Test error operation of password_needs_rehash() --FILE-- getMessage(), "\n"; } -var_dump(password_needs_rehash('', [])); +try { + var_dump(password_needs_rehash('', [])); +} catch (TypeError $e) { + echo $e->getMessage(), "\n"; +} try { var_dump(password_needs_rehash(array(), PASSWORD_BCRYPT)); @@ -28,7 +31,7 @@ echo "OK!"; ?> --EXPECT-- password_needs_rehash() expects at least 2 parameters, 1 given -bool(false) +password_needs_rehash(): Argument #2 ($algo) must be of type string|int|null, array given password_needs_rehash(): Argument #1 ($hash) must be of type string, array given password_needs_rehash(): Argument #3 ($options) must be of type array, string given OK! diff --git a/ext/standard/tests/strings/str_replace_basic.phpt b/ext/standard/tests/strings/str_replace_basic.phpt index bbabf198ee1d1..4dfbd098efc61 100644 --- a/ext/standard/tests/strings/str_replace_basic.phpt +++ b/ext/standard/tests/strings/str_replace_basic.phpt @@ -40,5 +40,5 @@ string(1) "q" int(1) string(0) "" int(0) -str_replace(): Argument #3 ($subject) must be of type string|array, resource given +str_replace(): Argument #1 ($search) must be of type array|string, resource given resource(%d) of type (stream) diff --git a/ext/standard/tests/strings/str_replace_variation3.phpt b/ext/standard/tests/strings/str_replace_variation3.phpt index 3c0562615a755..f08d8c7dc1bae 100644 --- a/ext/standard/tests/strings/str_replace_variation3.phpt +++ b/ext/standard/tests/strings/str_replace_variation3.phpt @@ -80,8 +80,11 @@ var_dump(str_replace( array("a", "a", "b"), ); var_dump($count); -var_dump(str_replace("a", array("q", "q", "c"), array("aaa"), $count)); -var_dump($count); +try { + str_replace("a", array("q", "q", "c"), array("aaa"), $count); +} catch (TypeError $exception) { + echo $exception->getMessage() . "\n"; +} var_dump(str_replace("a", 1, array("aaa", "bbb"), $count)); var_dump($count); @@ -175,13 +178,7 @@ array(2) { string(3) "ccc" } int(6) - -Warning: Array to string conversion in %s on line %d -array(1) { - [0]=> - string(15) "ArrayArrayArray" -} -int(3) +str_replace(): Argument #2 ($replace) must be of type string when argument #1 ($search) is a string array(2) { [0]=> string(3) "111" @@ -198,8 +195,8 @@ array(2) { int(1) -- Testing Resources -- -str_replace(): Argument #3 ($subject) must be of type string|array, resource given -str_replace(): Argument #3 ($subject) must be of type string|array, resource given +str_replace(): Argument #3 ($subject) must be of type array|string, resource given +str_replace(): Argument #3 ($subject) must be of type array|string, resource given -- Testing a longer and heredoc string -- string(623) "FOUNDghijklmnopqrstuvwxyz0123456789FOUNDghijklmnopqrstuvwxyz0123456789 From 36cdbd05490fb762212d8cc7a7556e16b1008e51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1t=C3=A9=20Kocsis?= Date: Thu, 3 Sep 2020 16:21:36 +0200 Subject: [PATCH 63/87] Promote warnings to exceptions in ext/ldap Closes GH-6065 --- ext/ldap/ldap.c | 144 +++++++++++----------- ext/ldap/tests/ldap_add_error.phpt | 12 +- ext/ldap/tests/ldap_search_error.phpt | 36 +++--- ext/ldap/tests/ldap_set_option_error.phpt | 23 ++-- 4 files changed, 109 insertions(+), 106 deletions(-) diff --git a/ext/ldap/ldap.c b/ext/ldap/ldap.c index 977e35e4c3b3e..b5031eaaab07d 100644 --- a/ext/ldap/ldap.c +++ b/ext/ldap/ldap.c @@ -290,7 +290,7 @@ static int _php_ldap_control_from_array(LDAP *ld, LDAPControl** ctrl, zval* arra size_t num_tmpstrings1 = 0, num_tmpstrings2 = 0; if ((val = zend_hash_str_find(Z_ARRVAL_P(array), "oid", sizeof("oid") - 1)) == NULL) { - php_error_docref(NULL, E_WARNING, "Control must have an \"oid\" key"); + zend_value_error("%s(): Control must have an \"oid\" key", get_active_function_name()); return -1; } @@ -345,7 +345,7 @@ static int _php_ldap_control_from_array(LDAP *ld, LDAPControl** ctrl, zval* arra zend_string* assert; if ((tmp = zend_hash_str_find(Z_ARRVAL_P(val), "filter", sizeof("filter") - 1)) == NULL) { rc = -1; - php_error_docref(NULL, E_WARNING, "Filter missing from assert control value array"); + zend_value_error("%s(): Control must have a \"filter\" key", get_active_function_name()); } else { assert = zval_get_string(tmp); if (EG(exception)) { @@ -368,7 +368,7 @@ static int _php_ldap_control_from_array(LDAP *ld, LDAPControl** ctrl, zval* arra zval* tmp; if ((tmp = zend_hash_str_find(Z_ARRVAL_P(val), "filter", sizeof("filter") - 1)) == NULL) { rc = -1; - php_error_docref(NULL, E_WARNING, "Filter missing from control value array"); + zend_value_error("%s(): Control must have a \"filter\" key", get_active_function_name()); } else { ber = ber_alloc_t(LBER_USE_DER); if (ber == NULL) { @@ -392,7 +392,7 @@ static int _php_ldap_control_from_array(LDAP *ld, LDAPControl** ctrl, zval* arra zval* tmp; if ((tmp = zend_hash_str_find(Z_ARRVAL_P(val), "attrs", sizeof("attrs") - 1)) == NULL) { rc = -1; - php_error_docref(NULL, E_WARNING, "Attributes list missing from control value array"); + zend_value_error("%s(): Control must have an \"attrs\" key", get_active_function_name()); } else { ber = ber_alloc_t(LBER_USE_DER); @@ -460,7 +460,7 @@ static int _php_ldap_control_from_array(LDAP *ld, LDAPControl** ctrl, zval* arra if ((tmp = zend_hash_str_find(Z_ARRVAL_P(sortkey), "attr", sizeof("attr") - 1)) == NULL) { rc = -1; - php_error_docref(NULL, E_WARNING, "Sort key list missing field"); + zend_value_error("%s(): Sort key list must have an \"attr\" key", get_active_function_name()); goto failure; } sort_keys[i] = emalloc(sizeof(LDAPSortKey)); @@ -507,7 +507,7 @@ static int _php_ldap_control_from_array(LDAP *ld, LDAPControl** ctrl, zval* arra vlvInfo.ldvlv_before_count = zval_get_long(tmp); } else { rc = -1; - php_error_docref(NULL, E_WARNING, "Before key missing from array value for VLV control"); + zend_value_error("%s(): Array value for VLV control must have a \"before\" key", get_active_function_name()); goto failure; } @@ -515,7 +515,7 @@ static int _php_ldap_control_from_array(LDAP *ld, LDAPControl** ctrl, zval* arra vlvInfo.ldvlv_after_count = zval_get_long(tmp); } else { rc = -1; - php_error_docref(NULL, E_WARNING, "After key missing from array value for VLV control"); + zend_value_error("%s(): Array value for VLV control must have an \"after\" key", get_active_function_name()); goto failure; } @@ -535,12 +535,12 @@ static int _php_ldap_control_from_array(LDAP *ld, LDAPControl** ctrl, zval* arra vlvInfo.ldvlv_count = zval_get_long(tmp); } else { rc = -1; - php_error_docref(NULL, E_WARNING, "Count key missing from array value for VLV control"); + zend_value_error("%s(): Array value for VLV control must have a \"count\" key", get_active_function_name()); goto failure; } } else { rc = -1; - php_error_docref(NULL, E_WARNING, "Missing either attrvalue or offset key from array value for VLV control"); + zend_value_error("%s(): Array value for VLV control must have either an \"attrvalue\" or an \"offset\" key", get_active_function_name()); goto failure; } @@ -564,7 +564,7 @@ static int _php_ldap_control_from_array(LDAP *ld, LDAPControl** ctrl, zval* arra php_error_docref(NULL, E_WARNING, "Failed to create VLV control value: %s (%d)", ldap_err2string(rc), rc); } } else { - php_error_docref(NULL, E_WARNING, "Control OID %s does not expect an array as value", ZSTR_VAL(control_oid)); + zend_type_error("%s(): Control OID %s cannot be of type array", get_active_function_name(), ZSTR_VAL(control_oid)); rc = -1; } } @@ -642,7 +642,7 @@ static void _php_ldap_controls_to_array(LDAP *ld, LDAPControl** ctrls, zval* arr ldap_controls_free(ctrls); } -static LDAPControl** _php_ldap_controls_from_array(LDAP *ld, zval* array) +static LDAPControl** _php_ldap_controls_from_array(LDAP *ld, zval* array, uint32_t arg_num) { int ncontrols; LDAPControl** ctrlp, **ctrls = NULL; @@ -655,7 +655,7 @@ static LDAPControl** _php_ldap_controls_from_array(LDAP *ld, zval* array) ctrlp = ctrls; ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(array), ctrlarray) { if (Z_TYPE_P(ctrlarray) != IS_ARRAY) { - php_error_docref(NULL, E_WARNING, "The array value must contain only arrays, where each array is a control"); + zend_argument_type_error(arg_num, "must contain only arrays, where each array is a control"); error = 1; break; } @@ -1029,8 +1029,8 @@ PHP_FUNCTION(ldap_connect) if (port <= 0 || port > 65535) { efree(ld); - php_error_docref(NULL, E_WARNING, "Invalid port number: " ZEND_LONG_FMT, port); - RETURN_FALSE; + zend_argument_value_error(2, "must be between 1 and 65535"); + RETURN_THROWS(); } url = emalloc(urllen); @@ -1129,14 +1129,14 @@ PHP_FUNCTION(ldap_bind) if (ldap_bind_dn != NULL && memchr(ldap_bind_dn, '\0', ldap_bind_dnlen) != NULL) { _set_lderrno(ld->link, LDAP_INVALID_CREDENTIALS); - php_error_docref(NULL, E_WARNING, "DN contains a null byte"); - RETURN_FALSE; + zend_argument_type_error(2, "must not contain null bytes"); + RETURN_THROWS(); } if (ldap_bind_pw != NULL && memchr(ldap_bind_pw, '\0', ldap_bind_pwlen) != NULL) { _set_lderrno(ld->link, LDAP_INVALID_CREDENTIALS); - php_error_docref(NULL, E_WARNING, "Password contains a null byte"); - RETURN_FALSE; + zend_argument_type_error(3, "must not contain null bytes"); + RETURN_THROWS(); } { @@ -1185,18 +1185,18 @@ PHP_FUNCTION(ldap_bind_ext) if (ldap_bind_dn != NULL && memchr(ldap_bind_dn, '\0', ldap_bind_dnlen) != NULL) { _set_lderrno(ld->link, LDAP_INVALID_CREDENTIALS); - php_error_docref(NULL, E_WARNING, "DN contains a null byte"); - RETURN_FALSE; + zend_argument_type_error(2, "must not contain null bytes"); + RETURN_THROWS(); } if (ldap_bind_pw != NULL && memchr(ldap_bind_pw, '\0', ldap_bind_pwlen) != NULL) { _set_lderrno(ld->link, LDAP_INVALID_CREDENTIALS); - php_error_docref(NULL, E_WARNING, "Password contains a null byte"); - RETURN_FALSE; + zend_argument_type_error(3, "must not contain null bytes"); + RETURN_THROWS(); } if (serverctrls) { - lserverctrls = _php_ldap_controls_from_array(ld->link, serverctrls); + lserverctrls = _php_ldap_controls_from_array(ld->link, serverctrls, 4); if (lserverctrls == NULL) { RETVAL_FALSE; goto cleanup; @@ -1491,7 +1491,7 @@ static void php_ldap_do_search(INTERNAL_FUNCTION_PARAMETERS, int scope) nlinks = zend_hash_num_elements(Z_ARRVAL_P(link)); if (nlinks == 0) { - php_error_docref(NULL, E_WARNING, "No links in link array"); + zend_argument_value_error(1, "cannot be empty"); ret = 0; goto cleanup; } @@ -1499,7 +1499,7 @@ static void php_ldap_do_search(INTERNAL_FUNCTION_PARAMETERS, int scope) if (base_dn_ht) { nbases = zend_hash_num_elements(base_dn_ht); if (nbases != nlinks) { - php_error_docref(NULL, E_WARNING, "Base must either be a string, or an array with the same number of elements as the links array"); + zend_argument_value_error(2, "must have the same number of elements as the links array"); ret = 0; goto cleanup; } @@ -1516,7 +1516,7 @@ static void php_ldap_do_search(INTERNAL_FUNCTION_PARAMETERS, int scope) if (filter_ht) { nfilters = zend_hash_num_elements(filter_ht); if (nfilters != nlinks) { - php_error_docref(NULL, E_WARNING, "Filter must either be a string, or an array with the same number of elements as the links array"); + zend_argument_value_error(3, "must have the same number of elements as the links array"); ret = 0; goto cleanup; } @@ -1560,7 +1560,7 @@ static void php_ldap_do_search(INTERNAL_FUNCTION_PARAMETERS, int scope) if (argcount > 8) { /* We have to parse controls again for each link as they use it */ _php_ldap_controls_free(&lserverctrls); - lserverctrls = _php_ldap_controls_from_array(ld->link, serverctrls); + lserverctrls = _php_ldap_controls_from_array(ld->link, serverctrls, 9); if (lserverctrls == NULL) { rcs[i] = -1; continue; @@ -1611,7 +1611,7 @@ static void php_ldap_do_search(INTERNAL_FUNCTION_PARAMETERS, int scope) ldap_filter = zend_string_copy(filter_str); if (argcount > 8) { - lserverctrls = _php_ldap_controls_from_array(ld->link, serverctrls); + lserverctrls = _php_ldap_controls_from_array(ld->link, serverctrls, 9); if (lserverctrls == NULL) { ret = 0; goto cleanup; @@ -2253,7 +2253,7 @@ static void php_ldap_do_modify(INTERNAL_FUNCTION_PARAMETERS, int oper, int ext) } else { for (j = 0; j < num_values; j++) { if ((ivalue = zend_hash_index_find(Z_ARRVAL_P(value), j)) == NULL) { - php_error_docref(NULL, E_WARNING, "Value array must have consecutive indices 0, 1, ..."); + zend_argument_value_error(3, "must contain arrays with consecutive integer indices starting from 0"); num_berval[i] = j; num_attribs = i + 1; RETVAL_FALSE; @@ -2275,7 +2275,7 @@ static void php_ldap_do_modify(INTERNAL_FUNCTION_PARAMETERS, int oper, int ext) ldap_mods[num_attribs] = NULL; if (serverctrls) { - lserverctrls = _php_ldap_controls_from_array(ld->link, serverctrls); + lserverctrls = _php_ldap_controls_from_array(ld->link, serverctrls, 4); if (lserverctrls == NULL) { RETVAL_FALSE; goto cleanup; @@ -2425,7 +2425,7 @@ static void php_ldap_do_delete(INTERNAL_FUNCTION_PARAMETERS, int ext) } if (serverctrls) { - lserverctrls = _php_ldap_controls_from_array(ld->link, serverctrls); + lserverctrls = _php_ldap_controls_from_array(ld->link, serverctrls, 3); if (lserverctrls == NULL) { RETVAL_FALSE; goto cleanup; @@ -2577,15 +2577,15 @@ PHP_FUNCTION(ldap_modify_batch) /* make sure the DN contains no NUL bytes */ if (_ldap_strlen_max(dn, dn_len) != dn_len) { - php_error_docref(NULL, E_WARNING, "DN must not contain NUL bytes"); - RETURN_FALSE; + zend_argument_type_error(2, "must not contain null bytes"); + RETURN_THROWS(); } /* make sure the top level is a normal array */ zend_hash_internal_pointer_reset(Z_ARRVAL_P(mods)); if (zend_hash_get_current_key_type(Z_ARRVAL_P(mods)) != HASH_KEY_IS_LONG) { - php_error_docref(NULL, E_WARNING, "Modifications array must not be string-indexed"); - RETURN_FALSE; + zend_argument_type_error(3, "must be integer-indexed"); + RETURN_THROWS(); } num_mods = zend_hash_num_elements(Z_ARRVAL_P(mods)); @@ -2593,15 +2593,15 @@ PHP_FUNCTION(ldap_modify_batch) for (i = 0; i < num_mods; i++) { /* is the numbering consecutive? */ if ((fetched = zend_hash_index_find(Z_ARRVAL_P(mods), i)) == NULL) { - php_error_docref(NULL, E_WARNING, "Modifications array must have consecutive indices 0, 1, ..."); - RETURN_FALSE; + zend_argument_value_error(3, "must have consecutive integer indices starting from 0"); + RETURN_THROWS(); } mod = fetched; /* is it an array? */ if (Z_TYPE_P(mod) != IS_ARRAY) { - php_error_docref(NULL, E_WARNING, "Each entry of modifications array must be an array itself"); - RETURN_FALSE; + zend_argument_value_error(3, "must only contain arrays"); + RETURN_THROWS(); } SEPARATE_ARRAY(mod); @@ -2612,8 +2612,8 @@ PHP_FUNCTION(ldap_modify_batch) for (j = 0; j < num_modprops; j++) { /* are the keys strings? */ if (zend_hash_get_current_key(Z_ARRVAL_P(mod), &modkey, &tmpUlong) != HASH_KEY_IS_STRING) { - php_error_docref(NULL, E_WARNING, "Each entry of modifications array must be string-indexed"); - RETURN_FALSE; + zend_argument_type_error(3, "must only contain string-indexed arrays"); + RETURN_THROWS(); } /* is this a valid entry? */ @@ -2622,8 +2622,8 @@ PHP_FUNCTION(ldap_modify_batch) !_ldap_str_equal_to_const(ZSTR_VAL(modkey), ZSTR_LEN(modkey), LDAP_MODIFY_BATCH_MODTYPE) && !_ldap_str_equal_to_const(ZSTR_VAL(modkey), ZSTR_LEN(modkey), LDAP_MODIFY_BATCH_VALUES) ) { - php_error_docref(NULL, E_WARNING, "The only allowed keys in entries of the modifications array are '" LDAP_MODIFY_BATCH_ATTRIB "', '" LDAP_MODIFY_BATCH_MODTYPE "' and '" LDAP_MODIFY_BATCH_VALUES "'"); - RETURN_FALSE; + zend_argument_value_error(3, "must contain arrays only containing the \"" LDAP_MODIFY_BATCH_ATTRIB "\", \"" LDAP_MODIFY_BATCH_MODTYPE "\" and \"" LDAP_MODIFY_BATCH_VALUES "\" keys"); + RETURN_THROWS(); } fetched = zend_hash_get_current_data(Z_ARRVAL_P(mod)); @@ -2632,19 +2632,19 @@ PHP_FUNCTION(ldap_modify_batch) /* does the value type match the key? */ if (_ldap_str_equal_to_const(ZSTR_VAL(modkey), ZSTR_LEN(modkey), LDAP_MODIFY_BATCH_ATTRIB)) { if (Z_TYPE_P(modinfo) != IS_STRING) { - php_error_docref(NULL, E_WARNING, "A '" LDAP_MODIFY_BATCH_ATTRIB "' value must be a string"); - RETURN_FALSE; + zend_type_error("%s(): Option \"" LDAP_MODIFY_BATCH_ATTRIB "\" must be of type string, %s given", get_active_function_name(), zend_zval_type_name(modinfo)); + RETURN_THROWS(); } if (Z_STRLEN_P(modinfo) != _ldap_strlen_max(Z_STRVAL_P(modinfo), Z_STRLEN_P(modinfo))) { - php_error_docref(NULL, E_WARNING, "A '" LDAP_MODIFY_BATCH_ATTRIB "' value must not contain NUL bytes"); - RETURN_FALSE; + zend_type_error("%s(): Option \"" LDAP_MODIFY_BATCH_ATTRIB "\" cannot contain null-bytes", get_active_function_name()); + RETURN_THROWS(); } } else if (_ldap_str_equal_to_const(ZSTR_VAL(modkey), ZSTR_LEN(modkey), LDAP_MODIFY_BATCH_MODTYPE)) { if (Z_TYPE_P(modinfo) != IS_LONG) { - php_error_docref(NULL, E_WARNING, "A '" LDAP_MODIFY_BATCH_MODTYPE "' value must be a long"); - RETURN_FALSE; + zend_type_error("%s(): Option \"" LDAP_MODIFY_BATCH_MODTYPE "\" must be of type int, %s given", get_active_function_name(), zend_zval_type_name(modinfo)); + RETURN_THROWS(); } /* is the value in range? */ @@ -2655,28 +2655,28 @@ PHP_FUNCTION(ldap_modify_batch) modtype != LDAP_MODIFY_BATCH_REPLACE && modtype != LDAP_MODIFY_BATCH_REMOVE_ALL ) { - php_error_docref(NULL, E_WARNING, "The '" LDAP_MODIFY_BATCH_MODTYPE "' value must match one of the LDAP_MODIFY_BATCH_* constants"); - RETURN_FALSE; + zend_value_error("%s(): Option \"" LDAP_MODIFY_BATCH_MODTYPE "\" must be one of LDAP_MODIFY_BATCH_ADD, LDAP_MODIFY_BATCH_REMOVE, LDAP_MODIFY_BATCH_REPLACE, or LDAP_MODIFY_BATCH_REMOVE_ALL", get_active_function_name()); + RETURN_THROWS(); } /* if it's REMOVE_ALL, there must not be a values array; otherwise, there must */ if (modtype == LDAP_MODIFY_BATCH_REMOVE_ALL) { if (zend_hash_str_exists(Z_ARRVAL_P(mod), LDAP_MODIFY_BATCH_VALUES, strlen(LDAP_MODIFY_BATCH_VALUES))) { - php_error_docref(NULL, E_WARNING, "If '" LDAP_MODIFY_BATCH_MODTYPE "' is LDAP_MODIFY_BATCH_REMOVE_ALL, a '" LDAP_MODIFY_BATCH_VALUES "' array must not be provided"); - RETURN_FALSE; + zend_value_error("%s(): If option \"" LDAP_MODIFY_BATCH_MODTYPE "\" is LDAP_MODIFY_BATCH_REMOVE_ALL, option \"" LDAP_MODIFY_BATCH_VALUES "\" cannot be provided", get_active_function_name()); + RETURN_THROWS(); } } else { if (!zend_hash_str_exists(Z_ARRVAL_P(mod), LDAP_MODIFY_BATCH_VALUES, strlen(LDAP_MODIFY_BATCH_VALUES))) { - php_error_docref(NULL, E_WARNING, "If '" LDAP_MODIFY_BATCH_MODTYPE "' is not LDAP_MODIFY_BATCH_REMOVE_ALL, a '" LDAP_MODIFY_BATCH_VALUES "' array must be provided"); - RETURN_FALSE; + zend_value_error("%s(): If option \"" LDAP_MODIFY_BATCH_MODTYPE "\" is not LDAP_MODIFY_BATCH_REMOVE_ALL, option \"" LDAP_MODIFY_BATCH_VALUES "\" must be provided", get_active_function_name()); + RETURN_THROWS(); } } } else if (_ldap_str_equal_to_const(ZSTR_VAL(modkey), ZSTR_LEN(modkey), LDAP_MODIFY_BATCH_VALUES)) { if (Z_TYPE_P(modinfo) != IS_ARRAY) { - php_error_docref(NULL, E_WARNING, "A '" LDAP_MODIFY_BATCH_VALUES "' value must be an array"); - RETURN_FALSE; + zend_type_error("%s(): Option \"" LDAP_MODIFY_BATCH_VALUES "\" must be of type array, %s given", get_active_function_name(), zend_zval_type_name(modinfo)); + RETURN_THROWS(); } SEPARATE_ARRAY(modinfo); @@ -2684,21 +2684,21 @@ PHP_FUNCTION(ldap_modify_batch) zend_hash_internal_pointer_reset(Z_ARRVAL_P(modinfo)); num_modvals = zend_hash_num_elements(Z_ARRVAL_P(modinfo)); if (num_modvals == 0) { - php_error_docref(NULL, E_WARNING, "A '" LDAP_MODIFY_BATCH_VALUES "' array must have at least one element"); - RETURN_FALSE; + zend_value_error("%s(): Option \"" LDAP_MODIFY_BATCH_VALUES "\" cannot be empty", get_active_function_name()); + RETURN_THROWS(); } /* are its keys integers? */ if (zend_hash_get_current_key_type(Z_ARRVAL_P(modinfo)) != HASH_KEY_IS_LONG) { - php_error_docref(NULL, E_WARNING, "A '" LDAP_MODIFY_BATCH_VALUES "' array must not be string-indexed"); - RETURN_FALSE; + zend_value_error("%s(): Option \"" LDAP_MODIFY_BATCH_VALUES "\" must be integer-indexed", get_active_function_name()); + RETURN_THROWS(); } /* are the keys consecutive? */ for (k = 0; k < num_modvals; k++) { if ((fetched = zend_hash_index_find(Z_ARRVAL_P(modinfo), k)) == NULL) { - php_error_docref(NULL, E_WARNING, "A '" LDAP_MODIFY_BATCH_VALUES "' array must have consecutive indices 0, 1, ..."); - RETURN_FALSE; + zend_value_error("%s(): Option \"" LDAP_MODIFY_BATCH_VALUES "\" must have consecutive integer indices starting from 0", get_active_function_name()); + RETURN_THROWS(); } } } @@ -2788,7 +2788,7 @@ PHP_FUNCTION(ldap_modify_batch) ldap_mods[num_mods] = NULL; if (serverctrls) { - lserverctrls = _php_ldap_controls_from_array(ld->link, serverctrls); + lserverctrls = _php_ldap_controls_from_array(ld->link, serverctrls, 4); if (lserverctrls == NULL) { RETVAL_FALSE; goto cleanup; @@ -2908,7 +2908,7 @@ PHP_FUNCTION(ldap_compare) } if (serverctrls) { - lserverctrls = _php_ldap_controls_from_array(ld->link, serverctrls); + lserverctrls = _php_ldap_controls_from_array(ld->link, serverctrls, 5); if (lserverctrls == NULL) { RETVAL_FALSE; goto cleanup; @@ -3161,8 +3161,8 @@ PHP_FUNCTION(ldap_set_option) convert_to_long_ex(newval); if (ZEND_LONG_EXCEEDS_INT(Z_LVAL_P(newval))) { - php_error_docref(NULL, E_WARNING, "Option value is too big"); - RETURN_FALSE; + zend_argument_value_error(3, "is too large"); + RETURN_THROWS(); } val = (int)Z_LVAL_P(newval); if (ldap_set_option(ldap, option, &val)) { @@ -3269,11 +3269,11 @@ PHP_FUNCTION(ldap_set_option) int rc; if (Z_TYPE_P(newval) != IS_ARRAY) { - php_error_docref(NULL, E_WARNING, "Expected array value for this option"); - RETURN_FALSE; + zend_argument_type_error(3, "must be of type array for the LDAP_OPT_CLIENT_CONTROLS option, %s given", zend_zval_type_name(newval)); + RETURN_THROWS(); } - ctrls = _php_ldap_controls_from_array(ldap, newval); + ctrls = _php_ldap_controls_from_array(ldap, newval, 3); if (ctrls == NULL) { RETURN_FALSE; @@ -3581,7 +3581,7 @@ static void php_ldap_do_rename(INTERNAL_FUNCTION_PARAMETERS, int ext) #if (LDAP_API_VERSION > 2000) || defined(HAVE_ORALDAP) if (serverctrls) { - lserverctrls = _php_ldap_controls_from_array(ld->link, serverctrls); + lserverctrls = _php_ldap_controls_from_array(ld->link, serverctrls, 6); if (lserverctrls == NULL) { RETVAL_FALSE; goto cleanup; @@ -4101,7 +4101,7 @@ PHP_FUNCTION(ldap_exop) } if (serverctrls) { - lserverctrls = _php_ldap_controls_from_array(ld->link, serverctrls); + lserverctrls = _php_ldap_controls_from_array(ld->link, serverctrls, 4); if (lserverctrls == NULL) { RETVAL_FALSE; goto cleanup; diff --git a/ext/ldap/tests/ldap_add_error.phpt b/ext/ldap/tests/ldap_add_error.phpt index 61b4d2808df9d..7a3326099972c 100644 --- a/ext/ldap/tests/ldap_add_error.phpt +++ b/ext/ldap/tests/ldap_add_error.phpt @@ -38,7 +38,7 @@ for ($i = 0; $i < 2; $i++) var_dump(ldap_error($link), ldap_errno($link)); // Wrong array indexes -var_dump( +try { ldap_add($link, "dc=my-domain2,dc=com", array( "objectClass" => array( 0 => "top", @@ -46,13 +46,15 @@ var_dump( 5 => "organization"), "dc" => "my-domain", "o" => "my-domain", - )) + )); /* Is this correct behaviour to still have "Already exists" as error/errno? , ldap_error($link), ldap_errno($link) */ -); +} catch (ValueError $exception) { + echo $exception->getMessage() . "\n"; +} // Invalid attribute var_dump( @@ -101,9 +103,7 @@ Warning: ldap_add(): Add: Already exists in %s on line %d bool(false) string(14) "Already exists" int(68) - -Warning: ldap_add(): Value array must have consecutive indices 0, 1, ... in %s on line %d -bool(false) +ldap_add(): Argument #3 ($entry) must contain arrays with consecutive integer indices starting from 0 Warning: ldap_add(): Add: Undefined attribute type in %s on line %d bool(false) diff --git a/ext/ldap/tests/ldap_search_error.phpt b/ext/ldap/tests/ldap_search_error.phpt index 0a260b2884300..cc4653f2b7bf2 100644 --- a/ext/ldap/tests/ldap_search_error.phpt +++ b/ext/ldap/tests/ldap_search_error.phpt @@ -21,14 +21,24 @@ var_dump($result); $result = ldap_search($link, $dn, $filter, array(1 => 'top')); var_dump($result); -$result = ldap_search(array(), $dn, $filter, array('top')); -var_dump($result); - -$result = ldap_search(array($link, $link), array($dn), $filter, array('top')); -var_dump($result); +try { + ldap_search(array(), $dn, $filter, array('top')); +} catch (ValueError $exception) { + echo $exception->getMessage() . "\n"; +} + +try { + ldap_search(array($link, $link), array($dn), $filter, array('top')); +} catch (ValueError $exception) { + echo $exception->getMessage() . "\n"; +} + +try { + ldap_search(array($link, $link), $dn, array($filter), array('top')); +} catch (ValueError $exception) { + echo $exception->getMessage() . "\n"; +} -$result = ldap_search(array($link, $link), $dn, array($filter), array('top')); -var_dump($result); ?> --EXPECTF-- Warning: ldap_search(): Search: No such object in %s on line %d @@ -36,12 +46,6 @@ bool(false) Warning: ldap_search(): Array initialization wrong in %s on line %d bool(false) - -Warning: ldap_search(): No links in link array in %s on line %d -bool(false) - -Warning: ldap_search(): Base must either be a string, or an array with the same number of elements as the links array in %s on line %d -bool(false) - -Warning: ldap_search(): Filter must either be a string, or an array with the same number of elements as the links array in %s on line %d -bool(false) +ldap_search(): Argument #1 ($link_identifier) cannot be empty +ldap_search(): Argument #2 ($base_dn) must have the same number of elements as the links array +ldap_search(): Argument #3 ($filter) must have the same number of elements as the links array diff --git a/ext/ldap/tests/ldap_set_option_error.phpt b/ext/ldap/tests/ldap_set_option_error.phpt index 5ef4c0b86b1d4..f97193e22b581 100644 --- a/ext/ldap/tests/ldap_set_option_error.phpt +++ b/ext/ldap/tests/ldap_set_option_error.phpt @@ -25,20 +25,19 @@ $controls = array( var_dump(ldap_set_option($link, LDAP_OPT_PROTOCOL_VERSION, 10)); -foreach ($controls as $control) - var_dump(ldap_set_option($link, LDAP_OPT_SERVER_CONTROLS, $control)); +foreach ($controls as $control) { + try { + var_dump(ldap_set_option($link, LDAP_OPT_SERVER_CONTROLS, $control)); + } catch (Error $exception) { + echo get_class($exception) . ": " . $exception->getMessage() . "\n"; + } +} var_dump(ldap_set_option($link, 999999, 999999)); ?> ---EXPECTF-- -bool(false) - -Warning: ldap_set_option(): Control must have an "oid" key in %s on line %d -bool(false) - -Warning: ldap_set_option(): The array value must contain only arrays, where each array is a control in %s on line %d -bool(false) - -Warning: ldap_set_option(): Expected array value for this option in %s on line %d +--EXPECT-- bool(false) +ValueError: ldap_set_option(): Control must have an "oid" key +TypeError: ldap_set_option(): Argument #3 ($newval) must contain only arrays, where each array is a control +TypeError: ldap_set_option(): Argument #3 ($newval) must be of type array for the LDAP_OPT_CLIENT_CONTROLS option, string given bool(false) From 2ee2335249d4bbeed27d60a59245a966d0580074 Mon Sep 17 00:00:00 2001 From: Derick Rethans Date: Fri, 4 Sep 2020 15:55:08 +0100 Subject: [PATCH 64/87] Fixed bug #80057 (DateTimeImmutable::createFromFormat() does not populate time) --- NEWS | 4 ++++ ext/date/php_date.c | 23 +++++++++++++++-------- ext/date/php_date.h | 5 ++++- ext/date/tests/bug80057.phpt | 13 +++++++++++++ 4 files changed, 36 insertions(+), 9 deletions(-) create mode 100644 ext/date/tests/bug80057.phpt diff --git a/NEWS b/NEWS index 34a8805503f2b..ebf47b05a337f 100644 --- a/NEWS +++ b/NEWS @@ -8,6 +8,10 @@ PHP NEWS . Fixed bug #80045 (memleak after two set_exception_handler calls with __call). (Nikita) +- Date: + . Fixed bug #80057 (DateTimeImmutable::createFromFormat() does not populate + time). (Derick) + 03 Sep 2020, PHP 8.0.0beta3 - Calendar: diff --git a/ext/date/php_date.c b/ext/date/php_date.c index c6ef4700ec654..d6f66b700e891 100644 --- a/ext/date/php_date.c +++ b/ext/date/php_date.c @@ -707,7 +707,7 @@ static zend_string *date_format(const char *format, size_t format_len, timelib_t /* timezone */ case 'I': length = slprintf(buffer, sizeof(buffer), "%d", localtime ? offset->is_dst : 0); break; - case 'p': + case 'p': if (!localtime || strcmp(offset->abbr, "UTC") == 0 || strcmp(offset->abbr, "Z") == 0) { length = slprintf(buffer, sizeof(buffer), "%s", "Z"); break; @@ -2179,7 +2179,7 @@ static void php_date_get_current_time_with_fraction(time_t *sec, suseconds_t *us #endif } -PHPAPI int php_date_initialize(php_date_obj *dateobj, const char *time_str, size_t time_str_len, const char *format, zval *timezone_object, int ctor) /* {{{ */ +PHPAPI int php_date_initialize(php_date_obj *dateobj, const char *time_str, size_t time_str_len, const char *format, zval *timezone_object, int flags) /* {{{ */ { timelib_time *now; timelib_tzinfo *tzi = NULL; @@ -2189,6 +2189,7 @@ PHPAPI int php_date_initialize(php_date_obj *dateobj, const char *time_str, size timelib_sll new_offset = 0; time_t sec; suseconds_t usec; + int options = 0; if (dateobj->time) { timelib_time_dtor(dateobj->time); @@ -2210,7 +2211,7 @@ PHPAPI int php_date_initialize(php_date_obj *dateobj, const char *time_str, size update_errors_warnings(err); - if (ctor && err && err->error_count) { + if ((flags & PHP_DATE_INIT_CTOR) && err && err->error_count) { /* spit out the first library error message, at least */ php_error_docref(NULL, E_WARNING, "Failed to parse time string (%s) at position %d (%c): %s", time_str, err->error_messages[0].position, err->error_messages[0].character, err->error_messages[0].message); @@ -2263,7 +2264,13 @@ PHPAPI int php_date_initialize(php_date_obj *dateobj, const char *time_str, size php_date_get_current_time_with_fraction(&sec, &usec); timelib_unixtime2local(now, (timelib_sll) sec); php_date_set_time_fraction(now, usec); - timelib_fill_holes(dateobj->time, now, TIMELIB_NO_CLONE); + + options = TIMELIB_NO_CLONE; + if (flags & PHP_DATE_INIT_FORMAT) { + options |= TIMELIB_OVERRIDE_TIME; + } + timelib_fill_holes(dateobj->time, now, options); + timelib_update_ts(dateobj->time, tzi); timelib_update_from_sse(dateobj->time); @@ -2331,7 +2338,7 @@ PHP_FUNCTION(date_create_from_format) ZEND_PARSE_PARAMETERS_END(); php_date_instantiate(execute_data->This.value.ce ? execute_data->This.value.ce : date_ce_date, return_value); - if (!php_date_initialize(Z_PHPDATE_P(return_value), time_str, time_str_len, format_str, timezone_object, 0)) { + if (!php_date_initialize(Z_PHPDATE_P(return_value), time_str, time_str_len, format_str, timezone_object, PHP_DATE_INIT_FORMAT)) { zval_ptr_dtor(return_value); RETURN_FALSE; } @@ -2353,7 +2360,7 @@ PHP_FUNCTION(date_create_immutable_from_format) ZEND_PARSE_PARAMETERS_END(); php_date_instantiate(execute_data->This.value.ce ? execute_data->This.value.ce : date_ce_immutable, return_value); - if (!php_date_initialize(Z_PHPDATE_P(return_value), time_str, time_str_len, format_str, timezone_object, 0)) { + if (!php_date_initialize(Z_PHPDATE_P(return_value), time_str, time_str_len, format_str, timezone_object, PHP_DATE_INIT_FORMAT)) { zval_ptr_dtor(return_value); RETURN_FALSE; } @@ -2375,7 +2382,7 @@ PHP_METHOD(DateTime, __construct) ZEND_PARSE_PARAMETERS_END(); zend_replace_error_handling(EH_THROW, NULL, &error_handling); - php_date_initialize(Z_PHPDATE_P(ZEND_THIS), time_str, time_str_len, NULL, timezone_object, 1); + php_date_initialize(Z_PHPDATE_P(ZEND_THIS), time_str, time_str_len, NULL, timezone_object, PHP_DATE_INIT_CTOR); zend_restore_error_handling(&error_handling); } /* }}} */ @@ -2395,7 +2402,7 @@ PHP_METHOD(DateTimeImmutable, __construct) ZEND_PARSE_PARAMETERS_END(); zend_replace_error_handling(EH_THROW, NULL, &error_handling); - php_date_initialize(Z_PHPDATE_P(ZEND_THIS), time_str, time_str_len, NULL, timezone_object, 1); + php_date_initialize(Z_PHPDATE_P(ZEND_THIS), time_str, time_str_len, NULL, timezone_object, PHP_DATE_INIT_CTOR); zend_restore_error_handling(&error_handling); } /* }}} */ diff --git a/ext/date/php_date.h b/ext/date/php_date.h index b89438e0c56fb..491f0b6c3e699 100644 --- a/ext/date/php_date.h +++ b/ext/date/php_date.h @@ -130,8 +130,11 @@ PHPAPI zend_class_entry *php_date_get_interval_ce(void); PHPAPI zend_class_entry *php_date_get_period_ce(void); /* Functions for creating DateTime objects, and initializing them from a string */ +#define PHP_DATE_INIT_CTOR 0x01 +#define PHP_DATE_INIT_FORMAT 0x02 + PHPAPI zval *php_date_instantiate(zend_class_entry *pce, zval *object); -PHPAPI int php_date_initialize(php_date_obj *dateobj, const char *time_str, size_t time_str_len, const char *format, zval *timezone_object, int ctor); +PHPAPI int php_date_initialize(php_date_obj *dateobj, const char *time_str, size_t time_str_len, const char *format, zval *timezone_object, int flags); #endif /* PHP_DATE_H */ diff --git a/ext/date/tests/bug80057.phpt b/ext/date/tests/bug80057.phpt new file mode 100644 index 0000000000000..30a3f8ccd7b97 --- /dev/null +++ b/ext/date/tests/bug80057.phpt @@ -0,0 +1,13 @@ +--TEST-- +Bug #80057 (DateTimeImmutable::createFromFormat() does not populate time) +--FILE-- +format("H:i"); +$parsedStr = $parsed->format("H:i"); + +var_dump($nowStr == $parsedStr); +?> +--EXPECT-- +bool(true) From edc8dec6758cc4254d672ec433dae98c49afce72 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Fri, 4 Sep 2020 15:22:11 +0200 Subject: [PATCH 65/87] Reenable s390x on travis Only enable it for cron builds. We don't need to run exotic architectures on every commit and PR. Closes GH-6076. --- .travis.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 5e0e7ccbac99a..dc2affa8996e3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -74,8 +74,9 @@ jobs: arch: amd64 - env: ENABLE_ZTS=1 ENABLE_DEBUG=1 SKIP_IO_CAPTURE_TESTS=1 ARM64=1 arch: arm64 - #- env: ENABLE_ZTS=1 ENABLE_DEBUG=1 SKIP_IO_CAPTURE_TESTS=1 S390X=1 - # arch: s390x + - env: ENABLE_ZTS=1 ENABLE_DEBUG=1 SKIP_IO_CAPTURE_TESTS=1 S390X=1 + arch: s390x + if: type = cron before_script: - ccache --version From d57f9e5ea41aac7e40d37b6335cd2e03bf3b73fa Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Fri, 4 Sep 2020 17:15:35 +0200 Subject: [PATCH 66/87] Handle null encoding in mb_http_input() --- ext/mbstring/mbstring.c | 28 ++++++++++++++-------- ext/mbstring/tests/mb_http_input_pass.phpt | 11 +++++++++ 2 files changed, 29 insertions(+), 10 deletions(-) diff --git a/ext/mbstring/mbstring.c b/ext/mbstring/mbstring.c index 24c55509759dc..050afa26e677f 100644 --- a/ext/mbstring/mbstring.c +++ b/ext/mbstring/mbstring.c @@ -1319,6 +1319,7 @@ PHP_FUNCTION(mb_http_input) char *type = NULL; size_t type_len = 0, n; const mbfl_encoding **entry; + const mbfl_encoding *encoding; ZEND_PARSE_PARAMETERS_START(0, 1) Z_PARAM_OPTIONAL @@ -1326,34 +1327,34 @@ PHP_FUNCTION(mb_http_input) ZEND_PARSE_PARAMETERS_END(); if (type == NULL) { - RETVAL_STRING(MBSTRG(http_input_identify)->name); + encoding = MBSTRG(http_input_identify); } else { switch (*type) { case 'G': case 'g': - RETVAL_STRING(MBSTRG(http_input_identify_get)->name); + encoding = MBSTRG(http_input_identify_get); break; case 'P': case 'p': - RETVAL_STRING(MBSTRG(http_input_identify_post)->name); + encoding = MBSTRG(http_input_identify_post); break; case 'C': case 'c': - RETVAL_STRING(MBSTRG(http_input_identify_cookie)->name); + encoding = MBSTRG(http_input_identify_cookie); break; case 'S': case 's': - RETVAL_STRING(MBSTRG(http_input_identify_string)->name); + encoding = MBSTRG(http_input_identify_string); break; case 'I': case 'i': entry = MBSTRG(http_input_list); n = MBSTRG(http_input_list_size); array_init(return_value); - for (int i = 0; i < n; i++, entry++) { + for (size_t i = 0; i < n; i++, entry++) { add_next_index_string(return_value, (*entry)->name); } - break; + return; case 'L': case 'l': entry = MBSTRG(http_input_list); @@ -1362,10 +1363,11 @@ PHP_FUNCTION(mb_http_input) // TODO should return empty string? RETURN_FALSE; } + // TODO Use smart_str instead. mbfl_string result; mbfl_memory_device device; mbfl_memory_device_init(&device, n * 12, 0); - for (int i = 0; i < n; i++, entry++) { + for (size_t i = 0; i < n; i++, entry++) { mbfl_memory_device_strcat(&device, (*entry)->name); mbfl_memory_device_output(',', &device); } @@ -1373,13 +1375,19 @@ PHP_FUNCTION(mb_http_input) mbfl_memory_device_result(&device, &result); RETVAL_STRINGL((const char*)result.val, result.len); mbfl_string_clear(&result); - break; + return; default: // TODO ValueError - RETVAL_STRING(MBSTRG(http_input_identify)->name); + encoding = MBSTRG(http_input_identify); break; } } + + if (encoding) { + RETURN_STRING(encoding->name); + } else { + RETURN_FALSE; + } } /* }}} */ diff --git a/ext/mbstring/tests/mb_http_input_pass.phpt b/ext/mbstring/tests/mb_http_input_pass.phpt index ffca4498d7c4c..c04f5ff118a70 100644 --- a/ext/mbstring/tests/mb_http_input_pass.phpt +++ b/ext/mbstring/tests/mb_http_input_pass.phpt @@ -20,6 +20,10 @@ echo $_GET['b']."\n"; // Get encoding var_dump(mb_http_input('P')); var_dump(mb_http_input('G')); +var_dump(mb_http_input('C')); +var_dump(mb_http_input('S')); +var_dump(mb_http_input('I')); +var_dump(mb_http_input('L')); ?> --EXPECT-- @@ -27,3 +31,10 @@ var_dump(mb_http_input('G')); ܸ0123456789ܸ쥫ʤҤ餬 string(4) "pass" string(4) "pass" +bool(false) +bool(false) +array(1) { + [0]=> + string(4) "pass" +} +string(4) "pass" From 4ebc04ca9d0a8871dc511f48977c36a4c9782ee0 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Sat, 5 Sep 2020 21:39:39 +0200 Subject: [PATCH 67/87] Fix azure i386 build Looks like pgsql on i386 broke even more. --- azure/i386/apt.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/azure/i386/apt.yml b/azure/i386/apt.yml index 4dd09423c9997..16200803046d2 100644 --- a/azure/i386/apt.yml +++ b/azure/i386/apt.yml @@ -7,8 +7,9 @@ steps: sudo apt-get update -y | true sudo apt-get install -y gcc-multilib sudo apt-get install -y g++-multilib - sudo apt-get purge -y libxml2 libsqlite3-0 + sudo apt-get purge -y libxml2 # TODO: Reenable postgresql + postgresql-contrib packages once they work again. + sudo apt-get purge -y libpq5 sudo apt-get install -y bison \ re2c \ locales \ From 9439ca53227b23e9a0eb0173c80f712ed480fdd8 Mon Sep 17 00:00:00 2001 From: Tyson Andre Date: Sat, 5 Sep 2020 16:52:14 -0400 Subject: [PATCH 68/87] Improve handling of `#[` in `php -a` PHP treats `#ini_setting=value` as a call to `ini_set('ini_setting', 'value')`, and silently skips undeclared settings. This is a problem due to `#[` becoming supported attribute syntax: - `#[Attr] const X = 123;` (this is not a valid place to put an attribute) This does not create a constant. - `#[Attr] function test($x=false){}` also contains `=`. This does not create a function. Instead, only treat lines starting with `#` as a special case when the next character isn't `[` Closes GH-6085 --- ext/readline/readline_cli.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/readline/readline_cli.c b/ext/readline/readline_cli.c index a463a89db4941..d7e6f20c9fbd8 100644 --- a/ext/readline/readline_cli.c +++ b/ext/readline/readline_cli.c @@ -518,7 +518,7 @@ static char *cli_completion_generator(const char *text, int index) /* {{{ */ } if (text[0] == '$') { retval = cli_completion_generator_var(text, textlen, &cli_completion_state); - } else if (text[0] == '#') { + } else if (text[0] == '#' && text[1] != '[') { retval = cli_completion_generator_ini(text, textlen, &cli_completion_state); } else { char *lc_text, *class_name_end; @@ -630,7 +630,7 @@ static int readline_shell_run(void) /* {{{ */ len = strlen(line); - if (line[0] == '#') { + if (line[0] == '#' && line[1] != '[') { char *param = strstr(&line[1], "="); if (param) { zend_string *cmd; From 1fc961e2de866ad426ce83dae760605599934673 Mon Sep 17 00:00:00 2001 From: Tyson Andre Date: Sun, 6 Sep 2020 09:43:09 -0400 Subject: [PATCH 69/87] Improve handling of `#[` attributes in `php -a` `php -a` treats lines starting with `#` as comments when deciding if the provided statement is valid. So it passed `#[MyAttr]` to the parser after the user hits enter, causing a syntax error for multi-line statements.. With this patch, the following snippet is parsed correctly ``` php > #[Attr] php > function x() { } php > var_export((new ReflectionFunction('x'))->getAttributes()[0]->getName()); 'Attr' ``` Followup to GH-6085 Closes GH-6086 --- ext/readline/readline_cli.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ext/readline/readline_cli.c b/ext/readline/readline_cli.c index d7e6f20c9fbd8..2930796ae7605 100644 --- a/ext/readline/readline_cli.c +++ b/ext/readline/readline_cli.c @@ -250,6 +250,10 @@ static int cli_is_valid_code(char *code, size_t len, zend_string **prompt) /* {{ code_type = dstring; break; case '#': + if (code[i+1] == '[') { + valid_end = 0; + break; + } code_type = comment_line; break; case '/': From ace876cdd66dc79be1c3a763bd2865dd88e723e7 Mon Sep 17 00:00:00 2001 From: Tyson Andre Date: Sun, 6 Sep 2020 12:29:32 -0400 Subject: [PATCH 70/87] Fix incorrect/unused macro zend_ts_hash_init accepts 4 arguments, not 5. The pHashFunction parameter was removed in 5d2576264653c2faaca9cd7d64218d10ab612408 Closes GH-6087 --- Zend/zend_ts_hash.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Zend/zend_ts_hash.h b/Zend/zend_ts_hash.h index 51801e4e05f17..d1b41b1d6f678 100644 --- a/Zend/zend_ts_hash.h +++ b/Zend/zend_ts_hash.h @@ -128,6 +128,6 @@ END_EXTERN_C() ZEND_TS_INIT_SYMTABLE_EX(ht, 2, 0) #define ZEND_TS_INIT_SYMTABLE_EX(ht, n, persistent) \ - zend_ts_hash_init(ht, n, NULL, ZVAL_PTR_DTOR, persistent) + zend_ts_hash_init(ht, n, ZVAL_PTR_DTOR, persistent) #endif /* ZEND_HASH_H */ From 623bf96e7e37a05622df163a228c8e1c3f7d0b02 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Mon, 7 Sep 2020 09:59:51 +0200 Subject: [PATCH 71/87] Throw on invalid mb_http_input() type --- ext/mbstring/mbstring.c | 6 +++--- ext/mbstring/tests/mb_http_input.phpt | 17 +++++++++++++++++ 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/ext/mbstring/mbstring.c b/ext/mbstring/mbstring.c index 050afa26e677f..2812580817eed 100644 --- a/ext/mbstring/mbstring.c +++ b/ext/mbstring/mbstring.c @@ -1377,9 +1377,9 @@ PHP_FUNCTION(mb_http_input) mbfl_string_clear(&result); return; default: - // TODO ValueError - encoding = MBSTRG(http_input_identify); - break; + zend_argument_value_error(1, + "must be one of \"G\", \"P\", \"C\", \"S\", \"I\" or \"L\""); + RETURN_THROWS(); } } diff --git a/ext/mbstring/tests/mb_http_input.phpt b/ext/mbstring/tests/mb_http_input.phpt index a81969ffff1e7..e6bb0528ec428 100644 --- a/ext/mbstring/tests/mb_http_input.phpt +++ b/ext/mbstring/tests/mb_http_input.phpt @@ -20,6 +20,15 @@ echo $_GET['b']."\n"; // Get encoding var_dump(mb_http_input('P')); var_dump(mb_http_input('G')); +var_dump(mb_http_input('C')); +var_dump(mb_http_input('S')); +var_dump(mb_http_input('I')); +var_dump(mb_http_input('L')); +try { + var_dump(mb_http_input('Q')); +} catch (ValueError $e) { + echo $e->getMessage(), "\n"; +} ?> --EXPECT-- @@ -27,3 +36,11 @@ var_dump(mb_http_input('G')); ÆüËܸì0123456789ÆüËܸ쥫¥¿¥«¥Ê¤Ò¤é¤¬¤Ê string(10) "ISO-8859-1" string(10) "ISO-8859-1" +bool(false) +bool(false) +array(1) { + [0]=> + string(10) "ISO-8859-1" +} +string(10) "ISO-8859-1" +mb_http_input(): Argument #1 ($type) must be one of "G", "P", "C", "S", "I" or "L" From e0c94677b775b3e32ff3d2be0264fee26cb6a667 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Fri, 4 Sep 2020 15:31:32 +0200 Subject: [PATCH 72/87] Add phpunit to community project tests --- azure/community_job.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/azure/community_job.yml b/azure/community_job.yml index e7b99cd374869..ae1a44ed949f2 100644 --- a/azure/community_job.yml +++ b/azure/community_job.yml @@ -92,4 +92,16 @@ jobs: sed -i 's/$exit = true/$exit = false/g' vendor/phpunit/phpunit/src/TextUI/Command.php php vendor/bin/phpunit displayName: 'Test Amphp' + - script: | + git clone https://github.com/sebastianbergmann/phpunit.git --branch=master --depth=1 + cd phpunit + export USE_ZEND_ALLOC=0 + export USE_TRACKED_ALLOC=1 + export ASAN_OPTIONS=exitcode=139 + php7.3 /usr/bin/composer install --no-progress + php ./phpunit + if [ $? -gt 128 ]; then + exit 1 + fi + displayName: 'Test PHPUnit' condition: or(succeeded(), failed()) From 8e05c4449673c8fd7bf3e1d3f5ddf4689ddd0bdb Mon Sep 17 00:00:00 2001 From: David Carlier Date: Sat, 5 Sep 2020 14:04:01 +0000 Subject: [PATCH 73/87] Opcache JIT, code simplification for Haiku. More straightforward approach to get the path of the current PHP process. Closes GH-6082. --- ext/opcache/jit/zend_elf.c | 17 +++++------------ ext/opcache/jit/zend_jit_perf_dump.c | 17 +++++------------ 2 files changed, 10 insertions(+), 24 deletions(-) diff --git a/ext/opcache/jit/zend_elf.c b/ext/opcache/jit/zend_elf.c index 2618f5a488d2d..58d6fdd72cc6a 100644 --- a/ext/opcache/jit/zend_elf.c +++ b/ext/opcache/jit/zend_elf.c @@ -22,7 +22,7 @@ #if defined(__FreeBSD__) #include #elif defined(__HAIKU__) -#include +#include #endif #include #include @@ -67,20 +67,13 @@ void zend_elf_load_symbols(void) const char *path = getexecname(); int fd = open(path, O_RDONLY); #elif defined(__HAIKU__) - image_info ii; - int32_t ic = 0; - - while (get_next_image_info(0, &ic, &ii) == B_OK) { - if (ii.type == B_APP_IMAGE) { - break; - } - } - - if (ii.type != B_APP_IMAGE) { + char path[PATH_MAX]; + if (find_path(B_APP_IMAGE_SYMBOL, B_FIND_PATH_IMAGE_PATH, + NULL, path, sizeof(path)) != B_OK) { return; } - int fd = open(ii.name, O_RDONLY); + int fd = open(path, O_RDONLY); #else // To complete eventually for other ELF platforms. // Otherwise APPLE is Mach-O diff --git a/ext/opcache/jit/zend_jit_perf_dump.c b/ext/opcache/jit/zend_jit_perf_dump.c index 94feba1f07d8c..613280c2179d2 100644 --- a/ext/opcache/jit/zend_jit_perf_dump.c +++ b/ext/opcache/jit/zend_jit_perf_dump.c @@ -36,7 +36,7 @@ // avoiding thread.h inclusion as it conflicts with vtunes types. extern unsigned int thr_self(void); #elif defined(__HAIKU__) -#include +#include #endif #include "zend_elf.h" @@ -136,20 +136,13 @@ static void zend_jit_perf_jitdump_open(void) const char *path = getexecname(); fd = open(path, O_RDONLY); #elif defined(__HAIKU__) - image_info ii; - int32_t ic = 0; - - while (get_next_image_info(0, &ic, &ii) == B_OK) { - if (ii.type == B_APP_IMAGE) { - break; - } - } - - if (ii.type != B_APP_IMAGE) { + char path[PATH_MAX]; + if (find_path(B_APP_IMAGE_SYMBOL, B_FIND_PATH_IMAGE_PATH, + NULL, path, sizeof(path)) != B_OK) { return; } - fd = open(ii.name, O_RDONLY); + fd = open(path, O_RDONLY); #else fd = -1; #endif From d1ac7e3ab1bf3cf639ddbd63ed3824e8bb9fc32f Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Mon, 7 Sep 2020 11:05:07 +0200 Subject: [PATCH 74/87] Remove some unnecessary HAVE_EXTNAME guards A recurring pattern in old extension: Putting the whole source code behind HAVE_EXTNAME. This is pointless, as the code is only compiled if the extension is enabled. This removes a couple of them, but not all. --- ext/curl/curl_file.c | 3 --- ext/curl/interface.c | 4 ---- ext/curl/multi.c | 4 ---- ext/curl/php_curl.h | 13 +------------ ext/curl/share.c | 4 ---- ext/exif/exif.c | 4 ---- ext/exif/php_exif.h | 4 ---- ext/ftp/ftp.c | 4 ---- ext/ftp/php_ftp.h | 10 +--------- 9 files changed, 2 insertions(+), 48 deletions(-) diff --git a/ext/curl/curl_file.c b/ext/curl/curl_file.c index 4a2b8328b9b72..3888840fd16a6 100644 --- a/ext/curl/curl_file.c +++ b/ext/curl/curl_file.c @@ -23,7 +23,6 @@ #include "Zend/zend_interfaces.h" #include "php_curl.h" #include "curl_file_arginfo.h" -#ifdef HAVE_CURL PHP_CURL_API zend_class_entry *curl_CURLFile_class; @@ -132,5 +131,3 @@ void curlfile_register_class(void) zend_declare_property_string(curl_CURLFile_class, "mime", sizeof("mime")-1, "", ZEND_ACC_PUBLIC); zend_declare_property_string(curl_CURLFile_class, "postname", sizeof("postname")-1, "", ZEND_ACC_PUBLIC); } - -#endif diff --git a/ext/curl/interface.c b/ext/curl/interface.c index a529ef8e73684..906b1c4a0b662 100644 --- a/ext/curl/interface.c +++ b/ext/curl/interface.c @@ -24,8 +24,6 @@ #include "Zend/zend_interfaces.h" #include "Zend/zend_exceptions.h" -#ifdef HAVE_CURL - #include #include @@ -3537,5 +3535,3 @@ PHP_FUNCTION(curl_pause) RETURN_LONG(curl_easy_pause(ch->cp, bitmask)); } /* }}} */ - -#endif /* HAVE_CURL */ diff --git a/ext/curl/multi.c b/ext/curl/multi.c index 55d7f8e4d5e29..954575d54f9c4 100644 --- a/ext/curl/multi.c +++ b/ext/curl/multi.c @@ -23,8 +23,6 @@ #include "php.h" #include "Zend/zend_interfaces.h" -#ifdef HAVE_CURL - #include "php_curl.h" #include @@ -599,5 +597,3 @@ void curl_multi_register_class(const zend_function_entry *method_entries) { curl_multi_handlers.clone_obj = NULL; curl_multi_handlers.cast_object = curl_cast_object; } - -#endif diff --git a/ext/curl/php_curl.h b/ext/curl/php_curl.h index 5022f69d21f88..2a195b082ba01 100644 --- a/ext/curl/php_curl.h +++ b/ext/curl/php_curl.h @@ -21,13 +21,6 @@ #include "php.h" #include "zend_smart_str.h" -#ifdef COMPILE_DL_CURL -#undef HAVE_CURL -#define HAVE_CURL 1 -#endif - -#ifdef HAVE_CURL - #define PHP_CURL_DEBUG 0 #ifdef PHP_WIN32 @@ -45,7 +38,7 @@ #include extern zend_module_entry curl_module_entry; -#define curl_module_ptr &curl_module_entry +#define phpext_curl_ptr &curl_module_entry #define CURLOPT_RETURNTRANSFER 19913 #define CURLOPT_BINARYTRANSFER 19914 /* For Backward compatibility */ @@ -180,8 +173,4 @@ int curl_cast_object(zend_object *obj, zval *result, int type); PHP_CURL_API extern zend_class_entry *curl_CURLFile_class; -#else -#define curl_module_ptr NULL -#endif /* HAVE_CURL */ -#define phpext_curl_ptr curl_module_ptr #endif /* _PHP_CURL_H */ diff --git a/ext/curl/share.c b/ext/curl/share.c index 407e14cdcffb3..d7eb7be56a23f 100644 --- a/ext/curl/share.c +++ b/ext/curl/share.c @@ -23,8 +23,6 @@ #include "php.h" #include "Zend/zend_interfaces.h" -#ifdef HAVE_CURL - #include "php_curl.h" #include @@ -179,5 +177,3 @@ void curl_share_register_class(const zend_function_entry *method_entries) { curl_share_handlers.get_constructor = curl_share_get_constructor; curl_share_handlers.clone_obj = NULL; } - -#endif diff --git a/ext/exif/exif.c b/ext/exif/exif.c index a75b7db57a8ee..b2852628badec 100644 --- a/ext/exif/exif.c +++ b/ext/exif/exif.c @@ -22,8 +22,6 @@ #include "php.h" #include "ext/standard/file.h" -#ifdef HAVE_EXIF - /* When EXIF_DEBUG is defined the module generates a lot of debug messages * that help understanding what is going on. This can and should be used * while extending the module as it shows if you are at the right position. @@ -4791,5 +4789,3 @@ PHP_FUNCTION(exif_imagetype) } } /* }}} */ - -#endif diff --git a/ext/exif/php_exif.h b/ext/exif/php_exif.h index 466b02645fac1..fbc91a0f85393 100644 --- a/ext/exif/php_exif.h +++ b/ext/exif/php_exif.h @@ -15,12 +15,8 @@ +----------------------------------------------------------------------+ */ -#ifdef HAVE_EXIF - #include "php_version.h" #define PHP_EXIF_VERSION PHP_VERSION extern zend_module_entry exif_module_entry; #define phpext_exif_ptr &exif_module_entry - -#endif diff --git a/ext/ftp/ftp.c b/ext/ftp/ftp.c index 3defd3d506ffb..7ce3386c57b20 100644 --- a/ext/ftp/ftp.c +++ b/ext/ftp/ftp.c @@ -21,8 +21,6 @@ #include "php.h" -#ifdef HAVE_FTP - #include #include #include @@ -2266,5 +2264,3 @@ ftp_nb_continue_write(ftpbuf_t *ftp) return PHP_FTP_FAILED; } /* }}} */ - -#endif /* HAVE_FTP */ diff --git a/ext/ftp/php_ftp.h b/ext/ftp/php_ftp.h index 60eba04adfd8c..ac0bef5fd7663 100644 --- a/ext/ftp/php_ftp.h +++ b/ext/ftp/php_ftp.h @@ -18,10 +18,8 @@ #ifndef _INCLUDED_FTP_H #define _INCLUDED_FTP_H -#ifdef HAVE_FTP - extern zend_module_entry php_ftp_module_entry; -#define php_ftp_module_ptr &php_ftp_module_entry +#define phpext_ftp_ptr &php_ftp_module_entry #include "php_version.h" #define PHP_FTP_VERSION PHP_VERSION @@ -34,10 +32,4 @@ extern zend_module_entry php_ftp_module_entry; PHP_MINIT_FUNCTION(ftp); PHP_MINFO_FUNCTION(ftp); -#define phpext_ftp_ptr php_ftp_module_ptr - -#else -#define php_ftp_module_ptr NULL -#endif /* HAVE_FTP */ - #endif From 85b5dc4711f6ce8b979ed60e3b60cf93225be32a Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Mon, 7 Sep 2020 11:12:41 +0200 Subject: [PATCH 75/87] Private/public split curl header To allow exporting the php_curl.h header containing curl class entries, split off a separate curl_private.h header with all the implementation details. We may move or expose additional APIs in php_curl.h on an as-needed basis. --- ext/curl/config.m4 | 1 + ext/curl/config.w32 | 1 + ext/curl/curl_file.c | 2 +- ext/curl/curl_private.h | 159 ++++++++++++++++++++++++++++++++++++++++ ext/curl/interface.c | 2 +- ext/curl/multi.c | 5 +- ext/curl/php_curl.h | 139 +---------------------------------- ext/curl/share.c | 2 +- 8 files changed, 168 insertions(+), 143 deletions(-) create mode 100644 ext/curl/curl_private.h diff --git a/ext/curl/config.m4 b/ext/curl/config.m4 index 051d97743b67b..3b11739654bd6 100644 --- a/ext/curl/config.m4 +++ b/ext/curl/config.m4 @@ -82,5 +82,6 @@ int main(int argc, char *argv[]) ]) PHP_NEW_EXTENSION(curl, interface.c multi.c share.c curl_file.c, $ext_shared) + PHP_INSTALL_HEADERS([ext/curl], [php_curl.h]) PHP_SUBST(CURL_SHARED_LIBADD) fi diff --git a/ext/curl/config.w32 b/ext/curl/config.w32 index 8ff6718b606be..9402e5b3ec801 100644 --- a/ext/curl/config.w32 +++ b/ext/curl/config.w32 @@ -29,6 +29,7 @@ if (PHP_CURL != "no") { EXTENSION("curl", "interface.c multi.c share.c curl_file.c"); AC_DEFINE('HAVE_CURL', 1, 'Have cURL library'); ADD_FLAG("CFLAGS_CURL", "/D CURL_STATICLIB"); + PHP_INSTALL_HEADERS("ext/curl", "php_curl.h"); // TODO: check for curl_version_info } else { WARNING("curl not enabled; libraries and headers not found"); diff --git a/ext/curl/curl_file.c b/ext/curl/curl_file.c index 3888840fd16a6..aad162604a1f4 100644 --- a/ext/curl/curl_file.c +++ b/ext/curl/curl_file.c @@ -21,7 +21,7 @@ #include "php.h" #include "Zend/zend_exceptions.h" #include "Zend/zend_interfaces.h" -#include "php_curl.h" +#include "curl_private.h" #include "curl_file_arginfo.h" PHP_CURL_API zend_class_entry *curl_CURLFile_class; diff --git a/ext/curl/curl_private.h b/ext/curl/curl_private.h new file mode 100644 index 0000000000000..8ff0aef605c8e --- /dev/null +++ b/ext/curl/curl_private.h @@ -0,0 +1,159 @@ +/* + +----------------------------------------------------------------------+ + | Copyright (c) The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Sterling Hughes | + | Wez Furlong | + +----------------------------------------------------------------------+ +*/ + +#ifndef _PHP_CURL_PRIVATE_H +#define _PHP_CURL_PRIVATE_H + +#include "php_curl.h" + +#define PHP_CURL_DEBUG 0 + +#include "php_version.h" +#define PHP_CURL_VERSION PHP_VERSION + +#include +#include + +#define CURLOPT_RETURNTRANSFER 19913 +#define CURLOPT_BINARYTRANSFER 19914 /* For Backward compatibility */ +#define PHP_CURL_STDOUT 0 +#define PHP_CURL_FILE 1 +#define PHP_CURL_USER 2 +#define PHP_CURL_DIRECT 3 +#define PHP_CURL_RETURN 4 +#define PHP_CURL_IGNORE 7 + +#define SAVE_CURL_ERROR(__handle, __err) \ + do { (__handle)->err.no = (int) __err; } while (0) + +PHP_MINIT_FUNCTION(curl); +PHP_MSHUTDOWN_FUNCTION(curl); +PHP_MINFO_FUNCTION(curl); + +typedef struct { + zval func_name; + zend_fcall_info_cache fci_cache; + FILE *fp; + smart_str buf; + int method; + zval stream; +} php_curl_write; + +typedef struct { + zval func_name; + zend_fcall_info_cache fci_cache; + FILE *fp; + zend_resource *res; + int method; + zval stream; +} php_curl_read; + +typedef struct { + zval func_name; + zend_fcall_info_cache fci_cache; + int method; +} php_curl_progress, php_curl_fnmatch, php_curlm_server_push; + +typedef struct { + php_curl_write *write; + php_curl_write *write_header; + php_curl_read *read; + zval std_err; + php_curl_progress *progress; +#if LIBCURL_VERSION_NUM >= 0x071500 /* Available since 7.21.0 */ + php_curl_fnmatch *fnmatch; +#endif +} php_curl_handlers; + +struct _php_curl_error { + char str[CURL_ERROR_SIZE + 1]; + int no; +}; + +struct _php_curl_send_headers { + zend_string *str; +}; + +struct _php_curl_free { + zend_llist str; + zend_llist post; + zend_llist stream; + HashTable *slist; +}; + +typedef struct { + CURL *cp; + php_curl_handlers *handlers; + struct _php_curl_free *to_free; + struct _php_curl_send_headers header; + struct _php_curl_error err; + zend_bool in_callback; + uint32_t* clone; + zval postfields; + zend_object std; +} php_curl; + +#define CURLOPT_SAFE_UPLOAD -1 + +typedef struct { + php_curlm_server_push *server_push; +} php_curlm_handlers; + +typedef struct { + int still_running; + CURLM *multi; + zend_llist easyh; + php_curlm_handlers *handlers; + struct { + int no; + } err; + zend_object std; +} php_curlm; + +typedef struct { + CURLSH *share; + struct { + int no; + } err; + zend_object std; +} php_curlsh; + +php_curl *init_curl_handle_into_zval(zval *curl); +void init_curl_handle(php_curl *ch); +void _php_curl_cleanup_handle(php_curl *); +void _php_curl_multi_cleanup_list(void *data); +void _php_curl_verify_handlers(php_curl *ch, int reporterror); +void _php_setup_easy_copy_handlers(php_curl *ch, php_curl *source); + +static inline php_curl *curl_from_obj(zend_object *obj) { + return (php_curl *)((char *)(obj) - XtOffsetOf(php_curl, std)); +} + +#define Z_CURL_P(zv) curl_from_obj(Z_OBJ_P(zv)) + +static inline php_curlsh *curl_share_from_obj(zend_object *obj) { + return (php_curlsh *)((char *)(obj) - XtOffsetOf(php_curlsh, std)); +} + +#define Z_CURL_SHARE_P(zv) curl_share_from_obj(Z_OBJ_P(zv)) + +void curl_multi_register_class(const zend_function_entry *method_entries); +void curl_share_register_class(const zend_function_entry *method_entries); +void curlfile_register_class(void); +int curl_cast_object(zend_object *obj, zval *result, int type); + +#endif /* _PHP_CURL_PRIVATE_H */ diff --git a/ext/curl/interface.c b/ext/curl/interface.c index 906b1c4a0b662..09e02b3ba527c 100644 --- a/ext/curl/interface.c +++ b/ext/curl/interface.c @@ -60,7 +60,7 @@ #include "ext/standard/info.h" #include "ext/standard/file.h" #include "ext/standard/url.h" -#include "php_curl.h" +#include "curl_private.h" #include "curl_arginfo.h" #ifdef PHP_CURL_NEED_OPENSSL_TSL /* {{{ */ diff --git a/ext/curl/multi.c b/ext/curl/multi.c index 954575d54f9c4..2c2e37e4028ac 100644 --- a/ext/curl/multi.c +++ b/ext/curl/multi.c @@ -22,8 +22,9 @@ #include "php.h" #include "Zend/zend_interfaces.h" +#include "Zend/zend_smart_str.h" -#include "php_curl.h" +#include "curl_private.h" #include #include @@ -48,7 +49,7 @@ /* CurlMultiHandle class */ -static zend_class_entry *curl_multi_ce; +zend_class_entry *curl_multi_ce; static inline php_curlm *curl_multi_from_obj(zend_object *obj) { return (php_curlm *)((char *)(obj) - XtOffsetOf(php_curlm, std)); diff --git a/ext/curl/php_curl.h b/ext/curl/php_curl.h index 2a195b082ba01..ebb56278aa24f 100644 --- a/ext/curl/php_curl.h +++ b/ext/curl/php_curl.h @@ -19,9 +19,6 @@ #define _PHP_CURL_H #include "php.h" -#include "zend_smart_str.h" - -#define PHP_CURL_DEBUG 0 #ifdef PHP_WIN32 # define PHP_CURL_API __declspec(dllexport) @@ -31,146 +28,12 @@ # define PHP_CURL_API #endif -#include "php_version.h" -#define PHP_CURL_VERSION PHP_VERSION - -#include -#include - extern zend_module_entry curl_module_entry; #define phpext_curl_ptr &curl_module_entry -#define CURLOPT_RETURNTRANSFER 19913 -#define CURLOPT_BINARYTRANSFER 19914 /* For Backward compatibility */ -#define PHP_CURL_STDOUT 0 -#define PHP_CURL_FILE 1 -#define PHP_CURL_USER 2 -#define PHP_CURL_DIRECT 3 -#define PHP_CURL_RETURN 4 -#define PHP_CURL_IGNORE 7 - -#define SAVE_CURL_ERROR(__handle, __err) \ - do { (__handle)->err.no = (int) __err; } while (0) - -PHP_MINIT_FUNCTION(curl); -PHP_MSHUTDOWN_FUNCTION(curl); -PHP_MINFO_FUNCTION(curl); - -typedef struct { - zval func_name; - zend_fcall_info_cache fci_cache; - FILE *fp; - smart_str buf; - int method; - zval stream; -} php_curl_write; - -typedef struct { - zval func_name; - zend_fcall_info_cache fci_cache; - FILE *fp; - zend_resource *res; - int method; - zval stream; -} php_curl_read; - -typedef struct { - zval func_name; - zend_fcall_info_cache fci_cache; - int method; -} php_curl_progress, php_curl_fnmatch, php_curlm_server_push; - -typedef struct { - php_curl_write *write; - php_curl_write *write_header; - php_curl_read *read; - zval std_err; - php_curl_progress *progress; -#if LIBCURL_VERSION_NUM >= 0x071500 /* Available since 7.21.0 */ - php_curl_fnmatch *fnmatch; -#endif -} php_curl_handlers; - -struct _php_curl_error { - char str[CURL_ERROR_SIZE + 1]; - int no; -}; - -struct _php_curl_send_headers { - zend_string *str; -}; - -struct _php_curl_free { - zend_llist str; - zend_llist post; - zend_llist stream; - HashTable *slist; -}; - -typedef struct { - CURL *cp; - php_curl_handlers *handlers; - struct _php_curl_free *to_free; - struct _php_curl_send_headers header; - struct _php_curl_error err; - zend_bool in_callback; - uint32_t* clone; - zval postfields; - zend_object std; -} php_curl; - -#define CURLOPT_SAFE_UPLOAD -1 - -typedef struct { - php_curlm_server_push *server_push; -} php_curlm_handlers; - -typedef struct { - int still_running; - CURLM *multi; - zend_llist easyh; - php_curlm_handlers *handlers; - struct { - int no; - } err; - zend_object std; -} php_curlm; - -typedef struct { - CURLSH *share; - struct { - int no; - } err; - zend_object std; -} php_curlsh; - -php_curl *init_curl_handle_into_zval(zval *curl); -void init_curl_handle(php_curl *ch); -void _php_curl_cleanup_handle(php_curl *); -void _php_curl_multi_cleanup_list(void *data); -void _php_curl_verify_handlers(php_curl *ch, int reporterror); -void _php_setup_easy_copy_handlers(php_curl *ch, php_curl *source); - -static inline php_curl *curl_from_obj(zend_object *obj) { - return (php_curl *)((char *)(obj) - XtOffsetOf(php_curl, std)); -} - -#define Z_CURL_P(zv) curl_from_obj(Z_OBJ_P(zv)) - -static inline php_curlsh *curl_share_from_obj(zend_object *obj) { - return (php_curlsh *)((char *)(obj) - XtOffsetOf(php_curlsh, std)); -} - -#define Z_CURL_SHARE_P(zv) curl_share_from_obj(Z_OBJ_P(zv)) - PHP_CURL_API extern zend_class_entry *curl_ce; PHP_CURL_API extern zend_class_entry *curl_share_ce; - -void curl_multi_register_class(const zend_function_entry *method_entries); -void curl_share_register_class(const zend_function_entry *method_entries); -void curlfile_register_class(void); -int curl_cast_object(zend_object *obj, zval *result, int type); - +PHP_CURL_API extern zend_class_entry *curl_multi_ce; PHP_CURL_API extern zend_class_entry *curl_CURLFile_class; #endif /* _PHP_CURL_H */ diff --git a/ext/curl/share.c b/ext/curl/share.c index d7eb7be56a23f..58135acdb5659 100644 --- a/ext/curl/share.c +++ b/ext/curl/share.c @@ -23,7 +23,7 @@ #include "php.h" #include "Zend/zend_interfaces.h" -#include "php_curl.h" +#include "curl_private.h" #include From f5dbebd82e642b1d1af462b486fc392ecff2c67a Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Mon, 7 Sep 2020 11:42:21 +0200 Subject: [PATCH 76/87] Accept zend_string instead of zval in zend_compile_string --- Zend/zend_compile.c | 2 +- Zend/zend_compile.h | 4 ++-- Zend/zend_execute.c | 4 +++- Zend/zend_execute_API.c | 15 ++++++--------- Zend/zend_language_scanner.l | 13 ++++--------- sapi/phpdbg/phpdbg.h | 2 +- sapi/phpdbg/phpdbg_bp.c | 16 +++++----------- sapi/phpdbg/phpdbg_list.c | 8 ++++---- sapi/phpdbg/phpdbg_prompt.c | 7 +------ 9 files changed, 27 insertions(+), 44 deletions(-) diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 36715c7bb5879..7eb2d79fe72f5 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -79,7 +79,7 @@ static inline uint32_t zend_alloc_cache_slot(void) { } ZEND_API zend_op_array *(*zend_compile_file)(zend_file_handle *file_handle, int type); -ZEND_API zend_op_array *(*zend_compile_string)(zval *source_string, const char *filename); +ZEND_API zend_op_array *(*zend_compile_string)(zend_string *source_string, const char *filename); #ifndef ZTS ZEND_API zend_compiler_globals compiler_globals; diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index e50f620ed4078..505e625270ebb 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -732,7 +732,7 @@ void zend_file_context_begin(zend_file_context *prev_context); void zend_file_context_end(zend_file_context *prev_context); extern ZEND_API zend_op_array *(*zend_compile_file)(zend_file_handle *file_handle, int type); -extern ZEND_API zend_op_array *(*zend_compile_string)(zval *source_string, const char *filename); +extern ZEND_API zend_op_array *(*zend_compile_string)(zend_string *source_string, const char *filename); ZEND_API int ZEND_FASTCALL lex_scan(zval *zendlval, zend_parser_stack_elem *elem); void startup_scanner(void); @@ -792,7 +792,7 @@ ZEND_API void function_add_ref(zend_function *function); struct _zend_arena; ZEND_API zend_op_array *compile_file(zend_file_handle *file_handle, int type); -ZEND_API zend_op_array *compile_string(zval *source_string, const char *filename); +ZEND_API zend_op_array *compile_string(zend_string *source_string, const char *filename); ZEND_API zend_op_array *compile_filename(int type, zval *filename); ZEND_API zend_ast *zend_compile_string_to_ast( zend_string *code, struct _zend_arena **ast_arena, const char *filename); diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 6e66ba72d66cd..2c07eae9eb96e 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -4217,7 +4217,9 @@ static zend_never_inline zend_op_array* ZEND_FASTCALL zend_include_or_eval(zval break; case ZEND_EVAL: { char *eval_desc = zend_make_compiled_string_description("eval()'d code"); - new_op_array = zend_compile_string(inc_filename, eval_desc); + zend_string *code = zval_get_string(inc_filename); + new_op_array = zend_compile_string(code, eval_desc); + zend_string_release(code); efree(eval_desc); } break; diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index b8c3f1197406b..f1bcc74a58d8a 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -1143,26 +1143,23 @@ ZEND_API zend_object *zend_get_this_object(zend_execute_data *ex) /* {{{ */ ZEND_API zend_result zend_eval_stringl(const char *str, size_t str_len, zval *retval_ptr, const char *string_name) /* {{{ */ { - zval pv; zend_op_array *new_op_array; uint32_t original_compiler_options; zend_result retval; + zend_string *code_str; if (retval_ptr) { - ZVAL_NEW_STR(&pv, zend_string_alloc(str_len + sizeof("return ;")-1, 0)); - memcpy(Z_STRVAL(pv), "return ", sizeof("return ") - 1); - memcpy(Z_STRVAL(pv) + sizeof("return ") - 1, str, str_len); - Z_STRVAL(pv)[Z_STRLEN(pv) - 1] = ';'; - Z_STRVAL(pv)[Z_STRLEN(pv)] = '\0'; + code_str = zend_string_concat3( + "return ", sizeof("return ")-1, str, str_len, ";", sizeof(";")-1); } else { - ZVAL_STRINGL(&pv, str, str_len); + code_str = zend_string_init(str, str_len, 0); } /*printf("Evaluating '%s'\n", pv.value.str.val);*/ original_compiler_options = CG(compiler_options); CG(compiler_options) = ZEND_COMPILE_DEFAULT_FOR_EVAL; - new_op_array = zend_compile_string(&pv, string_name); + new_op_array = zend_compile_string(code_str, string_name); CG(compiler_options) = original_compiler_options; if (new_op_array) { @@ -1200,7 +1197,7 @@ ZEND_API zend_result zend_eval_stringl(const char *str, size_t str_len, zval *re } else { retval = FAILURE; } - zval_ptr_dtor_str(&pv); + zend_string_release(code_str); return retval; } /* }}} */ diff --git a/Zend/zend_language_scanner.l b/Zend/zend_language_scanner.l index 91f00e95d960b..d1c5b85cf248c 100644 --- a/Zend/zend_language_scanner.l +++ b/Zend/zend_language_scanner.l @@ -804,23 +804,18 @@ ZEND_API size_t zend_get_scanned_file_offset(void) return offset; } -zend_op_array *compile_string(zval *source_string, const char *filename) +zend_op_array *compile_string(zend_string *source_string, const char *filename) { zend_lex_state original_lex_state; zend_op_array *op_array = NULL; zval tmp; - if (UNEXPECTED(Z_TYPE_P(source_string) != IS_STRING)) { - ZVAL_STR(&tmp, zval_get_string_func(source_string)); - } else { - ZVAL_COPY(&tmp, source_string); - } - - if (Z_STRLEN(tmp)==0) { - zval_ptr_dtor(&tmp); + if (ZSTR_LEN(source_string) == 0) { return NULL; } + ZVAL_STR_COPY(&tmp, source_string); + zend_save_lexical_state(&original_lex_state); zend_prepare_string_for_scanning(&tmp, filename); BEGIN(ST_IN_SCRIPTING); diff --git a/sapi/phpdbg/phpdbg.h b/sapi/phpdbg/phpdbg.h index 5405155833cbe..e5db7253364cb 100644 --- a/sapi/phpdbg/phpdbg.h +++ b/sapi/phpdbg/phpdbg.h @@ -275,7 +275,7 @@ ZEND_BEGIN_MODULE_GLOBALS(phpdbg) zend_op_array *(*compile_file)(zend_file_handle *file_handle, int type); zend_op_array *(*init_compile_file)(zend_file_handle *file_handle, int type); - zend_op_array *(*compile_string)(zval *source_string, const char *filename); + zend_op_array *(*compile_string)(zend_string *source_string, const char *filename); HashTable file_sources; FILE *oplog; /* opline log */ diff --git a/sapi/phpdbg/phpdbg_bp.c b/sapi/phpdbg/phpdbg_bp.c index a29d4442fbcf8..db3d1cf0c4267 100644 --- a/sapi/phpdbg/phpdbg_bp.c +++ b/sapi/phpdbg/phpdbg_bp.c @@ -828,7 +828,7 @@ static inline void phpdbg_create_conditional_break(phpdbg_breakcond_t *brake, co { phpdbg_breakcond_t new_break; uint32_t cops = CG(compiler_options); - zval pv; + zend_string *bp_code; switch (param->type) { case STR_PARAM: @@ -877,16 +877,10 @@ static inline void phpdbg_create_conditional_break(phpdbg_breakcond_t *brake, co new_break.code = estrndup(expr, expr_len); new_break.code_len = expr_len; - Z_STR(pv) = zend_string_alloc(expr_len + sizeof("return ;") - 1, 0); - memcpy(Z_STRVAL(pv), "return ", sizeof("return ") - 1); - memcpy(Z_STRVAL(pv) + sizeof("return ") - 1, expr, expr_len); - Z_STRVAL(pv)[Z_STRLEN(pv) - 1] = ';'; - Z_STRVAL(pv)[Z_STRLEN(pv)] = '\0'; - Z_TYPE_INFO(pv) = IS_STRING; - - new_break.ops = zend_compile_string(&pv, "Conditional Breakpoint Code"); - - zval_ptr_dtor_str(&pv); + bp_code = zend_string_concat3( + "return ", sizeof("return ")-1, expr, expr_len, ";", sizeof(";")-1); + new_break.ops = zend_compile_string(bp_code, "Conditional Breakpoint Code"); + zend_string_release(bp_code); if (new_break.ops) { brake = zend_hash_index_update_mem(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], hash, &new_break, sizeof(phpdbg_breakcond_t)); diff --git a/sapi/phpdbg/phpdbg_list.c b/sapi/phpdbg/phpdbg_list.c index d9b2fa00d58d4..0967e22f65dab 100644 --- a/sapi/phpdbg/phpdbg_list.c +++ b/sapi/phpdbg/phpdbg_list.c @@ -316,7 +316,7 @@ zend_op_array *phpdbg_init_compile_file(zend_file_handle *file, int type) { return op_array; } -zend_op_array *phpdbg_compile_string(zval *source_string, const char *filename) { +zend_op_array *phpdbg_compile_string(zend_string *source_string, const char *filename) { zend_string *fake_name; zend_op_array *op_array; phpdbg_file_source *dataptr; @@ -327,9 +327,9 @@ zend_op_array *phpdbg_compile_string(zval *source_string, const char *filename) return PHPDBG_G(compile_string)(source_string, filename); } - dataptr = emalloc(sizeof(phpdbg_file_source) + sizeof(uint32_t) * Z_STRLEN_P(source_string)); - dataptr->buf = estrndup(Z_STRVAL_P(source_string), Z_STRLEN_P(source_string)); - dataptr->len = Z_STRLEN_P(source_string); + dataptr = emalloc(sizeof(phpdbg_file_source) + sizeof(uint32_t) * ZSTR_LEN(source_string)); + dataptr->buf = estrndup(ZSTR_VAL(source_string), ZSTR_LEN(source_string)); + dataptr->len = ZSTR_LEN(source_string); dataptr->line[0] = 0; for (line = 0, bufptr = dataptr->buf - 1, endptr = dataptr->buf + dataptr->len; ++bufptr < endptr;) { if (*bufptr == '\n') { diff --git a/sapi/phpdbg/phpdbg_prompt.c b/sapi/phpdbg/phpdbg_prompt.c index 9f8fdd820c4bc..39ef7d8768263 100644 --- a/sapi/phpdbg/phpdbg_prompt.c +++ b/sapi/phpdbg/phpdbg_prompt.c @@ -519,12 +519,7 @@ PHPDBG_COMMAND(stdin) } /* }}} */ int phpdbg_compile_stdin(zend_string *code) { - zval zv; - - ZVAL_STR(&zv, code); - - PHPDBG_G(ops) = zend_compile_string(&zv, "Standard input code"); - + PHPDBG_G(ops) = zend_compile_string(code, "Standard input code"); zend_string_release(code); if (EG(exception)) { From 9475bcbef77c5e87d0381943ab0194f720b1323c Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Mon, 7 Sep 2020 11:53:01 +0200 Subject: [PATCH 77/87] Avoid large eval inputs in fuzzer While we limit the size of the main compilation input, the size of eval inputs was not limited. This could result in stack overflows, e.g. oss-fuzz #25464. --- sapi/fuzzer/fuzzer-execute.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/sapi/fuzzer/fuzzer-execute.c b/sapi/fuzzer/fuzzer-execute.c index f9faf90dea5f0..95afab1a3e7a0 100644 --- a/sapi/fuzzer/fuzzer-execute.c +++ b/sapi/fuzzer/fuzzer-execute.c @@ -20,13 +20,14 @@ #include "fuzzer-sapi.h" #define MAX_STEPS 1000 +#define MAX_SIZE (16 * 1024) static uint32_t steps_left; /* Because the fuzzer is always compiled with clang, * we can assume that we don't use global registers / hybrid VM. */ typedef int (ZEND_FASTCALL *opcode_handler_t)(zend_execute_data *); -void fuzzer_execute_ex(zend_execute_data *execute_data) { +static void fuzzer_execute_ex(zend_execute_data *execute_data) { while (1) { int ret; if (--steps_left == 0) { @@ -46,8 +47,19 @@ void fuzzer_execute_ex(zend_execute_data *execute_data) { } } +static zend_op_array *(*orig_compile_string)(zend_string *source_string, const char *filename); + +static zend_op_array *fuzzer_compile_string(zend_string *str, const char *filename) { + if (ZSTR_LEN(str) > MAX_SIZE) { + /* Avoid compiling huge inputs via eval(). */ + zend_bailout(); + } + + return orig_compile_string(str, filename); +} + int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { - if (Size > 16 * 1024) { + if (Size > MAX_SIZE) { /* Large inputs have a large impact on fuzzer performance, * but are unlikely to be necessary to reach new codepaths. */ return 0; @@ -68,7 +80,10 @@ int LLVMFuzzerInitialize(int *argc, char ***argv) { signal(SIGPIPE, SIG_IGN); fuzzer_init_php(); + zend_execute_ex = fuzzer_execute_ex; + orig_compile_string = zend_compile_string; + zend_compile_string = fuzzer_compile_string; /* fuzzer_shutdown_php(); */ return 0; From f4b2497ad8c366d276689dd1c7e3a84c33c11d9b Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Mon, 7 Sep 2020 12:30:43 +0200 Subject: [PATCH 78/87] Allocate temporary PCRE match data using ZMM Create a separate general context that uses ZMM as allocator and use it to allocate temporary PCRE match data (there is still one global match data). There is no requirement that the match data and the compiled regex / match context use the same general context. This makes sure that we do not leak persistent memory on bailout and fixes oss-fuzz #25296, on which half the libfuzzer runs currently get stuck. --- ext/pcre/php_pcre.c | 40 ++++++++++++++----- ext/pcre/php_pcre.h | 2 + ...reg_replace_callback_fatal_error_leak.phpt | 18 +++++++++ 3 files changed, 49 insertions(+), 11 deletions(-) create mode 100644 ext/pcre/tests/preg_replace_callback_fatal_error_leak.phpt diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c index 801d19fc4f9a9..99ab36e84f3e8 100644 --- a/ext/pcre/php_pcre.c +++ b/ext/pcre/php_pcre.c @@ -59,6 +59,7 @@ PHPAPI ZEND_DECLARE_MODULE_GLOBALS(pcre) #define PCRE_JIT_STACK_MAX_SIZE (192 * 1024) ZEND_TLS pcre2_jit_stack *jit_stack = NULL; #endif +/* General context using (infallible) system allocator. */ ZEND_TLS pcre2_general_context *gctx = NULL; /* These two are global per thread for now. Though it is possible to use these per pattern. Either one can copy it and use in pce, or one does no global @@ -173,15 +174,24 @@ static void php_efree_pcre_cache(zval *data) /* {{{ */ /* }}} */ static void *php_pcre_malloc(PCRE2_SIZE size, void *data) -{/*{{{*/ - void *p = pemalloc(size, 1); - return p; -}/*}}}*/ +{ + return pemalloc(size, 1); +} static void php_pcre_free(void *block, void *data) -{/*{{{*/ +{ pefree(block, 1); -}/*}}}*/ +} + +static void *php_pcre_emalloc(PCRE2_SIZE size, void *data) +{ + return emalloc(size); +} + +static void php_pcre_efree(void *block, void *data) +{ + efree(block); +} #define PHP_PCRE_PREALLOC_MDATA_SIZE 32 @@ -476,6 +486,11 @@ static PHP_RINIT_FUNCTION(pcre) mdata_used = 0; #endif + PCRE_G(gctx_zmm) = pcre2_general_context_create(php_pcre_emalloc, php_pcre_efree, NULL); + if (!PCRE_G(gctx_zmm)) { + return FAILURE; + } + if (PCRE_G(per_request_cache)) { zend_hash_init(&PCRE_G(pcre_cache), 0, NULL, php_efree_pcre_cache, 0); } @@ -486,6 +501,9 @@ static PHP_RINIT_FUNCTION(pcre) static PHP_RSHUTDOWN_FUNCTION(pcre) { + pcre2_general_context_free(PCRE_G(gctx_zmm)); + PCRE_G(gctx_zmm) = NULL; + if (PCRE_G(per_request_cache)) { zend_hash_destroy(&PCRE_G(pcre_cache)); } @@ -1246,7 +1264,7 @@ PHPAPI void php_pcre_match_impl(pcre_cache_entry *pce, zend_string *subject_str, if (!mdata_used && num_subpats <= PHP_PCRE_PREALLOC_MDATA_SIZE) { match_data = mdata; } else { - match_data = pcre2_match_data_create_from_pattern(pce->re, gctx); + match_data = pcre2_match_data_create_from_pattern(pce->re, PCRE_G(gctx_zmm)); if (!match_data) { PCRE_G(error_code) = PHP_PCRE_INTERNAL_ERROR; if (subpat_names) { @@ -1617,7 +1635,7 @@ PHPAPI zend_string *php_pcre_replace_impl(pcre_cache_entry *pce, zend_string *su if (!mdata_used && num_subpats <= PHP_PCRE_PREALLOC_MDATA_SIZE) { match_data = mdata; } else { - match_data = pcre2_match_data_create_from_pattern(pce->re, gctx); + match_data = pcre2_match_data_create_from_pattern(pce->re, PCRE_G(gctx_zmm)); if (!match_data) { PCRE_G(error_code) = PHP_PCRE_INTERNAL_ERROR; return NULL; @@ -1871,7 +1889,7 @@ static zend_string *php_pcre_replace_func_impl(pcre_cache_entry *pce, zend_strin mdata_used = 1; match_data = mdata; } else { - match_data = pcre2_match_data_create_from_pattern(pce->re, gctx); + match_data = pcre2_match_data_create_from_pattern(pce->re, PCRE_G(gctx_zmm)); if (!match_data) { PCRE_G(error_code) = PHP_PCRE_INTERNAL_ERROR; if (subpat_names) { @@ -2519,7 +2537,7 @@ PHPAPI void php_pcre_split_impl(pcre_cache_entry *pce, zend_string *subject_str, if (!mdata_used && num_subpats <= PHP_PCRE_PREALLOC_MDATA_SIZE) { match_data = mdata; } else { - match_data = pcre2_match_data_create_from_pattern(pce->re, gctx); + match_data = pcre2_match_data_create_from_pattern(pce->re, PCRE_G(gctx_zmm)); if (!match_data) { PCRE_G(error_code) = PHP_PCRE_INTERNAL_ERROR; zval_ptr_dtor(return_value); @@ -2853,7 +2871,7 @@ PHPAPI void php_pcre_grep_impl(pcre_cache_entry *pce, zval *input, zval *return if (!mdata_used && num_subpats <= PHP_PCRE_PREALLOC_MDATA_SIZE) { match_data = mdata; } else { - match_data = pcre2_match_data_create_from_pattern(pce->re, gctx); + match_data = pcre2_match_data_create_from_pattern(pce->re, PCRE_G(gctx_zmm)); if (!match_data) { PCRE_G(error_code) = PHP_PCRE_INTERNAL_ERROR; return; diff --git a/ext/pcre/php_pcre.h b/ext/pcre/php_pcre.h index 808b671bb8fdd..e9f5e34ab92c0 100644 --- a/ext/pcre/php_pcre.h +++ b/ext/pcre/php_pcre.h @@ -84,6 +84,8 @@ ZEND_BEGIN_MODULE_GLOBALS(pcre) /* Used for unmatched subpatterns in OFFSET_CAPTURE mode */ zval unmatched_null_pair; zval unmatched_empty_pair; + /* General context using per-request allocator (ZMM). */ + pcre2_general_context *gctx_zmm; ZEND_END_MODULE_GLOBALS(pcre) PHPAPI ZEND_EXTERN_MODULE_GLOBALS(pcre) diff --git a/ext/pcre/tests/preg_replace_callback_fatal_error_leak.phpt b/ext/pcre/tests/preg_replace_callback_fatal_error_leak.phpt new file mode 100644 index 0000000000000..5ea3d4081e688 --- /dev/null +++ b/ext/pcre/tests/preg_replace_callback_fatal_error_leak.phpt @@ -0,0 +1,18 @@ +--TEST-- +preg_replace_callback() should not leak persistent memory on fatal error +--FILE-- + +--EXPECTF-- +Fatal error: Cannot redeclare test() (previously declared in %s on line %d From 032f862133dbd2acc04cb75004428d6209f6046b Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Mon, 7 Sep 2020 15:43:26 +0200 Subject: [PATCH 79/87] Drop support for crypt() without explicit salt crypt() without salt generates a weak $1$ MD5 hash. It has been throwing a notice since 2013 and we provide a much better alternative in password_hash() (which can auto-generate salts for strong password hashes), so keeping this is just a liability. --- UPGRADING | 3 +++ ext/standard/basic_functions.stub.php | 2 +- ext/standard/basic_functions_arginfo.h | 4 ++-- ext/standard/crypt.c | 33 +++----------------------- ext/standard/tests/strings/crypt.phpt | 12 ++++++---- 5 files changed, 16 insertions(+), 38 deletions(-) diff --git a/UPGRADING b/UPGRADING index d18bc98eeb0e5..0621d8eadee41 100644 --- a/UPGRADING +++ b/UPGRADING @@ -576,6 +576,9 @@ PHP 8.0 UPGRADE NOTES $ctx = stream_context_create(['http' => ['protocol_version' => '1.0']]); echo file_get_contents('http://example.org', false, $ctx); + . Calling crypt() without an explicit salt is no longer supported. If you + would like to produce a strong hash with an auto-generated salt, use + password_hash() instead. - Sysvmsg: . msg_get_queue() will now return an SysvMessageQueue object rather than a diff --git a/ext/standard/basic_functions.stub.php b/ext/standard/basic_functions.stub.php index 75819c7fb556b..44eb05a015f59 100755 --- a/ext/standard/basic_functions.stub.php +++ b/ext/standard/basic_functions.stub.php @@ -391,7 +391,7 @@ function crc32(string $str): int {} /* crypt.c */ -function crypt(string $str, string $salt = UNKNOWN): string {} +function crypt(string $str, string $salt): string {} /* datetime.c */ diff --git a/ext/standard/basic_functions_arginfo.h b/ext/standard/basic_functions_arginfo.h index 9d13b25b855bd..ef031e7afb733 100755 --- a/ext/standard/basic_functions_arginfo.h +++ b/ext/standard/basic_functions_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 010a6e0dee6d5e419e66eeefadd4dfabbbddfaca */ + * Stub hash: 28da5d6df91403aad82b5872453053dc41076a6a */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_set_time_limit, 0, 1, _IS_BOOL, 0) ZEND_ARG_TYPE_INFO(0, seconds, IS_LONG, 0) @@ -597,7 +597,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_crc32, 0, 1, IS_LONG, 0) ZEND_ARG_TYPE_INFO(0, str, IS_STRING, 0) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_crypt, 0, 1, IS_STRING, 0) +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_crypt, 0, 2, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, str, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, salt, IS_STRING, 0) ZEND_END_ARG_INFO() diff --git a/ext/standard/crypt.c b/ext/standard/crypt.c index f994ff4c31350..8c105cf910e85 100644 --- a/ext/standard/crypt.c +++ b/ext/standard/crypt.c @@ -79,18 +79,6 @@ PHP_MSHUTDOWN_FUNCTION(crypt) /* {{{ */ } /* }}} */ -static unsigned char itoa64[] = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; - -/* Encode a string of bytes as Base64 */ -static void php_to64(char *s, int n) /* {{{ */ -{ - while (--n >= 0) { - *s = itoa64[*s & 0x3f]; - s++; - } -} -/* }}} */ - PHPAPI zend_string *php_crypt(const char *password, const int pass_len, const char *salt, int salt_len, zend_bool quiet) { char *crypt_res; @@ -216,9 +204,8 @@ PHP_FUNCTION(crypt) size_t str_len, salt_in_len = 0; zend_string *result; - ZEND_PARSE_PARAMETERS_START(1, 2) + ZEND_PARSE_PARAMETERS_START(2, 2) Z_PARAM_STRING(str, str_len) - Z_PARAM_OPTIONAL Z_PARAM_STRING(salt_in, salt_in_len) ZEND_PARSE_PARAMETERS_END(); @@ -227,23 +214,9 @@ PHP_FUNCTION(crypt) /* This will produce suitable results if people depend on DES-encryption * available (passing always 2-character salt). At least for glibc6.1 */ memset(&salt[1], '$', PHP_MAX_SALT_LEN - 1); + memcpy(salt, salt_in, MIN(PHP_MAX_SALT_LEN, salt_in_len)); - if (salt_in) { - memcpy(salt, salt_in, MIN(PHP_MAX_SALT_LEN, salt_in_len)); - } else { - php_error_docref(NULL, E_NOTICE, "No salt parameter was specified. You must use a randomly generated salt and a strong hash function to produce a secure hash."); - } - - /* The automatic salt generation covers standard DES, md5-crypt and Blowfish (simple) */ - if (!*salt) { - memcpy(salt, "$1$", 3); - php_random_bytes_throw(&salt[3], 8); - php_to64(&salt[3], 8); - strncpy(&salt[11], "$", PHP_MAX_SALT_LEN - 11); - salt_in_len = strlen(salt); - } else { - salt_in_len = MIN(PHP_MAX_SALT_LEN, salt_in_len); - } + salt_in_len = MIN(PHP_MAX_SALT_LEN, salt_in_len); salt[salt_in_len] = '\0'; if ((result = php_crypt(str, (int)str_len, salt, (int)salt_in_len, 0)) == NULL) { diff --git a/ext/standard/tests/strings/crypt.phpt b/ext/standard/tests/strings/crypt.phpt index 270f0372d13fd..462aea8b59749 100644 --- a/ext/standard/tests/strings/crypt.phpt +++ b/ext/standard/tests/strings/crypt.phpt @@ -18,14 +18,16 @@ echo (CRYPT_EXT_DES) ? ((crypt($str, $salt2) === $res_2) ? 'EXT' : 'EXT - ERROR echo (CRYPT_MD5) ? ((crypt($str, $salt3) === $res_3) ? 'MD5' : 'MD5 - ERROR') : 'MD5', "\n"; echo (CRYPT_BLOWFISH) ? ((crypt($str, $salt4) === $res_4) ? 'BLO' : 'BLO - ERROR') : 'BLO', "\n"; -var_dump(crypt($str)); +try { + var_dump(crypt($str)); +} catch (ArgumentCountError $e) { + echo $e->getMessage(), "\n"; +} ?> ---EXPECTF-- +--EXPECT-- STD EXT MD5 BLO - -Notice: crypt(): No salt parameter was specified. You must use a randomly generated salt and a strong hash function to produce a secure hash. in %s on line %d -string(%d) "%s" +crypt() expects exactly 2 parameters, 1 given From 2a334f165541e6f1efa5a9c7e927e689f4c47f3f Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Mon, 7 Sep 2020 16:15:44 +0200 Subject: [PATCH 80/87] Don't leave behind temporary file in bug70362.phpt --- ext/standard/tests/streams/bug70362.phpt | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/ext/standard/tests/streams/bug70362.phpt b/ext/standard/tests/streams/bug70362.phpt index 3fbc3fea16e8f..fa05ecdef544a 100644 --- a/ext/standard/tests/streams/bug70362.phpt +++ b/ext/standard/tests/streams/bug70362.phpt @@ -4,11 +4,16 @@ Bug #70362 (Can't copy() large 'data://' with open_basedir) open_basedir=. --FILE-- +--CLEAN-- + --EXPECT-- bool(true) From 2c96780e1c10c3c851608835411e21879a069199 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1t=C3=A9=20Kocsis?= Date: Fri, 21 Aug 2020 00:42:44 +0200 Subject: [PATCH 81/87] Fix UNKNOWN default values in ext/standard Closes GH-6026 --- ext/bz2/bz2.stub.php | 2 +- ext/bz2/bz2_arginfo.h | 4 +- ext/standard/basic_functions.c | 18 ++- ext/standard/basic_functions.stub.php | 103 +++++++++--------- ext/standard/basic_functions_arginfo.h | 74 ++++++------- ext/standard/dir.c | 8 +- ext/standard/dir.stub.php | 12 +- ext/standard/dir_arginfo.h | 4 +- ext/standard/file.c | 26 +++-- ext/standard/filestat.c | 33 +++--- ext/standard/fsock.c | 13 ++- ext/standard/head.c | 4 +- ext/standard/html.c | 2 +- ext/standard/info.c | 2 +- ext/standard/streamsfuncs.c | 49 ++++++--- ext/standard/string.c | 86 +++++++-------- .../directory/DirectoryClass_basic_001.phpt | 6 +- ext/standard/tests/file/touch.phpt | 7 ++ .../stream_get_contents_negative_length.phpt | 2 +- ext/standard/tests/strings/implode1.phpt | Bin 6036 -> 6041 bytes .../tests/strings/join_variation2.phpt | 46 ++++---- .../tests/strings/strip_tags_variation2.phpt | 8 +- ext/standard/versioning.c | 2 +- ext/zlib/zlib.stub.php | 4 +- ext/zlib/zlib_arginfo.h | 4 +- 25 files changed, 270 insertions(+), 249 deletions(-) diff --git a/ext/bz2/bz2.stub.php b/ext/bz2/bz2.stub.php index 2d47c045013bb..1f8b011059967 100644 --- a/ext/bz2/bz2.stub.php +++ b/ext/bz2/bz2.stub.php @@ -15,7 +15,7 @@ function bzread($bz, int $length = 1024): string|false {} * @param resource $bz * @alias fwrite */ -function bzwrite($bz, string $str, int $length = UNKNOWN): int|false {} +function bzwrite($bz, string $str, ?int $length = null): int|false {} /** * @param resource $bz diff --git a/ext/bz2/bz2_arginfo.h b/ext/bz2/bz2_arginfo.h index 322aaf7215cc6..902553002edc6 100644 --- a/ext/bz2/bz2_arginfo.h +++ b/ext/bz2/bz2_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: a5c534b7cd92619dfa0fdf29bd0a94fcda27f089 */ + * Stub hash: 9bcd75ddbde225e65ee9f00d86d16677d671b4e4 */ ZEND_BEGIN_ARG_INFO_EX(arginfo_bzopen, 0, 0, 2) ZEND_ARG_INFO(0, file) @@ -14,7 +14,7 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_bzwrite, 0, 2, MAY_BE_LONG|MAY_BE_FALSE) ZEND_ARG_INFO(0, bz) ZEND_ARG_TYPE_INFO(0, str, IS_STRING, 0) - ZEND_ARG_TYPE_INFO(0, length, IS_LONG, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, length, IS_LONG, 1, "null") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_bzflush, 0, 1, _IS_BOOL, 0) diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c index 6ff4c3d573f34..922bcab330baa 100755 --- a/ext/standard/basic_functions.c +++ b/ext/standard/basic_functions.c @@ -739,7 +739,7 @@ PHP_FUNCTION(getenv) ZEND_PARSE_PARAMETERS_START(0, 2) Z_PARAM_OPTIONAL - Z_PARAM_STRING(str, str_len) + Z_PARAM_STRING_OR_NULL(str, str_len) Z_PARAM_BOOL(local_only) ZEND_PARSE_PARAMETERS_END(); @@ -1429,22 +1429,17 @@ PHP_FUNCTION(error_log) { char *message, *opt = NULL, *headers = NULL; size_t message_len, opt_len = 0, headers_len = 0; - int opt_err = 0, argc = ZEND_NUM_ARGS(); zend_long erropt = 0; ZEND_PARSE_PARAMETERS_START(1, 4) Z_PARAM_STRING(message, message_len) Z_PARAM_OPTIONAL Z_PARAM_LONG(erropt) - Z_PARAM_PATH(opt, opt_len) - Z_PARAM_STRING(headers, headers_len) + Z_PARAM_PATH_OR_NULL(opt, opt_len) + Z_PARAM_STRING_OR_NULL(headers, headers_len) ZEND_PARSE_PARAMETERS_END(); - if (argc > 1) { - opt_err = (int)erropt; - } - - if (_php_error_log_ex(opt_err, message, message_len, opt, headers) == FAILURE) { + if (_php_error_log_ex((int) erropt, message, message_len, opt, headers) == FAILURE) { RETURN_FALSE; } @@ -2270,16 +2265,17 @@ PHP_FUNCTION(connection_status) PHP_FUNCTION(ignore_user_abort) { zend_bool arg = 0; + zend_bool arg_is_null = 1; int old_setting; ZEND_PARSE_PARAMETERS_START(0, 1) Z_PARAM_OPTIONAL - Z_PARAM_BOOL(arg) + Z_PARAM_BOOL_OR_NULL(arg, arg_is_null) ZEND_PARSE_PARAMETERS_END(); old_setting = (unsigned short)PG(ignore_user_abort); - if (ZEND_NUM_ARGS()) { + if (!arg_is_null) { zend_string *key = zend_string_init("ignore_user_abort", sizeof("ignore_user_abort") - 1, 0); zend_alter_ini_entry_chars(key, arg ? "1" : "0", 1, PHP_INI_USER, PHP_INI_STAGE_RUNTIME); zend_string_release_ex(key, 0); diff --git a/ext/standard/basic_functions.stub.php b/ext/standard/basic_functions.stub.php index 44eb05a015f59..9352b9712c148 100755 --- a/ext/standard/basic_functions.stub.php +++ b/ext/standard/basic_functions.stub.php @@ -271,7 +271,7 @@ function ip2long(string $ip_address): int|false {} function long2ip(int $proper_address): string|false {} -function getenv(string $variable = UNKNOWN, bool $local_only = false): string|array|false {} +function getenv(?string $variable = null, bool $local_only = false): string|array|false {} #ifdef HAVE_PUTENV function putenv(string $setting): bool {} @@ -296,7 +296,7 @@ function get_current_user(): string {} function get_cfg_var(string $option_name): string|array|false {} -function error_log(string $message, int $message_type = 0, string $destination = UNKNOWN, string $extra_headers = UNKNOWN): bool {} +function error_log(string $message, int $message_type = 0, ?string $destination = null, ?string $extra_headers = null): bool {} function error_get_last(): ?array {} @@ -343,7 +343,7 @@ function connection_aborted(): int {} function connection_status(): int {} -function ignore_user_abort(bool $value = UNKNOWN): int {} +function ignore_user_abort(?bool $value = null): int {} #if HAVE_GETSERVBYNAME function getservbyname(string $service, string $protocol): int|false {} @@ -504,7 +504,7 @@ function metaphone(string $text, int $phones = 0): string|false {} /* {{{ head.c */ function header(string $string, bool $replace = true, int $http_response_code = 0): void {} -function header_remove(string $name = UNKNOWN): void {} +function header_remove(?string $name = null): void {} /** @param array|int $expires_or_options */ function setrawcookie(string $name, string $value = '', $expires_or_options = 0, string $path = '', string $domain = '', bool $secure = false, bool $httponly = false): bool {} @@ -528,7 +528,7 @@ function htmlspecialchars(string $string, int $quote_style = ENT_COMPAT, ?string function htmlspecialchars_decode(string $string, int $quote_style = ENT_COMPAT): string|false {} -function html_entity_decode(string $string, int $quote_style = ENT_COMPAT, string $encoding = UNKNOWN): string|false {} +function html_entity_decode(string $string, int $quote_style = ENT_COMPAT, ?string $encoding = null): string|false {} function htmlentities(string $string, int $quote_style = ENT_COMPAT, ?string $encoding = null, bool $double_encode = true): string {} @@ -549,9 +549,9 @@ function bin2hex(string $data): string {} function hex2bin(string $data): string|false {} -function strspn(string $str, string $mask, int $start = 0, int $len = UNKNOWN): int|false {} +function strspn(string $str, string $mask, int $start = 0, ?int $len = null): int|false {} -function strcspn(string $str, string $mask, int $start = 0, int $len = UNKNOWN): int|false {} +function strcspn(string $str, string $mask, int $start = 0, ?int $len = null): int|false {} #if HAVE_NL_LANGINFO function nl_langinfo(int $item): string|false {} @@ -572,12 +572,12 @@ function wordwrap(string $str, int $width = 75, string $break = "\n", bool $cut function explode(string $separator, string $str, int $limit = PHP_INT_MAX): array {} -function implode(string|array $glue, array $pieces = UNKNOWN): string {} +function implode(string|array $glue, ?array $pieces = null): string {} /** @alias implode */ -function join(string|array $glue, array $pieces = UNKNOWN): string {} +function join(string|array $glue, ?array $pieces = null): string {} -function strtok(string $str, string $token = UNKNOWN): string|false {} +function strtok(string $str, ?string $token = null): string|false {} function strtoupper(string $str): string {} @@ -587,7 +587,7 @@ function basename(string $path, string $suffix = ""): string {} function dirname(string $path, int $levels = 1): string {} -function pathinfo(string $path, int $options = UNKNOWN): array|string {} +function pathinfo(string $path, int $options = PATHINFO_ALL): array|string {} function stristr(string $haystack, string $needle, bool $before_needle = false): string|false {} @@ -617,10 +617,10 @@ function chunk_split(string $str, int $chunklen = 76, string $ending = "\r\n"): function substr(string $str, int $start, ?int $length = null): string|false {} /** - * @param mixed $start - * @param mixed $length + * @param array|int $start + * @param array|int|null $length */ -function substr_replace(array|string $str, string|array $replace, $start, $length = UNKNOWN): string|array|false {} +function substr_replace(array|string $str, string|array $replace, $start, $length = null): string|array|false {} function quotemeta(string $str): string {} @@ -634,7 +634,7 @@ function lcfirst(string $str): string {} function ucwords(string $str, string $delimiters = " \t\r\n\f\v"): string {} -function strtr(string $str, string|array $from, string $to = UNKNOWN): string {} +function strtr(string $str, string|array $from, ?string $to = null): string {} function strrev(string $str): string {} @@ -650,17 +650,16 @@ function stripcslashes(string $str): string {} function stripslashes(string $str): string {} /** @param int $replace_count */ -function str_replace(array|string $search, array|string $replace, string|array $subject, &$replace_count = UNKNOWN): string|array {} +function str_replace(array|string $search, array|string $replace, string|array $subject, &$replace_count = null): string|array {} /** @param int $replace_count */ -function str_ireplace(array|string $search, array|string $replace, string|array $subject, &$replace_count = UNKNOWN): string|array {} +function str_ireplace(array|string $search, array|string $replace, string|array $subject, &$replace_count = null): string|array {} function hebrev(string $str, int $max_chars_per_line = 0): string {} function nl2br(string $str, bool $is_xhtml = true): string {} -/** @param array|string|null $allowable_tags */ -function strip_tags(string $str, $allowable_tags = UNKNOWN): string {} +function strip_tags(string $str, array|string|null $allowable_tags = null): string {} /** * @param array|string $locales @@ -693,7 +692,7 @@ function str_rot13(string $str): string {} function str_shuffle(string $str): string {} -function str_word_count(string $str, int $format = 0, string $charlist = UNKNOWN): array|int {} +function str_word_count(string $str, int $format = 0, ?string $charlist = null): array|int {} function str_split(string $str, int $split_length = 1): array {} @@ -706,22 +705,22 @@ function utf8_encode(string $data): string {} function utf8_decode(string $data): string {} /** - * @param resource $context + * @param resource|null $context * @return resource|false */ -function opendir(string $path, $context = UNKNOWN) {} +function opendir(string $path, $context = null) {} /** @param resource $context */ -function getdir(string $path, $context = UNKNOWN): Directory|false {} +function getdir(string $path, $context = null): Directory|false {} /** - * @param resource $context + * @param resource|null $context * @alias getdir */ -function dir(string $path, $context = UNKNOWN): Directory|false {} +function dir(string $path, $context = null): Directory|false {} -/** @param resource $dir_handle */ -function closedir($dir_handle = UNKNOWN): void {} +/** @param resource|null $dir_handle */ +function closedir($dir_handle = null): void {} function chdir(string $directory): bool {} @@ -731,14 +730,14 @@ function chroot(string $directory): bool {} function getcwd(): string|false {} -/** @param resource $dir_handle */ -function rewinddir($dir_handle = UNKNOWN): void {} +/** @param resource|null $dir_handle */ +function rewinddir($dir_handle = null): void {} -/** @param resource $dir_handle */ -function readdir($dir_handle = UNKNOWN): string|false {} +/** @param resource|null $dir_handle */ +function readdir($dir_handle = null): string|false {} -/** @param resource $context */ -function scandir(string $directory, int $sorting_order = 0, $context = UNKNOWN): array|false {} +/** @param resource|null $context */ +function scandir(string $directory, int $sorting_order = 0, $context = null): array|false {} #ifdef HAVE_GLOB function glob(string $pattern, int $flags = 0): array|false {} @@ -793,7 +792,7 @@ function rewind($handle): bool {} /** @param resource|null $context */ function rmdir(string $dirname, $context = null): bool {} -function umask(int $mask = UNKNOWN): int {} +function umask(?int $mask = null): int {} /** @param resource $handle */ function fclose($handle): bool {} @@ -805,7 +804,7 @@ function feof($handle): bool {} function fgetc($handle): string|false {} /** @param resource $handle */ -function fgets($handle, int $length = UNKNOWN): string|false {} +function fgets($handle, ?int $length = null): string|false {} /** @param resource $handle */ function fread($handle, int $length): string|false {} @@ -838,13 +837,13 @@ function ftell($handle): int|false {} function fflush($handle): bool {} /** @param resource $handle */ -function fwrite($handle, string $content, int $max_length = UNKNOWN): int|false {} +function fwrite($handle, string $content, ?int $max_length = null): int|false {} /** * @param resource $handle * @alias fwrite */ -function fputs($handle, string $content, int $max_length = UNKNOWN): int|false {} +function fputs($handle, string $content, ?int $max_length = null): int|false {} /** @param resource|null $context */ function mkdir(string $pathname, int $mode = 0777, bool $recursive = false, $context = null): bool {} @@ -940,7 +939,7 @@ function lchgrp(string $filename, string|int $group): bool {} function chmod(string $filename, int $mode): bool {} #if HAVE_UTIME -function touch(string $filename, int $time = UNKNOWN, int $atime = UNKNOWN): bool {} +function touch(string $filename, ?int $time = null, ?int $atime = null): bool {} #endif function clearstatcache(bool $clear_realpath_cache = false, string $filename = ""): void {} @@ -979,14 +978,14 @@ function vfprintf($handle, string $format, array $args): int {} * @param string $errstr * @return resource|false */ -function fsockopen(string $hostname, int $port = -1, &$errno = null, &$errstr = null, float $timeout = UNKNOWN) {} +function fsockopen(string $hostname, int $port = -1, &$errno = null, &$errstr = null, ?float $timeout = null) {} /** * @param int $errno * @param string $errstr * @return resource|false */ -function pfsockopen(string $hostname, int $port = -1, &$errno = null, &$errstr = null, float $timeout = UNKNOWN) {} +function pfsockopen(string $hostname, int $port = -1, &$errno = null, &$errstr = null, ?float $timeout = null) {} /* http.c */ @@ -1008,7 +1007,7 @@ function getimagesizefromstring(string $image, &$image_info = null): array|false function phpinfo(int $what = INFO_ALL): bool {} -function phpversion(string $extension = UNKNOWN): string|false {} +function phpversion(?string $extension = null): string|false {} function phpcredits(int $flag = CREDITS_ALL): bool {} @@ -1044,7 +1043,7 @@ function link(string $target, string $link): bool {} /* mail.c */ -function mail(string $to, string $subject, string $message, string|array $additional_headers = UNKNOWN, string $additional_parameters = ""): bool {} +function mail(string $to, string $subject, string $message, array|string $additional_headers = [], string $additional_parameters = ""): bool {} /* math.c */ @@ -1233,24 +1232,22 @@ function stream_context_set_option($context, array|string $wrapper_or_options, ? function stream_context_get_options($stream_or_context): array {} /** @return resource */ -function stream_context_get_default(array $options = UNKNOWN) {} +function stream_context_get_default(?array $options = null) {} /** @return resource */ function stream_context_set_default(array $options) {} /** * @param resource $stream - * @param mixed $params * @return resource|false */ -function stream_filter_prepend($stream, string $filtername, int $read_write = 0, $params = UNKNOWN) {} +function stream_filter_prepend($stream, string $filtername, int $read_write = 0, mixed $params = UNKNOWN) {} /** * @param resource $stream - * @param mixed $params * @return resource|false */ -function stream_filter_append($stream, string $filtername, int $read_write = 0, $params = UNKNOWN) {} +function stream_filter_append($stream, string $filtername, int $read_write = 0, mixed $params = UNKNOWN) {} /** @param resource $stream_filter */ function stream_filter_remove($stream_filter): bool {} @@ -1261,7 +1258,7 @@ function stream_filter_remove($stream_filter): bool {} * @param resource|null $context * @return resource|false */ -function stream_socket_client(string $remote_socket, &$errno = null, &$errstr = null, float $timeout = UNKNOWN, int $flags = STREAM_CLIENT_CONNECT, $context = null) {} +function stream_socket_client(string $remote_socket, &$errno = null, &$errstr = null, ?float $timeout = null, int $flags = STREAM_CLIENT_CONNECT, $context = null) {} /** * @param int $errno @@ -1277,7 +1274,7 @@ function stream_socket_server(string $local_socket, &$errno = null, &$errstr = n * @param string $peername * @return resource|false */ -function stream_socket_accept($server_socket, float $timeout = UNKNOWN, &$peername = null) {} +function stream_socket_accept($server_socket, ?float $timeout = null, &$peername = null) {} /** @param resource $handle */ function stream_socket_get_name($handle, bool $want_peer): string|false {} @@ -1310,10 +1307,10 @@ function stream_socket_pair(int $domain, int $type, int $protocol): array|false * @param resource $source * @param resource $dest */ -function stream_copy_to_stream($source, $dest, int $maxlength = UNKNOWN, int $position = 0): int|false {} +function stream_copy_to_stream($source, $dest, ?int $maxlength = null, int $position = 0): int|false {} /** @param resource $handle */ -function stream_get_contents($handle, int $maxlength = UNKNOWN, int $position = -1): string|false {} +function stream_get_contents($handle, ?int $maxlength = null, int $position = -1): string|false {} /** @param resource $stream */ function stream_supports_lock($stream): bool {} @@ -1498,14 +1495,14 @@ function memory_get_peak_usage(bool $real_usage = false): int {} /* versioning.c */ -function version_compare(string $version1, string $version2, string $operator = UNKNOWN): int|bool {} +function version_compare(string $version1, string $version2, ?string $operator = null): int|bool {} /* win32/codepage.c */ #ifdef PHP_WIN32 function sapi_windows_cp_set(int $cp): bool {} -function sapi_windows_cp_get(string $kind = UNKNOWN): int {} +function sapi_windows_cp_get(string $kind = ""): int {} function sapi_windows_cp_conv(int|string $in_codepage, int|string $out_codepage, string $subject): ?string {} diff --git a/ext/standard/basic_functions_arginfo.h b/ext/standard/basic_functions_arginfo.h index ef031e7afb733..61a92dc185208 100755 --- a/ext/standard/basic_functions_arginfo.h +++ b/ext/standard/basic_functions_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 28da5d6df91403aad82b5872453053dc41076a6a */ + * Stub hash: c51ad7a5f254f8d28f2b2c0b46e214c44f0f96cf */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_set_time_limit, 0, 1, _IS_BOOL, 0) ZEND_ARG_TYPE_INFO(0, seconds, IS_LONG, 0) @@ -389,7 +389,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_long2ip, 0, 1, MAY_BE_STRING|MAY ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_getenv, 0, 0, MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_FALSE) - ZEND_ARG_TYPE_INFO(0, variable, IS_STRING, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, variable, IS_STRING, 1, "null") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, local_only, _IS_BOOL, 0, "false") ZEND_END_ARG_INFO() @@ -439,8 +439,8 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_error_log, 0, 1, _IS_BOOL, 0) ZEND_ARG_TYPE_INFO(0, message, IS_STRING, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, message_type, IS_LONG, 0, "0") - ZEND_ARG_TYPE_INFO(0, destination, IS_STRING, 0) - ZEND_ARG_TYPE_INFO(0, extra_headers, IS_STRING, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, destination, IS_STRING, 1, "null") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, extra_headers, IS_STRING, 1, "null") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_error_get_last, 0, 0, IS_ARRAY, 1) @@ -519,7 +519,7 @@ ZEND_END_ARG_INFO() #define arginfo_connection_status arginfo_ob_get_level ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_ignore_user_abort, 0, 0, IS_LONG, 0) - ZEND_ARG_TYPE_INFO(0, value, _IS_BOOL, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, value, _IS_BOOL, 1, "null") ZEND_END_ARG_INFO() #if HAVE_GETSERVBYNAME @@ -744,7 +744,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_header, 0, 1, IS_VOID, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_header_remove, 0, 0, IS_VOID, 0) - ZEND_ARG_TYPE_INFO(0, name, IS_STRING, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, name, IS_STRING, 1, "null") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_setrawcookie, 0, 1, _IS_BOOL, 0) @@ -785,7 +785,7 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_html_entity_decode, 0, 1, MAY_BE_STRING|MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(0, string, IS_STRING, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, quote_style, IS_LONG, 0, "ENT_COMPAT") - ZEND_ARG_TYPE_INFO(0, encoding, IS_STRING, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, encoding, IS_STRING, 1, "null") ZEND_END_ARG_INFO() #define arginfo_htmlentities arginfo_htmlspecialchars @@ -818,7 +818,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_strspn, 0, 2, MAY_BE_LONG|MAY_BE ZEND_ARG_TYPE_INFO(0, str, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, mask, IS_STRING, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, start, IS_LONG, 0, "0") - ZEND_ARG_TYPE_INFO(0, len, IS_LONG, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, len, IS_LONG, 1, "null") ZEND_END_ARG_INFO() #define arginfo_strcspn arginfo_strspn @@ -860,14 +860,14 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_implode, 0, 1, IS_STRING, 0) ZEND_ARG_TYPE_MASK(0, glue, MAY_BE_STRING|MAY_BE_ARRAY, NULL) - ZEND_ARG_TYPE_INFO(0, pieces, IS_ARRAY, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, pieces, IS_ARRAY, 1, "null") ZEND_END_ARG_INFO() #define arginfo_join arginfo_implode ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_strtok, 0, 1, MAY_BE_STRING|MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(0, str, IS_STRING, 0) - ZEND_ARG_TYPE_INFO(0, token, IS_STRING, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, token, IS_STRING, 1, "null") ZEND_END_ARG_INFO() #define arginfo_strtoupper arginfo_base64_encode @@ -886,7 +886,7 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pathinfo, 0, 1, MAY_BE_ARRAY|MAY_BE_STRING) ZEND_ARG_TYPE_INFO(0, path, IS_STRING, 0) - ZEND_ARG_TYPE_INFO(0, options, IS_LONG, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, options, IS_LONG, 0, "PATHINFO_ALL") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_stristr, 0, 2, MAY_BE_STRING|MAY_BE_FALSE) @@ -941,7 +941,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_substr_replace, 0, 3, MAY_BE_STR ZEND_ARG_TYPE_MASK(0, str, MAY_BE_ARRAY|MAY_BE_STRING, NULL) ZEND_ARG_TYPE_MASK(0, replace, MAY_BE_STRING|MAY_BE_ARRAY, NULL) ZEND_ARG_INFO(0, start) - ZEND_ARG_INFO(0, length) + ZEND_ARG_INFO_WITH_DEFAULT_VALUE(0, length, "null") ZEND_END_ARG_INFO() #define arginfo_quotemeta arginfo_base64_encode @@ -966,7 +966,7 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_strtr, 0, 2, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, str, IS_STRING, 0) ZEND_ARG_TYPE_MASK(0, from, MAY_BE_STRING|MAY_BE_ARRAY, NULL) - ZEND_ARG_TYPE_INFO(0, to, IS_STRING, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, to, IS_STRING, 1, "null") ZEND_END_ARG_INFO() #define arginfo_strrev arginfo_base64_encode @@ -992,7 +992,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_str_replace, 0, 3, MAY_BE_STRING ZEND_ARG_TYPE_MASK(0, search, MAY_BE_ARRAY|MAY_BE_STRING, NULL) ZEND_ARG_TYPE_MASK(0, replace, MAY_BE_ARRAY|MAY_BE_STRING, NULL) ZEND_ARG_TYPE_MASK(0, subject, MAY_BE_STRING|MAY_BE_ARRAY, NULL) - ZEND_ARG_INFO(1, replace_count) + ZEND_ARG_INFO_WITH_DEFAULT_VALUE(1, replace_count, "null") ZEND_END_ARG_INFO() #define arginfo_str_ireplace arginfo_str_replace @@ -1009,7 +1009,7 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_strip_tags, 0, 1, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, str, IS_STRING, 0) - ZEND_ARG_INFO(0, allowable_tags) + ZEND_ARG_TYPE_MASK(0, allowable_tags, MAY_BE_ARRAY|MAY_BE_STRING|MAY_BE_NULL, "null") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_setlocale, 0, 2, MAY_BE_STRING|MAY_BE_FALSE) @@ -1076,7 +1076,7 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_str_word_count, 0, 1, MAY_BE_ARRAY|MAY_BE_LONG) ZEND_ARG_TYPE_INFO(0, str, IS_STRING, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, format, IS_LONG, 0, "0") - ZEND_ARG_TYPE_INFO(0, charlist, IS_STRING, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, charlist, IS_STRING, 1, "null") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_str_split, 0, 1, IS_ARRAY, 0) @@ -1103,18 +1103,18 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_opendir, 0, 0, 1) ZEND_ARG_TYPE_INFO(0, path, IS_STRING, 0) - ZEND_ARG_INFO(0, context) + ZEND_ARG_INFO_WITH_DEFAULT_VALUE(0, context, "null") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_getdir, 0, 1, Directory, MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(0, path, IS_STRING, 0) - ZEND_ARG_INFO(0, context) + ZEND_ARG_INFO_WITH_DEFAULT_VALUE(0, context, "null") ZEND_END_ARG_INFO() #define arginfo_dir arginfo_getdir ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_closedir, 0, 0, IS_VOID, 0) - ZEND_ARG_INFO(0, dir_handle) + ZEND_ARG_INFO_WITH_DEFAULT_VALUE(0, dir_handle, "null") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_chdir, 0, 1, _IS_BOOL, 0) @@ -1132,13 +1132,13 @@ ZEND_END_ARG_INFO() #define arginfo_rewinddir arginfo_closedir ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_readdir, 0, 0, MAY_BE_STRING|MAY_BE_FALSE) - ZEND_ARG_INFO(0, dir_handle) + ZEND_ARG_INFO_WITH_DEFAULT_VALUE(0, dir_handle, "null") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_scandir, 0, 1, MAY_BE_ARRAY|MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(0, directory, IS_STRING, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, sorting_order, IS_LONG, 0, "0") - ZEND_ARG_INFO(0, context) + ZEND_ARG_INFO_WITH_DEFAULT_VALUE(0, context, "null") ZEND_END_ARG_INFO() #if defined(HAVE_GLOB) @@ -1218,7 +1218,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_rmdir, 0, 1, _IS_BOOL, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_umask, 0, 0, IS_LONG, 0) - ZEND_ARG_TYPE_INFO(0, mask, IS_LONG, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, mask, IS_LONG, 1, "null") ZEND_END_ARG_INFO() #define arginfo_fclose arginfo_rewind @@ -1231,7 +1231,7 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_fgets, 0, 1, MAY_BE_STRING|MAY_BE_FALSE) ZEND_ARG_INFO(0, handle) - ZEND_ARG_TYPE_INFO(0, length, IS_LONG, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, length, IS_LONG, 1, "null") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_fread, 0, 2, MAY_BE_STRING|MAY_BE_FALSE) @@ -1278,7 +1278,7 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_fwrite, 0, 2, MAY_BE_LONG|MAY_BE_FALSE) ZEND_ARG_INFO(0, handle) ZEND_ARG_TYPE_INFO(0, content, IS_STRING, 0) - ZEND_ARG_TYPE_INFO(0, max_length, IS_LONG, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, max_length, IS_LONG, 1, "null") ZEND_END_ARG_INFO() #define arginfo_fputs arginfo_fwrite @@ -1444,8 +1444,8 @@ ZEND_END_ARG_INFO() #if HAVE_UTIME ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_touch, 0, 1, _IS_BOOL, 0) ZEND_ARG_TYPE_INFO(0, filename, IS_STRING, 0) - ZEND_ARG_TYPE_INFO(0, time, IS_LONG, 0) - ZEND_ARG_TYPE_INFO(0, atime, IS_LONG, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, time, IS_LONG, 1, "null") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, atime, IS_LONG, 1, "null") ZEND_END_ARG_INFO() #endif @@ -1503,7 +1503,7 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_fsockopen, 0, 0, 1) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, port, IS_LONG, 0, "-1") ZEND_ARG_INFO_WITH_DEFAULT_VALUE(1, errno, "null") ZEND_ARG_INFO_WITH_DEFAULT_VALUE(1, errstr, "null") - ZEND_ARG_TYPE_INFO(0, timeout, IS_DOUBLE, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, timeout, IS_DOUBLE, 1, "null") ZEND_END_ARG_INFO() #define arginfo_pfsockopen arginfo_fsockopen @@ -1539,7 +1539,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_phpinfo, 0, 0, _IS_BOOL, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_phpversion, 0, 0, MAY_BE_STRING|MAY_BE_FALSE) - ZEND_ARG_TYPE_INFO(0, extension, IS_STRING, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, extension, IS_STRING, 1, "null") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_phpcredits, 0, 0, _IS_BOOL, 0) @@ -1601,7 +1601,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_mail, 0, 3, _IS_BOOL, 0) ZEND_ARG_TYPE_INFO(0, to, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, subject, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, message, IS_STRING, 0) - ZEND_ARG_TYPE_MASK(0, additional_headers, MAY_BE_STRING|MAY_BE_ARRAY, NULL) + ZEND_ARG_TYPE_MASK(0, additional_headers, MAY_BE_ARRAY|MAY_BE_STRING, "[]") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, additional_parameters, IS_STRING, 0, "\"\"") ZEND_END_ARG_INFO() @@ -1887,7 +1887,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_stream_context_get_options, 0, 1 ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_stream_context_get_default, 0, 0, 0) - ZEND_ARG_TYPE_INFO(0, options, IS_ARRAY, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, options, IS_ARRAY, 1, "null") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_stream_context_set_default, 0, 0, 1) @@ -1898,7 +1898,7 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_stream_filter_prepend, 0, 0, 2) ZEND_ARG_INFO(0, stream) ZEND_ARG_TYPE_INFO(0, filtername, IS_STRING, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, read_write, IS_LONG, 0, "0") - ZEND_ARG_INFO(0, params) + ZEND_ARG_TYPE_INFO(0, params, IS_MIXED, 0) ZEND_END_ARG_INFO() #define arginfo_stream_filter_append arginfo_stream_filter_prepend @@ -1911,7 +1911,7 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_stream_socket_client, 0, 0, 1) ZEND_ARG_TYPE_INFO(0, remote_socket, IS_STRING, 0) ZEND_ARG_INFO_WITH_DEFAULT_VALUE(1, errno, "null") ZEND_ARG_INFO_WITH_DEFAULT_VALUE(1, errstr, "null") - ZEND_ARG_TYPE_INFO(0, timeout, IS_DOUBLE, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, timeout, IS_DOUBLE, 1, "null") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, flags, IS_LONG, 0, "STREAM_CLIENT_CONNECT") ZEND_ARG_INFO_WITH_DEFAULT_VALUE(0, context, "null") ZEND_END_ARG_INFO() @@ -1926,7 +1926,7 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_stream_socket_accept, 0, 0, 1) ZEND_ARG_INFO(0, server_socket) - ZEND_ARG_TYPE_INFO(0, timeout, IS_DOUBLE, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, timeout, IS_DOUBLE, 1, "null") ZEND_ARG_INFO_WITH_DEFAULT_VALUE(1, peername, "null") ZEND_END_ARG_INFO() @@ -1974,13 +1974,13 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_stream_copy_to_stream, 0, 2, MAY_BE_LONG|MAY_BE_FALSE) ZEND_ARG_INFO(0, source) ZEND_ARG_INFO(0, dest) - ZEND_ARG_TYPE_INFO(0, maxlength, IS_LONG, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, maxlength, IS_LONG, 1, "null") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, position, IS_LONG, 0, "0") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_stream_get_contents, 0, 1, MAY_BE_STRING|MAY_BE_FALSE) ZEND_ARG_INFO(0, handle) - ZEND_ARG_TYPE_INFO(0, maxlength, IS_LONG, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, maxlength, IS_LONG, 1, "null") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, position, IS_LONG, 0, "-1") ZEND_END_ARG_INFO() @@ -2199,7 +2199,7 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_version_compare, 0, 2, MAY_BE_LONG|MAY_BE_BOOL) ZEND_ARG_TYPE_INFO(0, version1, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, version2, IS_STRING, 0) - ZEND_ARG_TYPE_INFO(0, operator, IS_STRING, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, operator, IS_STRING, 1, "null") ZEND_END_ARG_INFO() #if defined(PHP_WIN32) @@ -2210,7 +2210,7 @@ ZEND_END_ARG_INFO() #if defined(PHP_WIN32) ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_sapi_windows_cp_get, 0, 0, IS_LONG, 0) - ZEND_ARG_TYPE_INFO(0, kind, IS_STRING, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, kind, IS_STRING, 0, "\"\"") ZEND_END_ARG_INFO() #endif diff --git a/ext/standard/dir.c b/ext/standard/dir.c index e480c245fee91..98bff12fc2bc3 100644 --- a/ext/standard/dir.c +++ b/ext/standard/dir.c @@ -61,9 +61,9 @@ static zend_class_entry *dir_class_entry_ptr; #define FETCH_DIRP() \ ZEND_PARSE_PARAMETERS_START(0, 1) \ Z_PARAM_OPTIONAL \ - Z_PARAM_RESOURCE(id) \ + Z_PARAM_RESOURCE_OR_NULL(id) \ ZEND_PARSE_PARAMETERS_END(); \ - if (ZEND_NUM_ARGS() == 0) { \ + if (!id) { \ myself = getThis(); \ if (myself) { \ if ((tmp = zend_hash_str_find(Z_OBJPROP_P(myself), "handle", sizeof("handle")-1)) == NULL) { \ @@ -201,7 +201,7 @@ static void _php_do_opendir(INTERNAL_FUNCTION_PARAMETERS, int createobject) ZEND_PARSE_PARAMETERS_START(1, 2) Z_PARAM_PATH(dirname, dir_len) Z_PARAM_OPTIONAL - Z_PARAM_RESOURCE(zcontext) + Z_PARAM_RESOURCE_OR_NULL(zcontext) ZEND_PARSE_PARAMETERS_END(); context = php_stream_context_from_zval(zcontext, 0); @@ -538,7 +538,7 @@ PHP_FUNCTION(scandir) Z_PARAM_PATH(dirn, dirn_len) Z_PARAM_OPTIONAL Z_PARAM_LONG(flags) - Z_PARAM_RESOURCE(zcontext) + Z_PARAM_RESOURCE_OR_NULL(zcontext) ZEND_PARSE_PARAMETERS_END(); if (dirn_len < 1) { diff --git a/ext/standard/dir.stub.php b/ext/standard/dir.stub.php index 39881f759bf73..86d08c1e1de3e 100755 --- a/ext/standard/dir.stub.php +++ b/ext/standard/dir.stub.php @@ -5,23 +5,23 @@ class Directory { /** - * @param resource $dir_handle + * @param resource|null $dir_handle * @return void * @alias closedir */ - public function close($dir_handle = UNKNOWN) {} + public function close($dir_handle = null) {} /** - * @param resource $dir_handle + * @param resource|null $dir_handle * @return void * @alias rewinddir */ - public function rewind($dir_handle = UNKNOWN) {} + public function rewind($dir_handle = null) {} /** - * @param resource $dir_handle + * @param resource|null $dir_handle * @return string|false * @alias readdir */ - public function read($dir_handle = UNKNOWN) {} + public function read($dir_handle = null) {} } diff --git a/ext/standard/dir_arginfo.h b/ext/standard/dir_arginfo.h index 68571fe8be73d..67a22b7249319 100644 --- a/ext/standard/dir_arginfo.h +++ b/ext/standard/dir_arginfo.h @@ -1,8 +1,8 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: ae14c81d7c4642412440f6236b34b7c7c0143911 */ + * Stub hash: 2670287ef059725cceda0a8f9ac6515cdcedb521 */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Directory_close, 0, 0, 0) - ZEND_ARG_INFO(0, dir_handle) + ZEND_ARG_INFO_WITH_DEFAULT_VALUE(0, dir_handle, "null") ZEND_END_ARG_INFO() #define arginfo_class_Directory_rewind arginfo_class_Directory_close diff --git a/ext/standard/file.c b/ext/standard/file.c index 9883973c5dc33..6f29343d9f34c 100644 --- a/ext/standard/file.c +++ b/ext/standard/file.c @@ -1015,8 +1015,8 @@ PHPAPI PHP_FUNCTION(fgets) { zval *res; zend_long len = 1024; + zend_bool len_is_null = 1; char *buf = NULL; - int argc = ZEND_NUM_ARGS(); size_t line_len = 0; zend_string *str; php_stream *stream; @@ -1024,12 +1024,12 @@ PHPAPI PHP_FUNCTION(fgets) ZEND_PARSE_PARAMETERS_START(1, 2) Z_PARAM_RESOURCE(res) Z_PARAM_OPTIONAL - Z_PARAM_LONG(len) + Z_PARAM_LONG_OR_NULL(len, len_is_null) ZEND_PARSE_PARAMETERS_END(); PHP_STREAM_TO_ZVAL(stream, res); - if (argc == 1) { + if (len_is_null) { /* ask streams to give us a buffer of an appropriate size */ buf = php_stream_get_line(stream, NULL, 0, &line_len); if (buf == NULL) { @@ -1038,7 +1038,7 @@ PHPAPI PHP_FUNCTION(fgets) // TODO: avoid reallocation ??? RETVAL_STRINGL(buf, line_len); efree(buf); - } else if (argc > 1) { + } else { if (len <= 0) { zend_argument_value_error(2, "must be greater than 0"); RETURN_THROWS(); @@ -1138,16 +1138,17 @@ PHPAPI PHP_FUNCTION(fwrite) ssize_t ret; size_t num_bytes; zend_long maxlen = 0; + zend_bool maxlen_is_null = 1; php_stream *stream; ZEND_PARSE_PARAMETERS_START(2, 3) Z_PARAM_RESOURCE(res) Z_PARAM_STRING(input, inputlen) Z_PARAM_OPTIONAL - Z_PARAM_LONG(maxlen) + Z_PARAM_LONG_OR_NULL(maxlen, maxlen_is_null) ZEND_PARSE_PARAMETERS_END(); - if (ZEND_NUM_ARGS() == 2) { + if (maxlen_is_null) { num_bytes = inputlen; } else if (maxlen <= 0) { num_bytes = 0; @@ -1354,20 +1355,21 @@ PHP_FUNCTION(readfile) PHP_FUNCTION(umask) { zend_long mask = 0; + zend_bool mask_is_null = 1; int oldumask; + ZEND_PARSE_PARAMETERS_START(0, 1) + Z_PARAM_OPTIONAL + Z_PARAM_LONG_OR_NULL(mask, mask_is_null) + ZEND_PARSE_PARAMETERS_END(); + oldumask = umask(077); if (BG(umask) == -1) { BG(umask) = oldumask; } - ZEND_PARSE_PARAMETERS_START(0, 1) - Z_PARAM_OPTIONAL - Z_PARAM_LONG(mask) - ZEND_PARSE_PARAMETERS_END(); - - if (ZEND_NUM_ARGS() == 0) { + if (mask_is_null) { umask(oldumask); } else { umask((int) mask); diff --git a/ext/standard/filestat.c b/ext/standard/filestat.c index cb0b406a322c8..3e431c744d63f 100644 --- a/ext/standard/filestat.c +++ b/ext/standard/filestat.c @@ -598,7 +598,8 @@ PHP_FUNCTION(touch) char *filename; size_t filename_len; zend_long filetime = 0, fileatime = 0; - int ret, argc = ZEND_NUM_ARGS(); + zend_bool filetime_is_null = 1, fileatime_is_null = 1; + int ret; FILE *file; struct utimbuf newtimebuf; struct utimbuf *newtime = &newtimebuf; @@ -607,28 +608,24 @@ PHP_FUNCTION(touch) ZEND_PARSE_PARAMETERS_START(1, 3) Z_PARAM_PATH(filename, filename_len) Z_PARAM_OPTIONAL - Z_PARAM_LONG(filetime) - Z_PARAM_LONG(fileatime) + Z_PARAM_LONG_OR_NULL(filetime, filetime_is_null) + Z_PARAM_LONG_OR_NULL(fileatime, fileatime_is_null) ZEND_PARSE_PARAMETERS_END(); if (!filename_len) { RETURN_FALSE; } - switch (argc) { - case 1: - newtime = NULL; - break; - case 2: - newtime->modtime = newtime->actime = filetime; - break; - case 3: - newtime->modtime = filetime; - newtime->actime = fileatime; - break; - default: - /* Never reached */ - WRONG_PARAM_COUNT; + if (filetime_is_null && fileatime_is_null) { + newtime = NULL; + } else if (!filetime_is_null && fileatime_is_null) { + newtime->modtime = newtime->actime = filetime; + } else if (filetime_is_null && !fileatime_is_null) { + zend_argument_value_error(2, "cannot be null when argument #3 ($atime) is an integer"); + RETURN_THROWS(); + } else { + newtime->modtime = filetime; + newtime->actime = fileatime; } wrapper = php_stream_locate_url_wrapper(filename, NULL, 0); @@ -641,7 +638,7 @@ PHP_FUNCTION(touch) } } else { php_stream *stream; - if(argc > 1) { + if(!filetime_is_null || !fileatime_is_null) { php_error_docref(NULL, E_WARNING, "Can not call touch() for a non-standard stream"); RETURN_FALSE; } diff --git a/ext/standard/fsock.c b/ext/standard/fsock.c index 6023234cd34f7..a9c3cb0bf5d06 100644 --- a/ext/standard/fsock.c +++ b/ext/standard/fsock.c @@ -31,7 +31,8 @@ static void php_fsockopen_stream(INTERNAL_FUNCTION_PARAMETERS, int persistent) size_t host_len; zend_long port = -1; zval *zerrno = NULL, *zerrstr = NULL; - double timeout = (double)FG(default_socket_timeout); + double timeout; + zend_bool timeout_is_null = 1; #ifndef PHP_WIN32 time_t conv; #else @@ -45,17 +46,21 @@ static void php_fsockopen_stream(INTERNAL_FUNCTION_PARAMETERS, int persistent) size_t hostname_len; zend_string *errstr = NULL; - RETVAL_FALSE; - ZEND_PARSE_PARAMETERS_START(1, 5) Z_PARAM_STRING(host, host_len) Z_PARAM_OPTIONAL Z_PARAM_LONG(port) Z_PARAM_ZVAL(zerrno) Z_PARAM_ZVAL(zerrstr) - Z_PARAM_DOUBLE(timeout) + Z_PARAM_DOUBLE_OR_NULL(timeout, timeout_is_null) ZEND_PARSE_PARAMETERS_END(); + RETVAL_FALSE; + + if (timeout_is_null) { + timeout = (double)FG(default_socket_timeout); + } + if (persistent) { spprintf(&hashkey, 0, "pfsockopen__%s:" ZEND_LONG_FMT, host, port); } diff --git a/ext/standard/head.c b/ext/standard/head.c index ceca0cbbefcff..cbc7e24a45b33 100644 --- a/ext/standard/head.c +++ b/ext/standard/head.c @@ -58,12 +58,12 @@ PHP_FUNCTION(header_remove) ZEND_PARSE_PARAMETERS_START(0, 1) Z_PARAM_OPTIONAL - Z_PARAM_STRING(line, len) + Z_PARAM_STRING_OR_NULL(line, len) ZEND_PARSE_PARAMETERS_END(); ctr.line = line; ctr.line_len = (uint32_t)len; - sapi_header_op(ZEND_NUM_ARGS() == 0 ? SAPI_HEADER_DELETE_ALL : SAPI_HEADER_DELETE, &ctr); + sapi_header_op(line == NULL ? SAPI_HEADER_DELETE_ALL : SAPI_HEADER_DELETE, &ctr); } /* }}} */ diff --git a/ext/standard/html.c b/ext/standard/html.c index 58c2989c85558..dfed889875381 100644 --- a/ext/standard/html.c +++ b/ext/standard/html.c @@ -1395,7 +1395,7 @@ PHP_FUNCTION(html_entity_decode) Z_PARAM_STR(str) Z_PARAM_OPTIONAL Z_PARAM_LONG(quote_style) - Z_PARAM_STR(hint_charset) + Z_PARAM_STR_OR_NULL(hint_charset) ZEND_PARSE_PARAMETERS_END(); replaced = php_unescape_html_entities( diff --git a/ext/standard/info.c b/ext/standard/info.c index 99ba4a179fcba..153cb6cde0140 100644 --- a/ext/standard/info.c +++ b/ext/standard/info.c @@ -1263,7 +1263,7 @@ PHP_FUNCTION(phpversion) ZEND_PARSE_PARAMETERS_START(0, 1) Z_PARAM_OPTIONAL - Z_PARAM_STRING(ext_name, ext_name_len) + Z_PARAM_STRING_OR_NULL(ext_name, ext_name_len) ZEND_PARSE_PARAMETERS_END(); if (!ext_name) { diff --git a/ext/standard/streamsfuncs.c b/ext/standard/streamsfuncs.c index f56f52930cbfb..78e3896d5be39 100644 --- a/ext/standard/streamsfuncs.c +++ b/ext/standard/streamsfuncs.c @@ -88,7 +88,8 @@ PHP_FUNCTION(stream_socket_client) { zend_string *host; zval *zerrno = NULL, *zerrstr = NULL, *zcontext = NULL; - double timeout = (double)FG(default_socket_timeout); + double timeout; + zend_bool timeout_is_null = 1; php_timeout_ull conv; struct timeval tv; char *hashkey = NULL; @@ -98,18 +99,22 @@ PHP_FUNCTION(stream_socket_client) zend_string *errstr = NULL; php_stream_context *context = NULL; - RETVAL_FALSE; - ZEND_PARSE_PARAMETERS_START(1, 6) Z_PARAM_STR(host) Z_PARAM_OPTIONAL Z_PARAM_ZVAL(zerrno) Z_PARAM_ZVAL(zerrstr) - Z_PARAM_DOUBLE(timeout) + Z_PARAM_DOUBLE_OR_NULL(timeout, timeout_is_null) Z_PARAM_LONG(flags) Z_PARAM_RESOURCE_OR_NULL(zcontext) ZEND_PARSE_PARAMETERS_END(); + RETVAL_FALSE; + + if (timeout_is_null) { + timeout = (double)FG(default_socket_timeout); + } + context = php_stream_context_from_zval(zcontext, flags & PHP_FILE_NO_DEFAULT_CONTEXT); if (flags & PHP_STREAM_CLIENT_PERSISTENT) { @@ -238,7 +243,8 @@ PHP_FUNCTION(stream_socket_server) /* {{{ Accept a client connection from a server socket */ PHP_FUNCTION(stream_socket_accept) { - double timeout = (double)FG(default_socket_timeout); + double timeout; + zend_bool timeout_is_null = 1; zval *zpeername = NULL; zend_string *peername = NULL; php_timeout_ull conv; @@ -250,10 +256,14 @@ PHP_FUNCTION(stream_socket_accept) ZEND_PARSE_PARAMETERS_START(1, 3) Z_PARAM_RESOURCE(zstream) Z_PARAM_OPTIONAL - Z_PARAM_DOUBLE(timeout) + Z_PARAM_DOUBLE_OR_NULL(timeout, timeout_is_null) Z_PARAM_ZVAL(zpeername) ZEND_PARSE_PARAMETERS_END(); + if (timeout_is_null) { + timeout = (double)FG(default_socket_timeout); + } + php_stream_from_zval(stream, zstream); /* prepare the timeout value for use */ @@ -406,21 +416,23 @@ PHP_FUNCTION(stream_socket_recvfrom) /* {{{ Reads all remaining bytes (or up to maxlen bytes) from a stream and returns them as a string. */ PHP_FUNCTION(stream_get_contents) { - php_stream *stream; - zval *zsrc; - zend_long maxlen = (ssize_t) PHP_STREAM_COPY_ALL, - desiredpos = -1L; + php_stream *stream; + zval *zsrc; + zend_long maxlen, desiredpos = -1L; + zend_bool maxlen_is_null = 1; zend_string *contents; ZEND_PARSE_PARAMETERS_START(1, 3) Z_PARAM_RESOURCE(zsrc) Z_PARAM_OPTIONAL - Z_PARAM_LONG(maxlen) + Z_PARAM_LONG_OR_NULL(maxlen, maxlen_is_null) Z_PARAM_LONG(desiredpos) ZEND_PARSE_PARAMETERS_END(); - if (maxlen < 0 && maxlen != PHP_STREAM_COPY_ALL) { - php_error_docref(NULL, E_WARNING, "Length must be greater than or equal to zero, or -1"); + if (maxlen_is_null) { + maxlen = (ssize_t) PHP_STREAM_COPY_ALL; + } else if (maxlen < 0 && maxlen != PHP_STREAM_COPY_ALL) { + php_error_docref(NULL, E_WARNING, "Length must be greater than or equal to 0, or -1"); RETURN_FALSE; } @@ -463,7 +475,8 @@ PHP_FUNCTION(stream_copy_to_stream) { php_stream *src, *dest; zval *zsrc, *zdest; - zend_long maxlen = PHP_STREAM_COPY_ALL, pos = 0; + zend_long maxlen, pos = 0; + zend_bool maxlen_is_null = 1; size_t len; int ret; @@ -471,10 +484,14 @@ PHP_FUNCTION(stream_copy_to_stream) Z_PARAM_RESOURCE(zsrc) Z_PARAM_RESOURCE(zdest) Z_PARAM_OPTIONAL - Z_PARAM_LONG(maxlen) + Z_PARAM_LONG_OR_NULL(maxlen, maxlen_is_null) Z_PARAM_LONG(pos) ZEND_PARSE_PARAMETERS_END(); + if (maxlen_is_null) { + maxlen = PHP_STREAM_COPY_ALL; + } + php_stream_from_zval(src, zsrc); php_stream_from_zval(dest, zdest); @@ -1074,7 +1091,7 @@ PHP_FUNCTION(stream_context_get_default) ZEND_PARSE_PARAMETERS_START(0, 1) Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_HT(params) + Z_PARAM_ARRAY_HT_OR_NULL(params) ZEND_PARSE_PARAMETERS_END(); if (FG(default_context) == NULL) { diff --git a/ext/standard/string.c b/ext/standard/string.c index 5631ce4ac0e45..915b6cff5386b 100644 --- a/ext/standard/string.c +++ b/ext/standard/string.c @@ -68,6 +68,7 @@ void register_string_constants(INIT_FUNC_ARGS) REGISTER_LONG_CONSTANT("PATHINFO_BASENAME", PHP_PATHINFO_BASENAME, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("PATHINFO_EXTENSION", PHP_PATHINFO_EXTENSION, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("PATHINFO_FILENAME", PHP_PATHINFO_FILENAME, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("PATHINFO_ALL", PHP_PATHINFO_ALL, CONST_CS | CONST_PERSISTENT); /* If last members of struct lconv equal CHAR_MAX, no grouping is done */ REGISTER_LONG_CONSTANT("CHAR_MAX", CHAR_MAX, CONST_CS | CONST_PERSISTENT); @@ -247,16 +248,17 @@ static void php_spn_common_handler(INTERNAL_FUNCTION_PARAMETERS, int behavior) / { zend_string *s11, *s22; zend_long start = 0, len = 0; + zend_bool len_is_null = 1; ZEND_PARSE_PARAMETERS_START(2, 4) Z_PARAM_STR(s11) Z_PARAM_STR(s22) Z_PARAM_OPTIONAL Z_PARAM_LONG(start) - Z_PARAM_LONG(len) + Z_PARAM_LONG_OR_NULL(len, len_is_null) ZEND_PARSE_PARAMETERS_END(); - if (ZEND_NUM_ARGS() < 4) { + if (len_is_null) { len = ZSTR_LEN(s11); } @@ -1228,7 +1230,7 @@ PHP_FUNCTION(implode) ZEND_PARSE_PARAMETERS_START(1, 2) Z_PARAM_STR_OR_ARRAY_HT(arg1_str, arg1_array) Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_HT(pieces) + Z_PARAM_ARRAY_HT_OR_NULL(pieces) ZEND_PARSE_PARAMETERS_END(); if (pieces == NULL) { @@ -1265,10 +1267,10 @@ PHP_FUNCTION(strtok) ZEND_PARSE_PARAMETERS_START(1, 2) Z_PARAM_STR(str) Z_PARAM_OPTIONAL - Z_PARAM_STR(tok) + Z_PARAM_STR_OR_NULL(tok) ZEND_PARSE_PARAMETERS_END(); - if (ZEND_NUM_ARGS() == 1) { + if (!tok) { tok = str; } else { if (BG(strtok_string)) { @@ -2239,7 +2241,6 @@ PHP_FUNCTION(substr_replace) zval *len = NULL; zend_long l = 0; zend_long f; - int argc = ZEND_NUM_ARGS(); zend_string *result; HashPosition from_idx, repl_idx, len_idx; zval *tmp_str = NULL, *tmp_repl, *tmp_from = NULL, *tmp_len= NULL; @@ -2249,7 +2250,7 @@ PHP_FUNCTION(substr_replace) Z_PARAM_STR_OR_ARRAY_HT(repl_str, repl_ht) Z_PARAM_ZVAL(from) Z_PARAM_OPTIONAL - Z_PARAM_ZVAL(len) + Z_PARAM_ZVAL_OR_NULL(len) ZEND_PARSE_PARAMETERS_END(); if (Z_TYPE_P(from) != IS_ARRAY) { @@ -2259,7 +2260,7 @@ PHP_FUNCTION(substr_replace) } } - if (argc > 3) { + if (len) { if (Z_TYPE_P(len) != IS_ARRAY) { convert_to_long_ex(len); l = Z_LVAL_P(len); @@ -2272,13 +2273,13 @@ PHP_FUNCTION(substr_replace) if (str) { if ( - (argc == 3 && Z_TYPE_P(from) == IS_ARRAY) || - (argc == 4 && Z_TYPE_P(from) != Z_TYPE_P(len)) + (!len && Z_TYPE_P(from) == IS_ARRAY) || + (len && Z_TYPE_P(from) != Z_TYPE_P(len)) ) { php_error_docref(NULL, E_WARNING, "'start' and 'length' should be of same type - numerical or array "); RETURN_STR_COPY(str); } - if (argc == 4 && Z_TYPE_P(from) == IS_ARRAY) { + if (len && Z_TYPE_P(from) == IS_ARRAY) { if (zend_hash_num_elements(Z_ARRVAL_P(from)) != zend_hash_num_elements(Z_ARRVAL_P(len))) { php_error_docref(NULL, E_WARNING, "'start' and 'length' should have the same number of elements"); RETURN_STR_COPY(str); @@ -2398,7 +2399,7 @@ PHP_FUNCTION(substr_replace) } } - if (argc > 3 && Z_TYPE_P(len) == IS_ARRAY) { + if (len && Z_TYPE_P(len) == IS_ARRAY) { while (len_idx < Z_ARRVAL_P(len)->nNumUsed) { tmp_len = &Z_ARRVAL_P(len)->arData[len_idx].val; if (Z_TYPE_P(tmp_len) != IS_UNDEF) { @@ -2412,7 +2413,7 @@ PHP_FUNCTION(substr_replace) } else { l = ZSTR_LEN(orig_str); } - } else if (argc > 3) { + } else if (len) { l = Z_LVAL_P(len); } else { l = ZSTR_LEN(orig_str); @@ -3204,19 +3205,18 @@ PHP_FUNCTION(strtr) HashTable *from_ht = NULL; char *to = NULL; size_t to_len = 0; - int ac = ZEND_NUM_ARGS(); ZEND_PARSE_PARAMETERS_START(2, 3) Z_PARAM_STR(str) Z_PARAM_STR_OR_ARRAY_HT(from_str, from_ht) Z_PARAM_OPTIONAL - Z_PARAM_STRING(to, to_len) + Z_PARAM_STRING_OR_NULL(to, to_len) ZEND_PARSE_PARAMETERS_END(); - if (ac == 2 && from_ht == NULL) { + if (!to && from_ht == NULL) { zend_argument_type_error(2, "must be of type array, string given"); RETURN_THROWS(); - } else if (ac != 2 && from_str == NULL) { + } else if (to && from_str == NULL) { zend_argument_type_error(2, "must be of type string, array given"); RETURN_THROWS(); } @@ -3226,7 +3226,7 @@ PHP_FUNCTION(strtr) RETURN_EMPTY_STRING(); } - if (ac == 2) { + if (!to) { if (zend_hash_num_elements(from_ht) < 1) { RETURN_STR_COPY(str); } else if (zend_hash_num_elements(from_ht) == 1) { @@ -4249,7 +4249,6 @@ static void php_str_replace_common(INTERNAL_FUNCTION_PARAMETERS, int case_sensit zend_string *string_key; zend_ulong num_key; zend_long count = 0; - int argc = ZEND_NUM_ARGS(); ZEND_PARSE_PARAMETERS_START(3, 4) Z_PARAM_STR_OR_ARRAY_HT(search_str, search_ht) @@ -4290,7 +4289,7 @@ static void php_str_replace_common(INTERNAL_FUNCTION_PARAMETERS, int case_sensit } else { /* if subject is not an array */ count = php_str_replace_in_subject(search_str, search_ht, replace_str, replace_ht, subject_str, return_value, case_sensitivity); } - if (argc > 3) { + if (zcount) { ZEND_TRY_ASSIGN_REF_LONG(zcount, count); } } @@ -4562,7 +4561,8 @@ PHP_FUNCTION(strip_tags) { zend_string *buf; zend_string *str; - zval *allow=NULL; + zend_string *allow_str = NULL; + HashTable *allow_ht = NULL; const char *allowed_tags=NULL; size_t allowed_tags_len=0; smart_str tags_ss = {0}; @@ -4570,32 +4570,28 @@ PHP_FUNCTION(strip_tags) ZEND_PARSE_PARAMETERS_START(1, 2) Z_PARAM_STR(str) Z_PARAM_OPTIONAL - Z_PARAM_ZVAL(allow) + Z_PARAM_STR_OR_ARRAY_HT_OR_NULL(allow_str, allow_ht) ZEND_PARSE_PARAMETERS_END(); - if (allow) { - if (Z_TYPE_P(allow) == IS_ARRAY) { - zval *tmp; - zend_string *tag; - - ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(allow), tmp) { - tag = zval_get_string(tmp); - smart_str_appendc(&tags_ss, '<'); - smart_str_append(&tags_ss, tag); - smart_str_appendc(&tags_ss, '>'); - zend_string_release(tag); - } ZEND_HASH_FOREACH_END(); - if (tags_ss.s) { - smart_str_0(&tags_ss); - allowed_tags = ZSTR_VAL(tags_ss.s); - allowed_tags_len = ZSTR_LEN(tags_ss.s); - } - } else { - /* To maintain a certain BC, we allow anything for the second parameter and return original string */ - convert_to_string(allow); - allowed_tags = Z_STRVAL_P(allow); - allowed_tags_len = Z_STRLEN_P(allow); + if (allow_ht) { + zval *tmp; + zend_string *tag; + + ZEND_HASH_FOREACH_VAL(allow_ht, tmp) { + tag = zval_get_string(tmp); + smart_str_appendc(&tags_ss, '<'); + smart_str_append(&tags_ss, tag); + smart_str_appendc(&tags_ss, '>'); + zend_string_release(tag); + } ZEND_HASH_FOREACH_END(); + if (tags_ss.s) { + smart_str_0(&tags_ss); + allowed_tags = ZSTR_VAL(tags_ss.s); + allowed_tags_len = ZSTR_LEN(tags_ss.s); } + } else if (allow_str) { + allowed_tags = ZSTR_VAL(allow_str); + allowed_tags_len = ZSTR_LEN(allow_str); } buf = zend_string_init(ZSTR_VAL(str), ZSTR_LEN(str), 0); @@ -5753,7 +5749,7 @@ PHP_FUNCTION(str_word_count) Z_PARAM_STR(str) Z_PARAM_OPTIONAL Z_PARAM_LONG(type) - Z_PARAM_STRING(char_list, char_list_len) + Z_PARAM_STRING_OR_NULL(char_list, char_list_len) ZEND_PARSE_PARAMETERS_END(); switch(type) { diff --git a/ext/standard/tests/directory/DirectoryClass_basic_001.phpt b/ext/standard/tests/directory/DirectoryClass_basic_001.phpt index 355a49452d7e9..7e3c53b7970e2 100644 --- a/ext/standard/tests/directory/DirectoryClass_basic_001.phpt +++ b/ext/standard/tests/directory/DirectoryClass_basic_001.phpt @@ -42,21 +42,21 @@ Class [ class Directory ] { Method [ public method close ] { - Parameters [1] { - Parameter #0 [ $dir_handle = ] + Parameter #0 [ $dir_handle = null ] } } Method [ public method rewind ] { - Parameters [1] { - Parameter #0 [ $dir_handle = ] + Parameter #0 [ $dir_handle = null ] } } Method [ public method read ] { - Parameters [1] { - Parameter #0 [ $dir_handle = ] + Parameter #0 [ $dir_handle = null ] } } } diff --git a/ext/standard/tests/file/touch.phpt b/ext/standard/tests/file/touch.phpt index 0474b34af214f..32e49f31497ba 100644 --- a/ext/standard/tests/file/touch.phpt +++ b/ext/standard/tests/file/touch.phpt @@ -35,6 +35,12 @@ var_dump(touch("/no/such/file/or/directory")); @unlink($filename); +try { + touch("/no/such/file/or/directory", null, 1599492068); +} catch (ValueError $exception) { + echo $exception->getMessage() . "\n"; +} + echo "Done\n"; ?> --EXPECTF-- @@ -51,4 +57,5 @@ int(100) Warning: touch(): Unable to create file /no/such/file/or/directory because %s in %s on line %d bool(false) +touch(): Argument #2 ($time) cannot be null when argument #3 ($atime) is an integer Done diff --git a/ext/standard/tests/streams/stream_get_contents_negative_length.phpt b/ext/standard/tests/streams/stream_get_contents_negative_length.phpt index 3d52729a2f246..a0efebc1f193c 100644 --- a/ext/standard/tests/streams/stream_get_contents_negative_length.phpt +++ b/ext/standard/tests/streams/stream_get_contents_negative_length.phpt @@ -12,5 +12,5 @@ var_dump(stream_get_contents($tmp, -2)); --EXPECTF-- string(2) "bc" -Warning: stream_get_contents(): Length must be greater than or equal to zero, or -1 in %s on line %d +Warning: stream_get_contents(): Length must be greater than or equal to 0, or -1 in %s on line %d bool(false) diff --git a/ext/standard/tests/strings/implode1.phpt b/ext/standard/tests/strings/implode1.phpt index bd0e03c6d565ad01faaf147b996261ead2ea8dd2..fdc9d329a8fad443258bc5c4945d85c74096a47f 100644 GIT binary patch delta 33 mcmbQDKU06h5-~>m$xFo4CRYj@O#UHe2js*aY+El)C%GN delta 46 wcmbQKKSh7T60yngV(gRGh{;cu6_)|AS@KGAawdNfa|LohScKIjKQEOF0CiOl3IG5A diff --git a/ext/standard/tests/strings/join_variation2.phpt b/ext/standard/tests/strings/join_variation2.phpt index b48c35ca9448a..5fc83dde794db 100644 --- a/ext/standard/tests/strings/join_variation2.phpt +++ b/ext/standard/tests/strings/join_variation2.phpt @@ -102,49 +102,49 @@ echo "Done\n"; --- Testing join() by supplying different values for 'pieces' argument --- -- Iteration 1 -- -join(): Argument #2 ($pieces) must be of type array, int given +join(): Argument #2 ($pieces) must be of type ?array, int given -- Iteration 2 -- -join(): Argument #2 ($pieces) must be of type array, int given +join(): Argument #2 ($pieces) must be of type ?array, int given -- Iteration 3 -- -join(): Argument #2 ($pieces) must be of type array, int given +join(): Argument #2 ($pieces) must be of type ?array, int given -- Iteration 4 -- -join(): Argument #2 ($pieces) must be of type array, int given +join(): Argument #2 ($pieces) must be of type ?array, int given -- Iteration 5 -- -join(): Argument #2 ($pieces) must be of type array, float given +join(): Argument #2 ($pieces) must be of type ?array, float given -- Iteration 6 -- -join(): Argument #2 ($pieces) must be of type array, float given +join(): Argument #2 ($pieces) must be of type ?array, float given -- Iteration 7 -- -join(): Argument #2 ($pieces) must be of type array, float given +join(): Argument #2 ($pieces) must be of type ?array, float given -- Iteration 8 -- -join(): Argument #2 ($pieces) must be of type array, float given +join(): Argument #2 ($pieces) must be of type ?array, float given -- Iteration 9 -- -join(): Argument #2 ($pieces) must be of type array, float given +join(): Argument #2 ($pieces) must be of type ?array, float given -- Iteration 10 -- -join(): Argument #2 ($pieces) must be of type array, bool given +join(): Argument #2 ($pieces) must be of type ?array, bool given -- Iteration 11 -- -join(): Argument #2 ($pieces) must be of type array, bool given +join(): Argument #2 ($pieces) must be of type ?array, bool given -- Iteration 12 -- -join(): Argument #2 ($pieces) must be of type array, bool given +join(): Argument #2 ($pieces) must be of type ?array, bool given -- Iteration 13 -- -join(): Argument #2 ($pieces) must be of type array, bool given +join(): Argument #2 ($pieces) must be of type ?array, bool given -- Iteration 14 -- -join(): Argument #2 ($pieces) must be of type array, string given +join(): Argument #2 ($pieces) must be of type ?array, string given -- Iteration 15 -- -join(): Argument #2 ($pieces) must be of type array, string given +join(): Argument #2 ($pieces) must be of type ?array, string given -- Iteration 16 -- -join(): Argument #2 ($pieces) must be of type array, test given +join(): Argument #2 ($pieces) must be of type ?array, test given -- Iteration 17 -- -join(): Argument #2 ($pieces) must be of type array, string given +join(): Argument #2 ($pieces) must be of type ?array, string given -- Iteration 18 -- -join(): Argument #2 ($pieces) must be of type array, string given +join(): Argument #2 ($pieces) must be of type ?array, string given -- Iteration 19 -- -join(): Argument #2 ($pieces) must be of type array, null given +join(): Argument #1 ($pieces) must be of type array, string given -- Iteration 20 -- -join(): Argument #2 ($pieces) must be of type array, null given +join(): Argument #1 ($pieces) must be of type array, string given -- Iteration 21 -- -join(): Argument #2 ($pieces) must be of type array, resource given +join(): Argument #2 ($pieces) must be of type ?array, resource given -- Iteration 22 -- -join(): Argument #2 ($pieces) must be of type array, null given +join(): Argument #1 ($pieces) must be of type array, string given -- Iteration 23 -- -join(): Argument #2 ($pieces) must be of type array, null given +join(): Argument #1 ($pieces) must be of type array, string given Done diff --git a/ext/standard/tests/strings/strip_tags_variation2.phpt b/ext/standard/tests/strings/strip_tags_variation2.phpt index 794933e7c0962..640e353ab2b81 100644 --- a/ext/standard/tests/strings/strip_tags_variation2.phpt +++ b/ext/standard/tests/strings/strip_tags_variation2.phpt @@ -72,7 +72,11 @@ $values = array( $iterator = 1; foreach($values as $value) { echo "-- Iteration $iterator --\n"; - var_dump( strip_tags($string, $value) ); + try { + var_dump(strip_tags($string, $value)); + } catch (TypeError $exception) { + echo $exception->getMessage() . "\n"; + } $iterator++; }; @@ -121,5 +125,5 @@ string(10) "helloworld" -- Iteration 20 -- string(10) "helloworld" -- Iteration 21 -- -string(10) "helloworld" +strip_tags(): Argument #2 ($allowable_tags) must be of type array|string|null, resource given Done diff --git a/ext/standard/versioning.c b/ext/standard/versioning.c index d46fd26ccd7d3..dbdae6ecf7532 100644 --- a/ext/standard/versioning.c +++ b/ext/standard/versioning.c @@ -211,7 +211,7 @@ PHP_FUNCTION(version_compare) Z_PARAM_STRING(v1, v1_len) Z_PARAM_STRING(v2, v2_len) Z_PARAM_OPTIONAL - Z_PARAM_STRING(op, op_len) + Z_PARAM_STRING_OR_NULL(op, op_len) ZEND_PARSE_PARAMETERS_END(); compare = php_version_compare(v1, v2); diff --git a/ext/zlib/zlib.stub.php b/ext/zlib/zlib.stub.php index 8f4ba12c7964c..f3c96ca545638 100644 --- a/ext/zlib/zlib.stub.php +++ b/ext/zlib/zlib.stub.php @@ -41,13 +41,13 @@ function gzuncompress(string $data, int $max_decoded_len = 0): string|false {} * @param resource $fp * @alias fwrite */ -function gzwrite($fp, string $str, int $length = UNKNOWN): int|false {} +function gzwrite($fp, string $str, ?int $length = null): int|false {} /** * @param resource $fp * @alias fwrite */ -function gzputs($fp, string $str, int $length = UNKNOWN): int|false {} +function gzputs($fp, string $str, ?int $length = null): int|false {} /** * @param resource $fp diff --git a/ext/zlib/zlib_arginfo.h b/ext/zlib/zlib_arginfo.h index 134fe9729b47a..86ce095b3bddc 100644 --- a/ext/zlib/zlib_arginfo.h +++ b/ext/zlib/zlib_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: ee70bdd414ad35521ea24384e22ab05e641d81e0 */ + * Stub hash: b31cdbe9a5d719194753bfe303d32319478048bb */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_ob_gzhandler, 0, 2, MAY_BE_STRING|MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(0, data, IS_STRING, 0) @@ -63,7 +63,7 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_gzwrite, 0, 2, MAY_BE_LONG|MAY_BE_FALSE) ZEND_ARG_INFO(0, fp) ZEND_ARG_TYPE_INFO(0, str, IS_STRING, 0) - ZEND_ARG_TYPE_INFO(0, length, IS_LONG, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, length, IS_LONG, 1, "null") ZEND_END_ARG_INFO() #define arginfo_gzputs arginfo_gzwrite From 628db3f3b5b28190997b3cb2f711b6853c074660 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1t=C3=A9=20Kocsis?= Date: Fri, 4 Sep 2020 14:01:09 +0200 Subject: [PATCH 82/87] Fix UNKNOWN default values in various extensions Closes GH-6075 --- ext/gd/gd.c | 44 +++++---------------- ext/gd/gd.stub.php | 14 ++++--- ext/gd/gd_arginfo.h | 36 ++++-------------- ext/gd/tests/bug67248.phpt | 55 ++++++++++++++++++++++++--- ext/phar/phar_object.c | 16 ++++---- ext/phar/phar_object.stub.php | 46 +++++++++++----------- ext/phar/phar_object_arginfo.h | 24 ++++++------ ext/phar/tests/badparameters.phpt | 2 +- ext/pspell/pspell.c | 8 ++-- ext/pspell/pspell.stub.php | 6 +-- ext/pspell/pspell_arginfo.h | 20 +++++----- ext/simplexml/simplexml.c | 2 +- ext/simplexml/simplexml.stub.php | 4 +- ext/simplexml/simplexml_arginfo.h | 4 +- ext/sockets/sockets.stub.php | 6 +-- ext/sockets/sockets_arginfo.h | 6 +-- ext/spl/spl_directory.c | 6 +-- ext/spl/spl_directory.stub.php | 8 ++-- ext/spl/spl_directory_arginfo.h | 6 +-- ext/spl/tests/bug46051.phpt | 2 +- ext/tidy/tidy.c | 10 ++--- ext/tidy/tidy.stub.php | 18 ++++----- ext/tidy/tidy_arginfo.h | 20 +++++----- ext/xmlwriter/php_xmlwriter.c | 2 +- ext/xmlwriter/php_xmlwriter.stub.php | 2 +- ext/xmlwriter/php_xmlwriter_arginfo.h | 8 ++-- 26 files changed, 188 insertions(+), 187 deletions(-) diff --git a/ext/gd/gd.c b/ext/gd/gd.c index 48dd6ecf4518f..d425b83109a11 100644 --- a/ext/gd/gd.c +++ b/ext/gd/gd.c @@ -86,7 +86,7 @@ static int le_gd_font; #endif #ifdef HAVE_GD_FREETYPE -static void php_imagettftext_common(INTERNAL_FUNCTION_PARAMETERS, int, int); +static void php_imagettftext_common(INTERNAL_FUNCTION_PARAMETERS, int); #endif #include "gd_arginfo.h" @@ -3099,33 +3099,19 @@ PHP_FUNCTION(imagegetclip) /* {{{ Give the bounding box of a text using fonts via freetype2 */ PHP_FUNCTION(imageftbbox) { - php_imagettftext_common(INTERNAL_FUNCTION_PARAM_PASSTHRU, TTFTEXT_BBOX, 1); + php_imagettftext_common(INTERNAL_FUNCTION_PARAM_PASSTHRU, TTFTEXT_BBOX); } /* }}} */ /* {{{ Write text to the image using fonts via freetype2 */ PHP_FUNCTION(imagefttext) { - php_imagettftext_common(INTERNAL_FUNCTION_PARAM_PASSTHRU, TTFTEXT_DRAW, 1); -} -/* }}} */ - -/* {{{ Give the bounding box of a text using TrueType fonts */ -PHP_FUNCTION(imagettfbbox) -{ - php_imagettftext_common(INTERNAL_FUNCTION_PARAM_PASSTHRU, TTFTEXT_BBOX, 0); -} -/* }}} */ - -/* {{{ Write text to the image using a TrueType font */ -PHP_FUNCTION(imagettftext) -{ - php_imagettftext_common(INTERNAL_FUNCTION_PARAM_PASSTHRU, TTFTEXT_DRAW, 0); + php_imagettftext_common(INTERNAL_FUNCTION_PARAM_PASSTHRU, TTFTEXT_DRAW); } /* }}} */ /* {{{ php_imagettftext_common */ -static void php_imagettftext_common(INTERNAL_FUNCTION_PARAMETERS, int mode, int extended) +static void php_imagettftext_common(INTERNAL_FUNCTION_PARAMETERS, int mode) { zval *IM, *EXT = NULL; gdImagePtr im=NULL; @@ -3135,19 +3121,14 @@ static void php_imagettftext_common(INTERNAL_FUNCTION_PARAMETERS, int mode, int double ptsize, angle; char *str = NULL, *fontname = NULL; char *error = NULL; - int argc = ZEND_NUM_ARGS(); gdFTStringExtra strex = {0}; if (mode == TTFTEXT_BBOX) { - if (argc < 4 || argc > ((extended) ? 5 : 4)) { - ZEND_WRONG_PARAM_COUNT(); - } else if (zend_parse_parameters(argc, "ddss|a", &ptsize, &angle, &fontname, &fontname_len, &str, &str_len, &EXT) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "ddss|a", &ptsize, &angle, &fontname, &fontname_len, &str, &str_len, &EXT) == FAILURE) { RETURN_THROWS(); } } else { - if (argc < 8 || argc > ((extended) ? 9 : 8)) { - ZEND_WRONG_PARAM_COUNT(); - } else if (zend_parse_parameters(argc, "Oddlllss|a", &IM, gd_image_ce, &ptsize, &angle, &x, &y, &col, &fontname, &fontname_len, &str, &str_len, &EXT) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "Oddlllss|a", &IM, gd_image_ce, &ptsize, &angle, &x, &y, &col, &fontname, &fontname_len, &str, &str_len, &EXT) == FAILURE) { RETURN_THROWS(); } im = php_gd_libgdimageptr_from_zval_p(IM); @@ -3156,7 +3137,7 @@ static void php_imagettftext_common(INTERNAL_FUNCTION_PARAMETERS, int mode, int /* convert angle to radians */ angle = angle * (M_PI/180); - if (extended && EXT) { /* parse extended info */ + if (EXT) { /* parse extended info */ zval *item; zend_string *key; @@ -3184,7 +3165,7 @@ static void php_imagettftext_common(INTERNAL_FUNCTION_PARAMETERS, int mode, int PHP_GD_CHECK_OPEN_BASEDIR(fontname, "Invalid font filename"); - if (extended) { + if (EXT) { error = gdImageStringFTEx(im, brect, col, fontname, ptsize, angle, x, y, str, &strex); } else { error = gdImageStringFT(im, brect, col, fontname, ptsize, angle, x, y, str); @@ -3819,7 +3800,7 @@ PHP_FUNCTION(imageaffinematrixget) zval *tmp; int res = GD_FALSE, i; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "l|z", &type, &options) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "lz", &type, &options) == FAILURE) { RETURN_THROWS(); } @@ -3827,7 +3808,7 @@ PHP_FUNCTION(imageaffinematrixget) case GD_AFFINE_TRANSLATE: case GD_AFFINE_SCALE: { double x, y; - if (!options || Z_TYPE_P(options) != IS_ARRAY) { + if (Z_TYPE_P(options) != IS_ARRAY) { zend_argument_type_error(1, "must be of type array when using translate or scale"); RETURN_THROWS(); } @@ -3859,11 +3840,6 @@ PHP_FUNCTION(imageaffinematrixget) case GD_AFFINE_SHEAR_VERTICAL: { double angle; - if (!options) { - zend_argument_type_error(2, "must be of type int|float when using rotate or shear"); - RETURN_THROWS(); - } - angle = zval_get_double(options); if (type == GD_AFFINE_SHEAR_HORIZONTAL) { diff --git a/ext/gd/gd.stub.php b/ext/gd/gd.stub.php index 7b2e754bad87c..26c8db9b12504 100644 --- a/ext/gd/gd.stub.php +++ b/ext/gd/gd.stub.php @@ -215,13 +215,15 @@ function imagesetclip(GdImage $im, int $x1, int $x2, int $y1, int $y2): bool {} function imagegetclip(GdImage $im): array {} #ifdef HAVE_GD_FREETYPE -function imageftbbox(float $size, float $angle, string $font_file, string $text, array $extrainfo = UNKNOWN): array|false {} +function imageftbbox(float $size, float $angle, string $font_file, string $text, array $extrainfo = []): array|false {} -function imagefttext(GdImage $im, float $size, float $angle, int $x, int $y, int $col, string $font_file, string $text, array $extrainfo = UNKNOWN): array|false {} +function imagefttext(GdImage $im, float $size, float $angle, int $x, int $y, int $col, string $font_file, string $text, array $extrainfo = []): array|false {} -function imagettfbbox(float $size, float $angle, string $font_file, string $text): array|false {} +/** @alias imageftbbox */ +function imagettfbbox(float $size, float $angle, string $font_file, string $text, array $extrainfo = []): array|false {} -function imagettftext(GdImage $im, float $size, float $angle, int $x, int $y, int $col, string $font_file, string $text): array|false {} +/** @alias imagefttext */ +function imagettftext(GdImage $im, float $size, float $angle, int $x, int $y, int $col, string $font_file, string $text, array $extrainfo = []): array|false {} #endif /** @param array|int|float|bool $filter_args */ @@ -241,8 +243,8 @@ function imagescale(GdImage $im, int $new_width, int $new_height = -1, int $mode function imageaffine(GdImage $im, array $affine, ?array $clip = null): GdImage|false {} -/** @param array|int|float $options */ -function imageaffinematrixget(int $type, $options = UNKNOWN): array|false {} +/** @param array|float $options */ +function imageaffinematrixget(int $type, $options): array|false {} function imageaffinematrixconcat(array $m1, array $m2): array|false {} diff --git a/ext/gd/gd_arginfo.h b/ext/gd/gd_arginfo.h index ca9ee8942619b..bd6255b0836f2 100644 --- a/ext/gd/gd_arginfo.h +++ b/ext/gd/gd_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 540beb37f18b81102e7977447399757e865285c2 */ + * Stub hash: 20849891a4907e348f1a509388ab08b0b7f6633d */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_gd_info, 0, 0, IS_ARRAY, 0) ZEND_END_ARG_INFO() @@ -459,7 +459,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_imageftbbox, 0, 4, MAY_BE_ARRAY| ZEND_ARG_TYPE_INFO(0, angle, IS_DOUBLE, 0) ZEND_ARG_TYPE_INFO(0, font_file, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, text, IS_STRING, 0) - ZEND_ARG_TYPE_INFO(0, extrainfo, IS_ARRAY, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, extrainfo, IS_ARRAY, 0, "[]") ZEND_END_ARG_INFO() #endif @@ -473,30 +473,16 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_imagefttext, 0, 8, MAY_BE_ARRAY| ZEND_ARG_TYPE_INFO(0, col, IS_LONG, 0) ZEND_ARG_TYPE_INFO(0, font_file, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, text, IS_STRING, 0) - ZEND_ARG_TYPE_INFO(0, extrainfo, IS_ARRAY, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, extrainfo, IS_ARRAY, 0, "[]") ZEND_END_ARG_INFO() #endif #if defined(HAVE_GD_FREETYPE) -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_imagettfbbox, 0, 4, MAY_BE_ARRAY|MAY_BE_FALSE) - ZEND_ARG_TYPE_INFO(0, size, IS_DOUBLE, 0) - ZEND_ARG_TYPE_INFO(0, angle, IS_DOUBLE, 0) - ZEND_ARG_TYPE_INFO(0, font_file, IS_STRING, 0) - ZEND_ARG_TYPE_INFO(0, text, IS_STRING, 0) -ZEND_END_ARG_INFO() +#define arginfo_imagettfbbox arginfo_imageftbbox #endif #if defined(HAVE_GD_FREETYPE) -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_imagettftext, 0, 8, MAY_BE_ARRAY|MAY_BE_FALSE) - ZEND_ARG_OBJ_INFO(0, im, GdImage, 0) - ZEND_ARG_TYPE_INFO(0, size, IS_DOUBLE, 0) - ZEND_ARG_TYPE_INFO(0, angle, IS_DOUBLE, 0) - ZEND_ARG_TYPE_INFO(0, x, IS_LONG, 0) - ZEND_ARG_TYPE_INFO(0, y, IS_LONG, 0) - ZEND_ARG_TYPE_INFO(0, col, IS_LONG, 0) - ZEND_ARG_TYPE_INFO(0, font_file, IS_STRING, 0) - ZEND_ARG_TYPE_INFO(0, text, IS_STRING, 0) -ZEND_END_ARG_INFO() +#define arginfo_imagettftext arginfo_imagefttext #endif ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_imagefilter, 0, 2, _IS_BOOL, 0) @@ -547,7 +533,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_imageaffine, 0, 2, GdImage, ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, clip, IS_ARRAY, 1, "null") ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_imageaffinematrixget, 0, 1, MAY_BE_ARRAY|MAY_BE_FALSE) +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_imageaffinematrixget, 0, 2, MAY_BE_ARRAY|MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(0, type, IS_LONG, 0) ZEND_ARG_INFO(0, options) ZEND_END_ARG_INFO() @@ -690,12 +676,6 @@ ZEND_FUNCTION(imageftbbox); #if defined(HAVE_GD_FREETYPE) ZEND_FUNCTION(imagefttext); #endif -#if defined(HAVE_GD_FREETYPE) -ZEND_FUNCTION(imagettfbbox); -#endif -#if defined(HAVE_GD_FREETYPE) -ZEND_FUNCTION(imagettftext); -#endif ZEND_FUNCTION(imagefilter); ZEND_FUNCTION(imageconvolution); ZEND_FUNCTION(imageflip); @@ -832,10 +812,10 @@ static const zend_function_entry ext_functions[] = { ZEND_FE(imagefttext, arginfo_imagefttext) #endif #if defined(HAVE_GD_FREETYPE) - ZEND_FE(imagettfbbox, arginfo_imagettfbbox) + ZEND_FALIAS(imagettfbbox, imageftbbox, arginfo_imagettfbbox) #endif #if defined(HAVE_GD_FREETYPE) - ZEND_FE(imagettftext, arginfo_imagettftext) + ZEND_FALIAS(imagettftext, imagefttext, arginfo_imagettftext) #endif ZEND_FE(imagefilter, arginfo_imagefilter) ZEND_FE(imageconvolution, arginfo_imageconvolution) diff --git a/ext/gd/tests/bug67248.phpt b/ext/gd/tests/bug67248.phpt index 054ba52861caf..5b5e0e8baec37 100644 --- a/ext/gd/tests/bug67248.phpt +++ b/ext/gd/tests/bug67248.phpt @@ -11,15 +11,60 @@ require __DIR__ . '/func.inc'; for($i=0;$i<7;$i++) { trycatch_dump( - fn() => imageaffinematrixget($i) + fn() => imageaffinematrixget($i, new stdClass()) ); } ?> ---EXPECT-- +--EXPECTF-- !! [TypeError] imageaffinematrixget(): Argument #1 ($type) must be of type array when using translate or scale !! [TypeError] imageaffinematrixget(): Argument #1 ($type) must be of type array when using translate or scale -!! [TypeError] imageaffinematrixget(): Argument #2 ($options) must be of type int|float when using rotate or shear -!! [TypeError] imageaffinematrixget(): Argument #2 ($options) must be of type int|float when using rotate or shear -!! [TypeError] imageaffinematrixget(): Argument #2 ($options) must be of type int|float when using rotate or shear + +Notice: Object of class stdClass could not be converted to float in %s on line %d +array(6) { + [0]=> + float(%f) + [1]=> + float(%f) + [2]=> + float(%f) + [3]=> + float(%f) + [4]=> + float(0) + [5]=> + float(0) +} + +Notice: Object of class stdClass could not be converted to float in %s on line %d +array(6) { + [0]=> + float(1) + [1]=> + float(0) + [2]=> + float(%f) + [3]=> + float(1) + [4]=> + float(0) + [5]=> + float(0) +} + +Notice: Object of class stdClass could not be converted to float in %s on line %d +array(6) { + [0]=> + float(1) + [1]=> + float(%f) + [2]=> + float(0) + [3]=> + float(1) + [4]=> + float(0) + [5]=> + float(0) +} !! [ValueError] imageaffinematrixget(): Argument #1 ($type) must be a valid element type !! [ValueError] imageaffinematrixget(): Argument #1 ($type) must be a valid element type diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c index efb7048cf6ab5..69b9d3206deca 100644 --- a/ext/phar/phar_object.c +++ b/ext/phar/phar_object.c @@ -928,7 +928,7 @@ PHP_METHOD(Phar, createDefaultStub) zend_string *stub; size_t index_len = 0, webindex_len = 0; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "|pp", &index, &index_len, &webindex, &webindex_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "|p!p!", &index, &index_len, &webindex, &webindex_len) == FAILURE) { RETURN_THROWS(); } @@ -1833,7 +1833,7 @@ PHP_METHOD(Phar, buildFromIterator) char *base = NULL; struct _phar_t pass; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "O|s", &obj, zend_ce_traversable, &base, &base_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "O|s!", &obj, zend_ce_traversable, &base, &base_len) == FAILURE) { RETURN_THROWS(); } @@ -2339,7 +2339,7 @@ PHP_METHOD(Phar, convertToExecutable) /* a number that is not 0, 1 or 2 (Which is also Greg's birthday, so there) */ zend_long format = 9021976, method = 9021976; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "|lls", &format, &method, &ext, &ext_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "|lls!", &format, &method, &ext, &ext_len) == FAILURE) { RETURN_THROWS(); } @@ -2443,7 +2443,7 @@ PHP_METHOD(Phar, convertToData) /* a number that is not 0, 1 or 2 (Which is also Greg's birthday so there) */ zend_long format = 9021976, method = 9021976; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "|lls", &format, &method, &ext, &ext_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "|lls!", &format, &method, &ext, &ext_len) == FAILURE) { RETURN_THROWS(); } @@ -2992,7 +2992,7 @@ PHP_METHOD(Phar, setSignatureAlgorithm) char *error, *key = NULL; size_t key_len = 0; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "l|s", &algo, &key, &key_len) != SUCCESS) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "l|s!", &algo, &key, &key_len) != SUCCESS) { RETURN_THROWS(); } @@ -3155,7 +3155,7 @@ PHP_METHOD(Phar, compress) uint32_t flags; zend_object *ret; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "l|s", &method, &ext, &ext_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "l|s!", &method, &ext, &ext_len) == FAILURE) { RETURN_THROWS(); } @@ -3221,7 +3221,7 @@ PHP_METHOD(Phar, decompress) size_t ext_len = 0; zend_object *ret; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "|s", &ext, &ext_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "|s!", &ext, &ext_len) == FAILURE) { RETURN_THROWS(); } @@ -3804,7 +3804,7 @@ PHP_METHOD(Phar, addFile) php_stream *resource; zval zresource; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "p|s", &fname, &fname_len, &localname, &localname_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "p|s!", &fname, &fname_len, &localname, &localname_len) == FAILURE) { RETURN_THROWS(); } diff --git a/ext/phar/phar_object.stub.php b/ext/phar/phar_object.stub.php index da6ab987edd5f..e62a95c0383f6 100644 --- a/ext/phar/phar_object.stub.php +++ b/ext/phar/phar_object.stub.php @@ -16,16 +16,16 @@ public function __destruct() {} public function addEmptyDir(string $dirname) {} /** @return void */ - public function addFile(string $filename, string $localname = UNKNOWN) {} + public function addFile(string $filename, ?string $localname = null) {} /** @return void */ public function addFromString(string $localname, string $contents) {} /** @return array|false */ - public function buildFromDirectory(string $base_dir, string $regex = UNKNOWN) {} + public function buildFromDirectory(string $base_dir, string $regex = "") {} /** @return array|false */ - public function buildFromIterator(Traversable $iterator, string $base_directory = UNKNOWN) {} + public function buildFromIterator(Traversable $iterator, ?string $base_directory = null) {} /** @return void */ public function compressFiles(int $compression_type) {} @@ -34,22 +34,22 @@ public function compressFiles(int $compression_type) {} public function decompressFiles() {} /** @return Phar|null */ - public function compress(int $compression_type, string $file_ext = UNKNOWN) {} + public function compress(int $compression_type, ?string $file_ext = null) {} /** @return Phar|null */ - public function decompress(string $file_ext = UNKNOWN) {} + public function decompress(?string $file_ext = null) {} /** @return Phar|null */ - public function convertToExecutable(int $format = 9021976, int $compression_type = 9021976, string $file_ext = UNKNOWN) {} + public function convertToExecutable(int $format = 9021976, int $compression_type = 9021976, ?string $file_ext = null) {} /** @return Phar|null */ - public function convertToData(int $format = 9021976, int $compression_type = 9021976, string $file_ext = UNKNOWN) {} + public function convertToData(int $format = 9021976, int $compression_type = 9021976, ?string $file_ext = null) {} /** @return bool */ public function copy(string $newfile, string $oldfile) {} /** @return int */ - public function count(int $mode = UNKNOWN) {} + public function count(int $mode = COUNT_NORMAL) {} /** @return bool */ public function delete(string $entry) {} @@ -131,7 +131,7 @@ public function setDefaultStub(?string $index = null, ?string $webindex = null) public function setMetadata(mixed $metadata) {} /** @return void */ - public function setSignatureAlgorithm(int $algorithm, string $privatekey = UNKNOWN) {} + public function setSignatureAlgorithm(int $algorithm, ?string $privatekey = null) {} /** * @param resource $newstub @@ -151,8 +151,7 @@ final public static function canCompress(int $method = 0): bool {} final public static function canWrite(): bool {} - final public static function createDefaultStub( - string $index = UNKNOWN, string $webindex = UNKNOWN): string {} + final public static function createDefaultStub(?string $index = null, ?string $webindex = null): string {} final public static function getSupportedCompression(): array {} @@ -176,7 +175,7 @@ final public static function mungServer(array $munglist): void {} final public static function unlinkArchive(string $archive): bool {} final public static function webPhar( - ?string $alias = null, ?string $index = null, string $f404 = UNKNOWN, + ?string $alias = null, ?string $index = null, string $f404 = "", array $mimetypes = [], ?callable $rewrites = null): void {} } @@ -198,7 +197,7 @@ public function addEmptyDir(string $dirname) {} * @return void * @alias Phar::addFile */ - public function addFile(string $filename, string $localname = UNKNOWN) {} + public function addFile(string $filename, ?string $localname = null) {} /** * @return void @@ -210,13 +209,13 @@ public function addFromString(string $localname, string $contents) {} * @return array|false * @alias Phar::buildFromDirectory */ - public function buildFromDirectory(string $base_dir, string $regex = UNKNOWN) {} + public function buildFromDirectory(string $base_dir, string $regex = "") {} /** * @return array|false * @alias Phar::buildFromIterator */ - public function buildFromIterator(Traversable $iterator, string $base_directory = UNKNOWN) {} + public function buildFromIterator(Traversable $iterator, ?string $base_directory = null) {} /** * @return void @@ -234,25 +233,25 @@ public function decompressFiles() {} * @return Phar|null * @alias Phar::compress */ - public function compress(int $compression_type, string $file_ext = UNKNOWN) {} + public function compress(int $compression_type, ?string $file_ext = null) {} /** * @return Phar|null * @alias Phar::decompress */ - public function decompress(string $file_ext = UNKNOWN) {} + public function decompress(?string $file_ext = null) {} /** * @return Phar|null * @alias Phar::convertToExecutable */ - public function convertToExecutable(int $format = 9021976, int $compression_type = 9021976, string $file_ext = UNKNOWN) {} + public function convertToExecutable(int $format = 9021976, int $compression_type = 9021976, ?string $file_ext = null) {} /** * @return Phar|null * @alias Phar::convertToData */ - public function convertToData(int $format = 9021976, int $compression_type = 9021976, string $file_ext = UNKNOWN) {} + public function convertToData(int $format = 9021976, int $compression_type = 9021976, ?string $file_ext = null) {} /** * @return bool @@ -264,7 +263,7 @@ public function copy(string $newfile, string $oldfile) {} * @return int * @alias Phar::count */ - public function count(int $mode = UNKNOWN) {} + public function count(int $mode = COUNT_NORMAL) {} /** * @return bool @@ -407,7 +406,7 @@ public function setMetadata(mixed $metadata) {} * @return void * @alias Phar::setSignatureAlgorithm */ - public function setSignatureAlgorithm(int $algorithm, string $privatekey = UNKNOWN) {} + public function setSignatureAlgorithm(int $algorithm, ?string $privatekey = null) {} /** * @param resource $newstub @@ -438,8 +437,7 @@ final public static function canCompress(int $method = 0): bool {} final public static function canWrite(): bool {} /** @alias Phar::createDefaultStub */ - final public static function createDefaultStub( - string $index = UNKNOWN, string $webindex = UNKNOWN): string {} + final public static function createDefaultStub(?string $index = null, ?string $webindex = null): string {} /** @alias Phar::getSupportedCompression */ final public static function getSupportedCompression(): array {} @@ -474,7 +472,7 @@ final public static function unlinkArchive(string $archive): bool {} /** @alias Phar::webPhar */ final public static function webPhar( - ?string $alias = null, ?string $index = null, string $f404 = UNKNOWN, + ?string $alias = null, ?string $index = null, string $f404 = "", array $mimetypes = [], ?callable $rewrites = null): void {} } diff --git a/ext/phar/phar_object_arginfo.h b/ext/phar/phar_object_arginfo.h index e3963fe1a93e8..d6c6d5690ed48 100644 --- a/ext/phar/phar_object_arginfo.h +++ b/ext/phar/phar_object_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: d735d786b6804e336f45ac99c80276f5c67d4258 */ + * Stub hash: 8f92d8a7b1266cdec193336b36b2319235fbc40c */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Phar___construct, 0, 0, 1) ZEND_ARG_TYPE_INFO(0, filename, IS_STRING, 0) @@ -16,7 +16,7 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Phar_addFile, 0, 0, 1) ZEND_ARG_TYPE_INFO(0, filename, IS_STRING, 0) - ZEND_ARG_TYPE_INFO(0, localname, IS_STRING, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, localname, IS_STRING, 1, "null") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Phar_addFromString, 0, 0, 2) @@ -26,12 +26,12 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Phar_buildFromDirectory, 0, 0, 1) ZEND_ARG_TYPE_INFO(0, base_dir, IS_STRING, 0) - ZEND_ARG_TYPE_INFO(0, regex, IS_STRING, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, regex, IS_STRING, 0, "\"\"") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Phar_buildFromIterator, 0, 0, 1) ZEND_ARG_OBJ_INFO(0, iterator, Traversable, 0) - ZEND_ARG_TYPE_INFO(0, base_directory, IS_STRING, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, base_directory, IS_STRING, 1, "null") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Phar_compressFiles, 0, 0, 1) @@ -42,17 +42,17 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Phar_compress, 0, 0, 1) ZEND_ARG_TYPE_INFO(0, compression_type, IS_LONG, 0) - ZEND_ARG_TYPE_INFO(0, file_ext, IS_STRING, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, file_ext, IS_STRING, 1, "null") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Phar_decompress, 0, 0, 0) - ZEND_ARG_TYPE_INFO(0, file_ext, IS_STRING, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, file_ext, IS_STRING, 1, "null") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Phar_convertToExecutable, 0, 0, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, format, IS_LONG, 0, "9021976") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, compression_type, IS_LONG, 0, "9021976") - ZEND_ARG_TYPE_INFO(0, file_ext, IS_STRING, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, file_ext, IS_STRING, 1, "null") ZEND_END_ARG_INFO() #define arginfo_class_Phar_convertToData arginfo_class_Phar_convertToExecutable @@ -63,7 +63,7 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Phar_copy, 0, 0, 2) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Phar_count, 0, 0, 0) - ZEND_ARG_TYPE_INFO(0, mode, IS_LONG, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, mode, IS_LONG, 0, "COUNT_NORMAL") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Phar_delete, 0, 0, 1) @@ -134,7 +134,7 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Phar_setSignatureAlgorithm, 0, 0, 1) ZEND_ARG_TYPE_INFO(0, algorithm, IS_LONG, 0) - ZEND_ARG_TYPE_INFO(0, privatekey, IS_STRING, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, privatekey, IS_STRING, 1, "null") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Phar_setStub, 0, 0, 1) @@ -157,8 +157,8 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Phar_canWrite, 0, 0, _IS_B ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Phar_createDefaultStub, 0, 0, IS_STRING, 0) - ZEND_ARG_TYPE_INFO(0, index, IS_STRING, 0) - ZEND_ARG_TYPE_INFO(0, webindex, IS_STRING, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, index, IS_STRING, 1, "null") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, webindex, IS_STRING, 1, "null") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Phar_getSupportedCompression, 0, 0, IS_ARRAY, 0) @@ -204,7 +204,7 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Phar_webPhar, 0, 0, IS_VOID, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, alias, IS_STRING, 1, "null") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, index, IS_STRING, 1, "null") - ZEND_ARG_TYPE_INFO(0, f404, IS_STRING, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, f404, IS_STRING, 0, "\"\"") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, mimetypes, IS_ARRAY, 0, "[]") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, rewrites, IS_CALLABLE, 1, "null") ZEND_END_ARG_INFO() diff --git a/ext/phar/tests/badparameters.phpt b/ext/phar/tests/badparameters.phpt index 2ad994385cc77..47c5d9edfb153 100644 --- a/ext/phar/tests/badparameters.phpt +++ b/ext/phar/tests/badparameters.phpt @@ -229,7 +229,7 @@ try { ?> --EXPECTF-- Phar::mungServer(): Argument #1 ($munglist) must be of type array, string given -Phar::createDefaultStub(): Argument #1 ($index) must be a valid path, array given +Phar::createDefaultStub(): Argument #1 ($index) must be a valid path or null, array given Phar::loadPhar(): Argument #1 ($filename) must be a valid path, array given Phar::canCompress(): Argument #1 ($method) must be of type int, string given Phar::__construct(): Argument #1 ($filename) must be a valid path, array given diff --git a/ext/pspell/pspell.c b/ext/pspell/pspell.c index ce3242007e2f0..63732b77b087b 100644 --- a/ext/pspell/pspell.c +++ b/ext/pspell/pspell.c @@ -109,7 +109,7 @@ PHP_FUNCTION(pspell_new) { char *language, *spelling = NULL, *jargon = NULL, *encoding = NULL; size_t language_len, spelling_len = 0, jargon_len = 0, encoding_len = 0; - zend_long mode = Z_L(0), speed = Z_L(0); + zend_long mode = Z_L(0), speed = Z_L(0); int argc = ZEND_NUM_ARGS(); zval *ind; @@ -167,7 +167,7 @@ PHP_FUNCTION(pspell_new) pspell_config_replace(config, "encoding", encoding); } - if (argc > 4) { + if (mode) { speed = mode & PSPELL_SPEED_MASK_INTERNAL; /* First check what mode we want (how many suggestions) */ @@ -205,7 +205,7 @@ PHP_FUNCTION(pspell_new_personal) { char *personal, *language, *spelling = NULL, *jargon = NULL, *encoding = NULL; size_t personal_len, language_len, spelling_len = 0, jargon_len = 0, encoding_len = 0; - zend_long mode = Z_L(0), speed = Z_L(0); + zend_long mode = Z_L(0), speed = Z_L(0); int argc = ZEND_NUM_ARGS(); zval *ind; @@ -271,7 +271,7 @@ PHP_FUNCTION(pspell_new_personal) pspell_config_replace(config, "encoding", encoding); } - if (argc > 5) { + if (mode) { speed = mode & PSPELL_SPEED_MASK_INTERNAL; /* First check what mode we want (how many suggestions) */ diff --git a/ext/pspell/pspell.stub.php b/ext/pspell/pspell.stub.php index 8c549786f2718..03363f46b8a6a 100644 --- a/ext/pspell/pspell.stub.php +++ b/ext/pspell/pspell.stub.php @@ -2,9 +2,9 @@ /** @generate-function-entries */ -function pspell_new(string $language, string $spelling = UNKNOWN, string $jargon = UNKNOWN, string $encoding = UNKNOWN, int $mode = 0): int|false {} +function pspell_new(string $language, string $spelling = "", string $jargon = "", string $encoding = "", int $mode = 0): int|false {} -function pspell_new_personal(string $personal, string $language, string $spelling = UNKNOWN, string $jargon = UNKNOWN, string $encoding = UNKNOWN, int $mode = 0): int|false {} +function pspell_new_personal(string $personal, string $language, string $spelling = "", string $jargon = "", string $encoding = "", int $mode = 0): int|false {} function pspell_new_config(int $config): int|false {} @@ -22,7 +22,7 @@ function pspell_clear_session(int $pspell): bool {} function pspell_save_wordlist(int $pspell): bool {} -function pspell_config_create(string $language, string $spelling = UNKNOWN, string $jargon = UNKNOWN, string $encoding = UNKNOWN): int {} +function pspell_config_create(string $language, string $spelling = "", string $jargon = "", string $encoding = ""): int {} function pspell_config_runtogether(int $conf, bool $runtogether): bool {} diff --git a/ext/pspell/pspell_arginfo.h b/ext/pspell/pspell_arginfo.h index 9f9bf447d6238..4a009dec12d04 100644 --- a/ext/pspell/pspell_arginfo.h +++ b/ext/pspell/pspell_arginfo.h @@ -1,20 +1,20 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 9103420bb4162cad03e7ee06efa0d1c16820a099 */ + * Stub hash: 77f9effa6d246cf2b8da121d219462cce8a99918 */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pspell_new, 0, 1, MAY_BE_LONG|MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(0, language, IS_STRING, 0) - ZEND_ARG_TYPE_INFO(0, spelling, IS_STRING, 0) - ZEND_ARG_TYPE_INFO(0, jargon, IS_STRING, 0) - ZEND_ARG_TYPE_INFO(0, encoding, IS_STRING, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, spelling, IS_STRING, 0, "\"\"") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, jargon, IS_STRING, 0, "\"\"") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, encoding, IS_STRING, 0, "\"\"") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, mode, IS_LONG, 0, "0") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pspell_new_personal, 0, 2, MAY_BE_LONG|MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(0, personal, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, language, IS_STRING, 0) - ZEND_ARG_TYPE_INFO(0, spelling, IS_STRING, 0) - ZEND_ARG_TYPE_INFO(0, jargon, IS_STRING, 0) - ZEND_ARG_TYPE_INFO(0, encoding, IS_STRING, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, spelling, IS_STRING, 0, "\"\"") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, jargon, IS_STRING, 0, "\"\"") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, encoding, IS_STRING, 0, "\"\"") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, mode, IS_LONG, 0, "0") ZEND_END_ARG_INFO() @@ -50,9 +50,9 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_pspell_config_create, 0, 1, IS_LONG, 0) ZEND_ARG_TYPE_INFO(0, language, IS_STRING, 0) - ZEND_ARG_TYPE_INFO(0, spelling, IS_STRING, 0) - ZEND_ARG_TYPE_INFO(0, jargon, IS_STRING, 0) - ZEND_ARG_TYPE_INFO(0, encoding, IS_STRING, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, spelling, IS_STRING, 0, "\"\"") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, jargon, IS_STRING, 0, "\"\"") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, encoding, IS_STRING, 0, "\"\"") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_pspell_config_runtogether, 0, 2, _IS_BOOL, 0) diff --git a/ext/simplexml/simplexml.c b/ext/simplexml/simplexml.c index 1944ecf797819..c941e43ad37b9 100644 --- a/ext/simplexml/simplexml.c +++ b/ext/simplexml/simplexml.c @@ -1392,7 +1392,7 @@ SXE_METHOD(asXML) char *filename = NULL; size_t filename_len; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "|p", &filename, &filename_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "|p!", &filename, &filename_len) == FAILURE) { RETURN_THROWS(); } diff --git a/ext/simplexml/simplexml.stub.php b/ext/simplexml/simplexml.stub.php index 18cddf2886162..d068cb2d713cc 100644 --- a/ext/simplexml/simplexml.stub.php +++ b/ext/simplexml/simplexml.stub.php @@ -17,13 +17,13 @@ public function xpath(string $expression) {} public function registerXPathNamespace(string $prefix, string $namespace) {} /** @return string|bool */ - public function asXML(string $filename = UNKNOWN) {} + public function asXML(?string $filename = null) {} /** * @return string|bool * @alias SimpleXMLElement::asXML */ - public function saveXML(string $filename = UNKNOWN) {} + public function saveXML(?string $filename = null) {} /** @return array */ public function getNamespaces(bool $recursive = false) {} diff --git a/ext/simplexml/simplexml_arginfo.h b/ext/simplexml/simplexml_arginfo.h index 5aa6d50ba1d03..14624870324ac 100644 --- a/ext/simplexml/simplexml_arginfo.h +++ b/ext/simplexml/simplexml_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 953089f230247acf18b9ac48c0a4c516d144a987 */ + * Stub hash: 38b23ba107bcd8a519a2aa70bacbbc6ace9aaa77 */ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_simplexml_load_file, 0, 1, SimpleXMLElement, MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(0, filename, IS_STRING, 0) @@ -32,7 +32,7 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_SimpleXMLElement_registerXPathNamespace, 0, ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_class_SimpleXMLElement_asXML, 0, 0, 0) - ZEND_ARG_TYPE_INFO(0, filename, IS_STRING, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, filename, IS_STRING, 1, "null") ZEND_END_ARG_INFO() #define arginfo_class_SimpleXMLElement_saveXML arginfo_class_SimpleXMLElement_asXML diff --git a/ext/sockets/sockets.stub.php b/ext/sockets/sockets.stub.php index 7d524dd51c479..547374fe97bd5 100644 --- a/ext/sockets/sockets.stub.php +++ b/ext/sockets/sockets.stub.php @@ -32,13 +32,13 @@ function socket_read(Socket $socket, int $length, int $type = PHP_BINARY_READ): * @param string $addr * @param int $port */ -function socket_getsockname(Socket $socket, &$addr, &$port = UNKNOWN): bool {} +function socket_getsockname(Socket $socket, &$addr, &$port = null): bool {} /** * @param string $addr * @param int $port */ -function socket_getpeername(Socket $socket, &$addr, &$port = UNKNOWN): bool {} +function socket_getpeername(Socket $socket, &$addr, &$port = null): bool {} function socket_create(int $domain, int $type, int $protocol): Socket|false {} @@ -58,7 +58,7 @@ function socket_send(Socket $socket, string $buf, int $len, int $flags): int|fal * @param string $name * @param int $port */ -function socket_recvfrom(Socket $socket, &$buf, int $len, int $flags, &$name, &$port = UNKNOWN): int|false {} +function socket_recvfrom(Socket $socket, &$buf, int $len, int $flags, &$name, &$port = null): int|false {} function socket_sendto(Socket $socket, string $buf, int $len, int $flags, string $addr, ?int $port = null): int|false {} diff --git a/ext/sockets/sockets_arginfo.h b/ext/sockets/sockets_arginfo.h index f02533324b036..e7f4c04799397 100644 --- a/ext/sockets/sockets_arginfo.h +++ b/ext/sockets/sockets_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 8d03ee514902490691aa4a9b8801fbc10b5b9c26 */ + * Stub hash: f2d1b412bf2e07c3e607aa6ebad25b19d882b98e */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_socket_select, 0, 4, MAY_BE_LONG|MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(1, read_fds, IS_ARRAY, 1) @@ -48,7 +48,7 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_socket_getsockname, 0, 2, _IS_BOOL, 0) ZEND_ARG_OBJ_INFO(0, socket, Socket, 0) ZEND_ARG_INFO(1, addr) - ZEND_ARG_INFO(1, port) + ZEND_ARG_INFO_WITH_DEFAULT_VALUE(1, port, "null") ZEND_END_ARG_INFO() #define arginfo_socket_getpeername arginfo_socket_getsockname @@ -95,7 +95,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_socket_recvfrom, 0, 5, MAY_BE_LO ZEND_ARG_TYPE_INFO(0, len, IS_LONG, 0) ZEND_ARG_TYPE_INFO(0, flags, IS_LONG, 0) ZEND_ARG_INFO(1, name) - ZEND_ARG_INFO(1, port) + ZEND_ARG_INFO_WITH_DEFAULT_VALUE(1, port, "null") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_socket_sendto, 0, 5, MAY_BE_LONG|MAY_BE_FALSE) diff --git a/ext/spl/spl_directory.c b/ext/spl/spl_directory.c index 3f3391334aa7f..72fb1cbe8f575 100644 --- a/ext/spl/spl_directory.c +++ b/ext/spl/spl_directory.c @@ -532,7 +532,7 @@ static spl_filesystem_object *spl_filesystem_object_create_type(int num_args, sp size_t open_mode_len = 1; zval *resource = NULL; - if (zend_parse_parameters(num_args, "|sbr", + if (zend_parse_parameters(num_args, "|sbr!", &open_mode, &open_mode_len, &use_include_path, &resource) == FAILURE ) { return NULL; @@ -1350,7 +1350,7 @@ PHP_METHOD(SplFileInfo, getFileInfo) spl_filesystem_object *intern = Z_SPLFILESYSTEM_P(ZEND_THIS); zend_class_entry *ce = intern->info_class; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "|C", &ce) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "|C!", &ce) == FAILURE) { RETURN_THROWS(); } @@ -1366,7 +1366,7 @@ PHP_METHOD(SplFileInfo, getPathInfo) size_t path_len; char *path; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "|C", &ce) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "|C!", &ce) == FAILURE) { RETURN_THROWS(); } diff --git a/ext/spl/spl_directory.stub.php b/ext/spl/spl_directory.stub.php index 3d4f3969223bf..4691378ca9b71 100755 --- a/ext/spl/spl_directory.stub.php +++ b/ext/spl/spl_directory.stub.php @@ -73,16 +73,16 @@ public function getLinkTarget() {} public function getRealPath() {} /** @return SplFileInfo */ - public function getFileInfo(string $class_name = UNKNOWN) {} + public function getFileInfo(?string $class_name = null) {} /** @return SplFileInfo|null */ - public function getPathInfo(string $class_name = UNKNOWN) {} + public function getPathInfo(?string $class_name = null) {} /** - * @param resource $context + * @param resource|null $context * @return SplFileObject */ - public function openFile(string $open_mode = 'r', bool $use_include_path = false, $context = UNKNOWN) {} + public function openFile(string $open_mode = 'r', bool $use_include_path = false, $context = null) {} /** @return void */ public function setFileClass(string $class_name = SplFileObject::class) {} diff --git a/ext/spl/spl_directory_arginfo.h b/ext/spl/spl_directory_arginfo.h index 02081567593d8..7442c9c0e88e1 100644 --- a/ext/spl/spl_directory_arginfo.h +++ b/ext/spl/spl_directory_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 444071056e55fdc44d76db009c92b4d06eba81fb */ + * Stub hash: 9127cb70a84f3e75ed16a17b15940b8a6b5f3937 */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_SplFileInfo___construct, 0, 0, 1) ZEND_ARG_TYPE_INFO(0, file_name, IS_STRING, 0) @@ -53,7 +53,7 @@ ZEND_END_ARG_INFO() #define arginfo_class_SplFileInfo_getRealPath arginfo_class_SplFileInfo_getPath ZEND_BEGIN_ARG_INFO_EX(arginfo_class_SplFileInfo_getFileInfo, 0, 0, 0) - ZEND_ARG_TYPE_INFO(0, class_name, IS_STRING, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, class_name, IS_STRING, 1, "null") ZEND_END_ARG_INFO() #define arginfo_class_SplFileInfo_getPathInfo arginfo_class_SplFileInfo_getFileInfo @@ -61,7 +61,7 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_class_SplFileInfo_openFile, 0, 0, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, open_mode, IS_STRING, 0, "\'r\'") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, use_include_path, _IS_BOOL, 0, "false") - ZEND_ARG_INFO(0, context) + ZEND_ARG_INFO_WITH_DEFAULT_VALUE(0, context, "null") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_class_SplFileInfo_setFileClass, 0, 0, 0) diff --git a/ext/spl/tests/bug46051.phpt b/ext/spl/tests/bug46051.phpt index 0b3c422905f40..cebe8a52d7efa 100644 --- a/ext/spl/tests/bug46051.phpt +++ b/ext/spl/tests/bug46051.phpt @@ -6,7 +6,7 @@ Bug #46051 (SplFileInfo::openFile - memory overlap) $x = new splfileinfo(__FILE__); try { - $x->openFile(NULL, NULL, NULL); + $x->openFile(NULL, NULL, []); } catch (TypeError $e) { } var_dump($x->getPathName()); diff --git a/ext/tidy/tidy.c b/ext/tidy/tidy.c index 0adb122ff5bb1..37f9230aad722 100644 --- a/ext/tidy/tidy.c +++ b/ext/tidy/tidy.c @@ -998,7 +998,7 @@ PHP_FUNCTION(tidy_parse_string) Z_PARAM_STR(input) Z_PARAM_OPTIONAL Z_PARAM_STR_OR_ARRAY_HT_OR_NULL(options_str, options_ht) - Z_PARAM_STRING(enc, enc_len) + Z_PARAM_STRING_OR_NULL(enc, enc_len) ZEND_PARSE_PARAMETERS_END(); if (ZEND_SIZE_T_UINT_OVFL(ZSTR_LEN(input))) { @@ -1060,7 +1060,7 @@ PHP_FUNCTION(tidy_parse_file) Z_PARAM_PATH_STR(inputfile) Z_PARAM_OPTIONAL Z_PARAM_STR_OR_ARRAY_HT_OR_NULL(options_str, options_ht) - Z_PARAM_STRING(enc, enc_len) + Z_PARAM_STRING_OR_NULL(enc, enc_len) Z_PARAM_BOOL(use_include_path) ZEND_PARSE_PARAMETERS_END(); @@ -1353,7 +1353,7 @@ PHP_METHOD(tidy, __construct) Z_PARAM_OPTIONAL Z_PARAM_PATH_STR_OR_NULL(inputfile) Z_PARAM_STR_OR_ARRAY_HT_OR_NULL(options_str, options_ht) - Z_PARAM_STRING(enc, enc_len) + Z_PARAM_STRING_OR_NULL(enc, enc_len) Z_PARAM_BOOL(use_include_path) ZEND_PARSE_PARAMETERS_END(); @@ -1392,7 +1392,7 @@ PHP_METHOD(tidy, parseFile) Z_PARAM_PATH_STR(inputfile) Z_PARAM_OPTIONAL Z_PARAM_STR_OR_ARRAY_HT_OR_NULL(options_str, options_ht) - Z_PARAM_STRING(enc, enc_len) + Z_PARAM_STRING_OR_NULL(enc, enc_len) Z_PARAM_BOOL(use_include_path) ZEND_PARSE_PARAMETERS_END(); @@ -1432,7 +1432,7 @@ PHP_METHOD(tidy, parseString) Z_PARAM_STR(input) Z_PARAM_OPTIONAL Z_PARAM_STR_OR_ARRAY_HT_OR_NULL(options_str, options_ht) - Z_PARAM_STRING(enc, enc_len) + Z_PARAM_STRING_OR_NULL(enc, enc_len) ZEND_PARSE_PARAMETERS_END(); if (ZEND_SIZE_T_UINT_OVFL(ZSTR_LEN(input))) { diff --git a/ext/tidy/tidy.stub.php b/ext/tidy/tidy.stub.php index 76f4525132cc0..4ae1b5e000c3e 100644 --- a/ext/tidy/tidy.stub.php +++ b/ext/tidy/tidy.stub.php @@ -2,19 +2,19 @@ /** @generate-function-entries */ -function tidy_parse_string(string $input, array|string|null $config_options = null, string $encoding = UNKNOWN): tidy|false {} +function tidy_parse_string(string $input, array|string|null $config_options = null, ?string $encoding = null): tidy|false {} function tidy_get_error_buffer(tidy $object): string|false {} function tidy_get_output(tidy $object): string {} -function tidy_parse_file(string $file, array|string|null $config_options = null, string $encoding = UNKNOWN, bool $use_include_path = false): tidy|false {} +function tidy_parse_file(string $file, array|string|null $config_options = null, ?string $encoding = null, bool $use_include_path = false): tidy|false {} function tidy_clean_repair(tidy $object): bool {} -function tidy_repair_string(string $data, array|string|null $config_options = null, string $encoding = UNKNOWN): string|false {} +function tidy_repair_string(string $data, array|string|null $config_options = null, ?string $encoding = null): string|false {} -function tidy_repair_file(string $filename, array|string|null $config_options = null, string $encoding = UNKNOWN, bool $use_include_path = false): string|false {} +function tidy_repair_file(string $filename, array|string|null $config_options = null, ?string $encoding = null, bool $use_include_path = false): string|false {} function tidy_diagnose(tidy $object): bool {} @@ -54,7 +54,7 @@ function tidy_get_body(tidy $tidy): ?tidyNode {} class tidy { - public function __construct(?string $filename = null, array|string|null $config_options = null, string $encoding = UNKNOWN, bool $use_include_path = false) {} + public function __construct(?string $filename = null, array|string|null $config_options = null, ?string $encoding = null, bool $use_include_path = false) {} /** * @return string|int|bool @@ -69,22 +69,22 @@ public function getOpt(string $option) {} public function cleanRepair() {} /** @return bool */ - public function parseFile(string $file, array|string|null $config_options = null, string $encoding = UNKNOWN, bool $use_include_path = false) {} + public function parseFile(string $file, array|string|null $config_options = null, ?string $encoding = null, bool $use_include_path = false) {} /** @return bool */ - public function parseString(string $input, array|string|null $config_options = null, string $encoding = UNKNOWN) {} + public function parseString(string $input, array|string|null $config_options = null, ?string $encoding = null) {} /** * @return bool * @alias tidy_repair_string */ - public function repairString(string $data, array|string|null $config_options = null, string $encoding = UNKNOWN) {} + public function repairString(string $data, array|string|null $config_options = null, ?string $encoding = null) {} /** * @return bool * @alias tidy_repair_file */ - public function repairFile(string $filename, array|string|null $config_options = null, string $encoding = UNKNOWN, bool $use_include_path = false) {} + public function repairFile(string $filename, array|string|null $config_options = null, ?string $encoding = null, bool $use_include_path = false) {} /** * @return bool diff --git a/ext/tidy/tidy_arginfo.h b/ext/tidy/tidy_arginfo.h index 30ca646812494..ae3617a88f516 100644 --- a/ext/tidy/tidy_arginfo.h +++ b/ext/tidy/tidy_arginfo.h @@ -1,10 +1,10 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: cc7cee7934007aa4b195fb1be0626496937e9d38 */ + * Stub hash: 62b1cdb7f9b9a5641d3bd9248f5a73c30266d02e */ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_tidy_parse_string, 0, 1, tidy, MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(0, input, IS_STRING, 0) ZEND_ARG_TYPE_MASK(0, config_options, MAY_BE_ARRAY|MAY_BE_STRING|MAY_BE_NULL, "null") - ZEND_ARG_TYPE_INFO(0, encoding, IS_STRING, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, encoding, IS_STRING, 1, "null") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_tidy_get_error_buffer, 0, 1, MAY_BE_STRING|MAY_BE_FALSE) @@ -18,7 +18,7 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_tidy_parse_file, 0, 1, tidy, MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(0, file, IS_STRING, 0) ZEND_ARG_TYPE_MASK(0, config_options, MAY_BE_ARRAY|MAY_BE_STRING|MAY_BE_NULL, "null") - ZEND_ARG_TYPE_INFO(0, encoding, IS_STRING, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, encoding, IS_STRING, 1, "null") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, use_include_path, _IS_BOOL, 0, "false") ZEND_END_ARG_INFO() @@ -29,13 +29,13 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_tidy_repair_string, 0, 1, MAY_BE_STRING|MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(0, data, IS_STRING, 0) ZEND_ARG_TYPE_MASK(0, config_options, MAY_BE_ARRAY|MAY_BE_STRING|MAY_BE_NULL, "null") - ZEND_ARG_TYPE_INFO(0, encoding, IS_STRING, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, encoding, IS_STRING, 1, "null") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_tidy_repair_file, 0, 1, MAY_BE_STRING|MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(0, filename, IS_STRING, 0) ZEND_ARG_TYPE_MASK(0, config_options, MAY_BE_ARRAY|MAY_BE_STRING|MAY_BE_NULL, "null") - ZEND_ARG_TYPE_INFO(0, encoding, IS_STRING, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, encoding, IS_STRING, 1, "null") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, use_include_path, _IS_BOOL, 0, "false") ZEND_END_ARG_INFO() @@ -93,7 +93,7 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_class_tidy___construct, 0, 0, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, filename, IS_STRING, 1, "null") ZEND_ARG_TYPE_MASK(0, config_options, MAY_BE_ARRAY|MAY_BE_STRING|MAY_BE_NULL, "null") - ZEND_ARG_TYPE_INFO(0, encoding, IS_STRING, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, encoding, IS_STRING, 1, "null") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, use_include_path, _IS_BOOL, 0, "false") ZEND_END_ARG_INFO() @@ -107,26 +107,26 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_class_tidy_parseFile, 0, 0, 1) ZEND_ARG_TYPE_INFO(0, file, IS_STRING, 0) ZEND_ARG_TYPE_MASK(0, config_options, MAY_BE_ARRAY|MAY_BE_STRING|MAY_BE_NULL, "null") - ZEND_ARG_TYPE_INFO(0, encoding, IS_STRING, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, encoding, IS_STRING, 1, "null") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, use_include_path, _IS_BOOL, 0, "false") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_class_tidy_parseString, 0, 0, 1) ZEND_ARG_TYPE_INFO(0, input, IS_STRING, 0) ZEND_ARG_TYPE_MASK(0, config_options, MAY_BE_ARRAY|MAY_BE_STRING|MAY_BE_NULL, "null") - ZEND_ARG_TYPE_INFO(0, encoding, IS_STRING, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, encoding, IS_STRING, 1, "null") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_class_tidy_repairString, 0, 0, 1) ZEND_ARG_TYPE_INFO(0, data, IS_STRING, 0) ZEND_ARG_TYPE_MASK(0, config_options, MAY_BE_ARRAY|MAY_BE_STRING|MAY_BE_NULL, "null") - ZEND_ARG_TYPE_INFO(0, encoding, IS_STRING, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, encoding, IS_STRING, 1, "null") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_class_tidy_repairFile, 0, 0, 1) ZEND_ARG_TYPE_INFO(0, filename, IS_STRING, 0) ZEND_ARG_TYPE_MASK(0, config_options, MAY_BE_ARRAY|MAY_BE_STRING|MAY_BE_NULL, "null") - ZEND_ARG_TYPE_INFO(0, encoding, IS_STRING, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, encoding, IS_STRING, 1, "null") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, use_include_path, _IS_BOOL, 0, "false") ZEND_END_ARG_INFO() diff --git a/ext/xmlwriter/php_xmlwriter.c b/ext/xmlwriter/php_xmlwriter.c index 3dfaab97ee2a6..6ccd23b37ea66 100644 --- a/ext/xmlwriter/php_xmlwriter.c +++ b/ext/xmlwriter/php_xmlwriter.c @@ -855,7 +855,7 @@ PHP_FUNCTION(xmlwriter_write_dtd_entity) size_t pubid_len, sysid_len, ndataid_len; zval *self; - if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Oss|bsss", &self, xmlwriter_class_entry_ce, + if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Oss|bs!s!s!", &self, xmlwriter_class_entry_ce, &name, &name_len, &content, &content_len, &pe, &pubid, &pubid_len, &sysid, &sysid_len, &ndataid, &ndataid_len) == FAILURE) { RETURN_THROWS(); diff --git a/ext/xmlwriter/php_xmlwriter.stub.php b/ext/xmlwriter/php_xmlwriter.stub.php index 54cdd4ff5607c..5b3b4f512b1be 100644 --- a/ext/xmlwriter/php_xmlwriter.stub.php +++ b/ext/xmlwriter/php_xmlwriter.stub.php @@ -206,7 +206,7 @@ public function startDtdEntity(string $name, bool $isparam): bool {} public function endDtdEntity(): bool {} /** @alias xmlwriter_write_dtd_entity */ - public function writeDtdEntity(string $name, string $content, bool $isparam = false, string $publicId = UNKNOWN, string $systemId = UNKNOWN, string $ndataid = UNKNOWN): bool {} + public function writeDtdEntity(string $name, string $content, bool $isparam = false, ?string $publicId = null, ?string $systemId = null, ?string $ndataid = null): bool {} /** @alias xmlwriter_output_memory */ public function outputMemory(bool $flush = true): string {} diff --git a/ext/xmlwriter/php_xmlwriter_arginfo.h b/ext/xmlwriter/php_xmlwriter_arginfo.h index cebddf6372fb1..31eeb140aad7e 100644 --- a/ext/xmlwriter/php_xmlwriter_arginfo.h +++ b/ext/xmlwriter/php_xmlwriter_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 9323f768ddea26f104b699a9c0ce54e3560b3b32 */ + * Stub hash: 46bde559f165fc53d75690bfb4d86389202bb19e */ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_xmlwriter_open_uri, 0, 1, XMLWriter, MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(0, uri, IS_STRING, 0) @@ -314,9 +314,9 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_XMLWriter_writeDtdEntity, ZEND_ARG_TYPE_INFO(0, name, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, content, IS_STRING, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, isparam, _IS_BOOL, 0, "false") - ZEND_ARG_TYPE_INFO(0, publicId, IS_STRING, 0) - ZEND_ARG_TYPE_INFO(0, systemId, IS_STRING, 0) - ZEND_ARG_TYPE_INFO(0, ndataid, IS_STRING, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, publicId, IS_STRING, 1, "null") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, systemId, IS_STRING, 1, "null") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, ndataid, IS_STRING, 1, "null") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_XMLWriter_outputMemory, 0, 0, IS_STRING, 0) From 174dadf6b476a11c72646294700e62fe911366cb Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Mon, 7 Sep 2020 19:06:53 +0200 Subject: [PATCH 83/87] Don't allow dynamic properties on generators Noticed this because we leak those properties in GC. This was never intended to be allowed. --- Zend/tests/generators/dynamic_properties.phpt | 19 +++++++++++++++++++ Zend/zend_generators.c | 2 +- 2 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 Zend/tests/generators/dynamic_properties.phpt diff --git a/Zend/tests/generators/dynamic_properties.phpt b/Zend/tests/generators/dynamic_properties.phpt new file mode 100644 index 0000000000000..d42eed914abb0 --- /dev/null +++ b/Zend/tests/generators/dynamic_properties.phpt @@ -0,0 +1,19 @@ +--TEST-- +It's not possible to assign dynamic properties on a generator +--FILE-- +prop = 42; +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} + +?> +--EXPECT-- +Cannot create dynamic property Generator::$prop diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c index 13f06a4c343ea..cbb0a10d06e62 100644 --- a/Zend/zend_generators.c +++ b/Zend/zend_generators.c @@ -1159,7 +1159,7 @@ void zend_register_generator_ce(void) /* {{{ */ INIT_CLASS_ENTRY(ce, "Generator", class_Generator_methods); zend_ce_generator = zend_register_internal_class(&ce); - zend_ce_generator->ce_flags |= ZEND_ACC_FINAL; + zend_ce_generator->ce_flags |= ZEND_ACC_FINAL | ZEND_ACC_NO_DYNAMIC_PROPERTIES; zend_ce_generator->create_object = zend_generator_create; zend_ce_generator->serialize = zend_class_serialize_deny; zend_ce_generator->unserialize = zend_class_unserialize_deny; From fd0b39905c299c24941644f22947553e0e009dbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1t=C3=A9=20Kocsis?= Date: Mon, 10 Aug 2020 23:23:35 +0200 Subject: [PATCH 84/87] Promote warnings to exceptions in ext/intl Closes GH-5972 --- ext/intl/converter/converter.c | 4 +- ext/intl/converter/converter.stub.php | 2 +- ext/intl/converter/converter_arginfo.h | 2 +- ext/intl/formatter/formatter_format.c | 5 +- ext/intl/formatter/formatter_parse.c | 19 ++-- ext/intl/grapheme/grapheme_string.c | 66 +++++++------- ext/intl/locale/locale_methods.c | 7 +- ext/intl/normalizer/normalizer_normalize.c | 10 +-- .../resourcebundle/resourcebundle_class.c | 8 +- ext/intl/tests/bug61487.phpt | 17 +++- ext/intl/tests/bug62083.phpt | 8 +- ext/intl/tests/grapheme.phpt | 48 +++++++--- ext/intl/tests/grapheme2.phpt | 52 ++++++----- ext/intl/tests/grapheme_empty.phpt | 88 +++++++++++++++++++ ext/intl/tests/locale_compose_locale.phpt | 25 +++--- .../transliterator_transliterate_error.phpt | 11 ++- .../transliterator/transliterator_class.c | 7 +- .../transliterator/transliterator_methods.c | 39 ++++---- 18 files changed, 272 insertions(+), 146 deletions(-) create mode 100644 ext/intl/tests/grapheme_empty.phpt diff --git a/ext/intl/converter/converter.c b/ext/intl/converter/converter.c index 72144a4ee185b..697ebcda0b7c2 100644 --- a/ext/intl/converter/converter.c +++ b/ext/intl/converter/converter.c @@ -693,8 +693,8 @@ PHP_METHOD(UConverter, reasonText) { UCNV_REASON_CASE(CLOSE) UCNV_REASON_CASE(CLONE) default: - php_error_docref(NULL, E_WARNING, "Unknown UConverterCallbackReason: " ZEND_LONG_FMT, reason); - RETURN_FALSE; + zend_argument_value_error(1, "must be a UConverter::REASON_* constant"); + RETURN_THROWS(); } } /* }}} */ diff --git a/ext/intl/converter/converter.stub.php b/ext/intl/converter/converter.stub.php index f888a78b03601..5b82b098f47f7 100644 --- a/ext/intl/converter/converter.stub.php +++ b/ext/intl/converter/converter.stub.php @@ -45,7 +45,7 @@ public static function getStandards() {} /** @return string|false|null */ public function getSubstChars() {} - /** @return string|false */ + /** @return string */ public static function reasonText(int $reason) {} /** @return bool */ diff --git a/ext/intl/converter/converter_arginfo.h b/ext/intl/converter/converter_arginfo.h index 513d8e4525841..8b8f8fc1f521e 100644 --- a/ext/intl/converter/converter_arginfo.h +++ b/ext/intl/converter/converter_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 9eef3fe293c07ab77f4c8b6d8d53a3798f8a9865 */ + * Stub hash: e33e2614c969c59b79c6062f7a347a8e8e486d85 */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_UConverter___construct, 0, 0, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, destination_encoding, IS_STRING, 1, "null") diff --git a/ext/intl/formatter/formatter_format.c b/ext/intl/formatter/formatter_format.c index 7d2d5932289d2..aa9c5915adeb8 100644 --- a/ext/intl/formatter/formatter_format.c +++ b/ext/intl/formatter/formatter_format.c @@ -105,9 +105,8 @@ PHP_FUNCTION( numfmt_format ) break; default: - php_error_docref(NULL, E_WARNING, "Unsupported format type " ZEND_LONG_FMT, type); - RETURN_FALSE; - break; + zend_argument_value_error(3, "must be a NumberFormatter::TYPE_* constant"); + RETURN_THROWS(); } INTL_METHOD_RETVAL_UTF8( nfo, formatted, formatted_len, ( formatted != format_buf ) ); diff --git a/ext/intl/formatter/formatter_parse.c b/ext/intl/formatter/formatter_parse.c index 3015adac057d0..9940cc5fe7bd0 100644 --- a/ext/intl/formatter/formatter_parse.c +++ b/ext/intl/formatter/formatter_parse.c @@ -44,13 +44,13 @@ PHP_FUNCTION( numfmt_parse ) FORMATTER_METHOD_INIT_VARS; /* Parse parameters. */ - if( zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "Os|lz!", + if (zend_parse_method_parameters( ZEND_NUM_ARGS(), getThis(), "Os|lz!", &object, NumberFormatter_ce_ptr, &str, &str_len, &type, &zposition ) == FAILURE ) { RETURN_THROWS(); } - if(zposition) { + if (zposition) { position = (int32_t) zval_get_long(zposition); position_p = &position; } @@ -86,17 +86,20 @@ PHP_FUNCTION( numfmt_parse ) RETVAL_DOUBLE(val_double); break; default: - php_error_docref(NULL, E_WARNING, "Unsupported format type " ZEND_LONG_FMT, type); - RETVAL_FALSE; - break; + zend_argument_value_error(3, "must be a NumberFormatter::TYPE_* constant"); + goto cleanup; + } + + if (zposition) { + ZEND_TRY_ASSIGN_REF_LONG(zposition, position); } + +cleanup: + #if ICU_LOCALE_BUG && defined(LC_NUMERIC) setlocale(LC_NUMERIC, oldlocale); efree(oldlocale); #endif - if(zposition) { - ZEND_TRY_ASSIGN_REF_LONG(zposition, position); - } if (sstr) { efree(sstr); diff --git a/ext/intl/grapheme/grapheme_string.c b/ext/intl/grapheme/grapheme_string.c index 12305aa049eeb..8706381e58825 100644 --- a/ext/intl/grapheme/grapheme_string.c +++ b/ext/intl/grapheme/grapheme_string.c @@ -114,8 +114,8 @@ PHP_FUNCTION(grapheme_strpos) } if ( OUTSIDE_STRING(loffset, haystack_len) ) { - intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "grapheme_strpos: Offset not contained in string", 1 ); - RETURN_FALSE; + zend_argument_value_error(3, "must be contained in argument #1 ($haystack)"); + RETURN_THROWS(); } /* we checked that it will fit: */ @@ -125,8 +125,8 @@ PHP_FUNCTION(grapheme_strpos) /* the offset is 'grapheme count offset' so it still might be invalid - we'll check it later */ if (needle_len == 0) { - intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "grapheme_strpos: Empty delimiter", 1 ); - RETURN_FALSE; + zend_argument_value_error(2, "cannot be empty"); + RETURN_THROWS(); } if (offset >= 0) { @@ -154,7 +154,6 @@ PHP_FUNCTION(grapheme_strpos) } else { RETURN_FALSE; } - } /* }}} */ @@ -174,8 +173,8 @@ PHP_FUNCTION(grapheme_stripos) } if ( OUTSIDE_STRING(loffset, haystack_len) ) { - intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "grapheme_stripos: Offset not contained in string", 1 ); - RETURN_FALSE; + zend_argument_value_error(3, "must be contained in argument #1 ($haystack)"); + RETURN_THROWS(); } /* we checked that it will fit: */ @@ -184,8 +183,8 @@ PHP_FUNCTION(grapheme_stripos) /* the offset is 'grapheme count offset' so it still might be invalid - we'll check it later */ if (needle_len == 0) { - intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "grapheme_stripos: Empty delimiter", 1 ); - RETURN_FALSE; + zend_argument_value_error(2, "cannot be empty"); + RETURN_THROWS(); } is_ascii = ( grapheme_ascii_check((unsigned char*)haystack, haystack_len) >= 0 ); @@ -240,8 +239,8 @@ PHP_FUNCTION(grapheme_strrpos) } if ( OUTSIDE_STRING(loffset, haystack_len) ) { - intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "grapheme_strpos: Offset not contained in string", 1 ); - RETURN_FALSE; + zend_argument_value_error(3, "must be contained in argument #1 ($haystack)"); + RETURN_THROWS(); } /* we checked that it will fit: */ @@ -250,8 +249,8 @@ PHP_FUNCTION(grapheme_strrpos) /* the offset is 'grapheme count offset' so it still might be invalid - we'll check it later */ if (needle_len == 0) { - intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "grapheme_strpos: Empty delimiter", 1 ); - RETURN_FALSE; + zend_argument_value_error(2, "cannot be empty"); + RETURN_THROWS(); } is_ascii = grapheme_ascii_check((unsigned char *)haystack, haystack_len) >= 0; @@ -300,8 +299,8 @@ PHP_FUNCTION(grapheme_strripos) } if ( OUTSIDE_STRING(loffset, haystack_len) ) { - intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "grapheme_strpos: Offset not contained in string", 1 ); - RETURN_FALSE; + zend_argument_value_error(3, "must be contained in argument #1 ($haystack)"); + RETURN_THROWS(); } /* we checked that it will fit: */ @@ -310,8 +309,8 @@ PHP_FUNCTION(grapheme_strripos) /* the offset is 'grapheme count offset' so it still might be invalid - we'll check it later */ if (needle_len == 0) { - intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "grapheme_strpos: Empty delimiter", 1 ); - RETURN_FALSE; + zend_argument_value_error(2, "cannot be empty"); + RETURN_THROWS(); } is_ascii = grapheme_ascii_check((unsigned char *)haystack, haystack_len) >= 0; @@ -377,8 +376,8 @@ PHP_FUNCTION(grapheme_substr) } if ( OUTSIDE_STRING(lstart, str_len)) { - intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "grapheme_substr: start not contained in string", 1 ); - RETURN_FALSE; + zend_argument_value_error(2, "must be contained in argument #1 ($string)"); + RETURN_THROWS(); } /* we checked that it will fit: */ @@ -532,10 +531,9 @@ PHP_FUNCTION(grapheme_substr) if ( UBRK_DONE == sub_str_end_pos) { if(length < 0) { - intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "grapheme_substr: length not contained in string", 1 ); - + zend_argument_value_error(3, "must be contained in argument #1 ($string)"); efree(ustr); - RETURN_FALSE; + RETURN_THROWS(); } else { sub_str_end_pos = ustr_len; } @@ -582,13 +580,10 @@ static void strstr_common_handler(INTERNAL_FUNCTION_PARAMETERS, int f_ignore_cas } if (needle_len == 0) { - - intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "grapheme_strpos: Empty delimiter", 1 ); - - RETURN_FALSE; + zend_argument_value_error(2, "cannot be empty"); + RETURN_THROWS(); } - if ( !f_ignore_case ) { /* ASCII optimization: quick check to see if the string might be there @@ -783,9 +778,8 @@ PHP_FUNCTION(grapheme_extract) } if ( extract_type < GRAPHEME_EXTRACT_TYPE_MIN || extract_type > GRAPHEME_EXTRACT_TYPE_MAX ) { - intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, - "grapheme_extract: unknown extract type param", 0 ); - RETURN_FALSE; + zend_argument_value_error(3, "must be either GRAPHEME_EXTR_COUNT, GRAPHEME_EXTR_MAXBYTES, or GRAPHEME_EXTR_MAXCHARS"); + RETURN_THROWS(); } if ( lstart > INT32_MAX || lstart < 0 || (size_t)lstart >= str_len ) { @@ -793,10 +787,16 @@ PHP_FUNCTION(grapheme_extract) RETURN_FALSE; } - if ( size > INT32_MAX || size < 0) { - intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "grapheme_extract: size is invalid", 0 ); - RETURN_FALSE; + if (size < 0) { + zend_argument_value_error(2, "must be greater than or equal to 0"); + RETURN_THROWS(); } + + if (size > INT32_MAX) { + zend_argument_value_error(2, "is too large"); + RETURN_THROWS(); + } + if (size == 0) { RETURN_EMPTY_STRING(); } diff --git a/ext/intl/locale/locale_methods.c b/ext/intl/locale/locale_methods.c index 2b166b74dce98..466dafadaceda 100644 --- a/ext/intl/locale/locale_methods.c +++ b/ext/intl/locale/locale_methods.c @@ -882,10 +882,9 @@ PHP_FUNCTION(locale_compose) /* Not grandfathered */ result = append_key_value(loc_name, hash_arr , LOC_LANG_TAG); if( result == LOC_NOT_FOUND ){ - intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, - "locale_compose: parameter array does not contain 'language' tag.", 0 ); + zend_argument_value_error(1, "must contain a \"%s\" key", LOC_LANG_TAG); smart_str_free(loc_name); - RETURN_FALSE; + RETURN_THROWS(); } if( !handleAppendResult( result, loc_name)){ RETURN_FALSE; @@ -1348,7 +1347,7 @@ static zend_string* lookup_loc_range(const char* loc_range, HashTable* hash_arr, /* convert the array to lowercase , also replace hyphens with the underscore and store it in cur_arr */ if(Z_TYPE_P(ele_value)!= IS_STRING) { /* element value is not a string */ - intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "lookup_loc_range: locale array element is not a string", 0); + zend_argument_type_error(2, "must only contain string values"); LOOKUP_CLEAN_RETURN(NULL); } cur_arr[cur_arr_len*2] = estrndup(Z_STRVAL_P(ele_value), Z_STRLEN_P(ele_value)); diff --git a/ext/intl/normalizer/normalizer_normalize.c b/ext/intl/normalizer/normalizer_normalize.c index f712049ea3fa6..5eca379c9905b 100644 --- a/ext/intl/normalizer/normalizer_normalize.c +++ b/ext/intl/normalizer/normalizer_normalize.c @@ -121,9 +121,8 @@ PHP_FUNCTION( normalizer_normalize ) #endif break; default: - intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, - "normalizer_normalize: illegal normalization form", 0 ); - RETURN_FALSE; + zend_argument_value_error(2, "must be a a valid normalization form"); + RETURN_THROWS(); } /* @@ -248,9 +247,8 @@ PHP_FUNCTION( normalizer_is_normalized ) #endif break; default: - intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, - "normalizer_normalize: illegal normalization form", 0 ); - RETURN_FALSE; + zend_argument_value_error(2, "must be a a valid normalization form"); + RETURN_THROWS(); } diff --git a/ext/intl/resourcebundle/resourcebundle_class.c b/ext/intl/resourcebundle/resourcebundle_class.c index 3a0fb22e08d80..98a33b9284878 100644 --- a/ext/intl/resourcebundle/resourcebundle_class.c +++ b/ext/intl/resourcebundle/resourcebundle_class.c @@ -105,9 +105,7 @@ static int resourcebundle_ctor(INTERNAL_FUNCTION_PARAMETERS) } if (bundlename_len >= MAXPATHLEN) { - intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "Bundle name too long", 0 ); - zval_ptr_dtor(return_value); - ZVAL_NULL(return_value); + zend_argument_value_error(2, "is too long"); return FAILURE; } @@ -296,8 +294,8 @@ PHP_FUNCTION( resourcebundle_locales ) } if (bundlename_len >= MAXPATHLEN) { - intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "resourcebundle_locales: bundle name too long", 0 ); - RETURN_FALSE; + zend_argument_value_error(1, "is too long"); + RETURN_THROWS(); } if(bundlename_len == 0) { diff --git a/ext/intl/tests/bug61487.phpt b/ext/intl/tests/bug61487.phpt index 677787bda5b65..0d1e7f6fd84f9 100644 --- a/ext/intl/tests/bug61487.phpt +++ b/ext/intl/tests/bug61487.phpt @@ -6,9 +6,18 @@ if (PHP_INT_SIZE != 8) die('skip 64-bit only'); ?> --FILE-- getMessage() . "\n"; +} + +try { + grapheme_strpos(1,1,2147483648); +} catch (ValueError $exception) { + echo $exception->getMessage() . "\n"; +} ?> --EXPECT-- -bool(false) -bool(false) +grapheme_stripos(): Argument #3 ($offset) must be contained in argument #1 ($haystack) +grapheme_strpos(): Argument #3 ($offset) must be contained in argument #1 ($haystack) diff --git a/ext/intl/tests/bug62083.phpt b/ext/intl/tests/bug62083.phpt index 944a717a363c2..7bfa53058bae5 100644 --- a/ext/intl/tests/bug62083.phpt +++ b/ext/intl/tests/bug62083.phpt @@ -7,7 +7,11 @@ if (!extension_loaded('intl')) --FILE-- getMessage() . "\n"; +} ?> --EXPECT-- -bool(false) +grapheme_extract(): Argument #3 ($extract_type) must be either GRAPHEME_EXTR_COUNT, GRAPHEME_EXTR_MAXBYTES, or GRAPHEME_EXTR_MAXCHARS diff --git a/ext/intl/tests/grapheme.phpt b/ext/intl/tests/grapheme.phpt index be82abf718090..18cf3fb6d5057 100644 --- a/ext/intl/tests/grapheme.phpt +++ b/ext/intl/tests/grapheme.phpt @@ -400,11 +400,19 @@ function ut_main() $arg0 = urlencode($test[0]); $res_str .= "substring of \"$arg0\" from \"$test[1]\" - grapheme_substr"; if ( 3 == count( $test ) ) { - $result = grapheme_substr($test[0], $test[1]); + try { + $result = grapheme_substr($test[0], $test[1]); + } catch (ValueError $exception) { + $res_str .= ": " . $exception->getMessage() . "\n"; + } } else { $res_str .= " with length $test[2]"; - $result = grapheme_substr($test[0], $test[1], $test[2]); + try { + $result = grapheme_substr($test[0], $test[1], $test[2]); + } catch (ValueError $exception) { + $res_str .= ": " . $exception->getMessage() . "\n"; + } } $res_str .= " = "; if ( $result === false ) { @@ -465,11 +473,19 @@ function ut_main() $arg0 = urlencode($test[0]); $res_str .= "find \"$arg1\" in \"$arg0\" - grapheme_strstr"; if ( 3 == count( $test ) ) { - $result = grapheme_strstr($test[0], $test[1]); + try { + $result = grapheme_strstr($test[0], $test[1]); + } catch (ValueError $exception) { + $res_str .= ": " . $exception->getMessage() . "\n"; + } } else { $res_str .= " before flag is " . ( $test[2] ? "TRUE" : "FALSE" ); - $result = grapheme_strstr($test[0], $test[1], $test[2]); + try { + $result = grapheme_strstr($test[0], $test[1], $test[2]); + } catch (ValueError $exception) { + $res_str .= ": " . $exception->getMessage() . "\n"; + } } $res_str .= " = "; if ( $result === false ) { @@ -957,7 +973,8 @@ find "a%CC%8ABca%CC%8A" in "o%CC%88a%CC%8AaA%CC%8AbCa%CC%8Adef" - grapheme_strri function grapheme_substr($string, $start, $length = -1) {} -substring of "abc" from "3" - grapheme_substr = false == false +substring of "abc" from "3" - grapheme_substr: grapheme_substr(): Argument #2 ($start) must be contained in argument #1 ($string) + = 3 == false **FAILED** substring of "aa%CC%8Abco%CC%88" from "5" - grapheme_substr = false == false substring of "aoa%CC%8Abco%CC%88O" from "2" - grapheme_substr = a%CC%8Abco%CC%88O == a%CC%8Abco%CC%88O substring of "o%CC%88a%CC%8AaA%CC%8Abc" from "2" - grapheme_substr = aA%CC%8Abc == aA%CC%8Abc @@ -966,14 +983,17 @@ substring of "aa%CC%8Abco%CC%88" from "5" - grapheme_substr = false == false substring of "aa%CC%8AbcO%CC%88" from "4" - grapheme_substr = O%CC%88 == O%CC%88 substring of "o%CC%88aa%CC%8Abc" from "2" - grapheme_substr = a%CC%8Abc == a%CC%8Abc substring of "aA%CC%8Abc" from "1" - grapheme_substr = A%CC%8Abc == A%CC%8Abc -substring of "Abc" from "-5" - grapheme_substr = false == false +substring of "Abc" from "-5" - grapheme_substr: grapheme_substr(): Argument #2 ($start) must be contained in argument #1 ($string) + = A%CC%8Abc == false **FAILED** substring of "a%CC%8Abc" from "3" - grapheme_substr = false == false -substring of "abc" from "4" - grapheme_substr = false == false +substring of "abc" from "4" - grapheme_substr: grapheme_substr(): Argument #2 ($start) must be contained in argument #1 ($string) + = false == false substring of "abC" from "2" - grapheme_substr = C == C substring of "abc" from "1" - grapheme_substr = bc == bc substring of "Abc" from "1" - grapheme_substr with length 1 = b == b substring of "abc" from "0" - grapheme_substr with length 2 = ab == ab -substring of "Abc" from "-4" - grapheme_substr with length 1 = false == false +substring of "Abc" from "-4" - grapheme_substr with length 1: grapheme_substr(): Argument #2 ($start) must be contained in argument #1 ($string) + = ab == false **FAILED** substring of "ababc" from "1" - grapheme_substr with length 2 = ba == ba substring of "ababc" from "0" - grapheme_substr with length 10 = ababc == ababc substring of "aa%CC%8Abco%CC%88Opq" from "0" - grapheme_substr with length 10 = aa%CC%8Abco%CC%88Opq == aa%CC%8Abco%CC%88Opq @@ -991,7 +1011,8 @@ substring of "aa%CC%8Abco%CC%88Opq" from "0" - grapheme_substr with length -5 = substring of "aa%CC%8Abco%CC%88Opq" from "0" - grapheme_substr with length -6 = aa%CC%8A == aa%CC%8A substring of "aa%CC%8Abco%CC%88Opq" from "0" - grapheme_substr with length -7 = a == a substring of "aa%CC%8Abco%CC%88Opq" from "0" - grapheme_substr with length -8 = == -substring of "aa%CC%8Abco%CC%88Opq" from "0" - grapheme_substr with length -9 = false == false +substring of "aa%CC%8Abco%CC%88Opq" from "0" - grapheme_substr with length -9: grapheme_substr(): Argument #3 ($length) must be contained in argument #1 ($string) + = == false **FAILED** substring of "aa%CC%8Abco%CC%88Opq" from "-8" - grapheme_substr = aa%CC%8Abco%CC%88Opq == aa%CC%8Abco%CC%88Opq substring of "aa%CC%8Abco%CC%88Opq" from "-7" - grapheme_substr = a%CC%8Abco%CC%88Opq == a%CC%8Abco%CC%88Opq substring of "aa%CC%8Abco%CC%88Opq" from "-6" - grapheme_substr = bco%CC%88Opq == bco%CC%88Opq @@ -1000,7 +1021,8 @@ substring of "aa%CC%8Abco%CC%88Opq" from "-4" - grapheme_substr = o%CC%88Opq == substring of "aa%CC%8Abco%CC%88Opq" from "-3" - grapheme_substr = Opq == Opq substring of "aa%CC%8Abco%CC%88Opq" from "-2" - grapheme_substr = pq == pq substring of "aa%CC%8Abco%CC%88Opq" from "-1" - grapheme_substr = q == q -substring of "aa%CC%8Abco%CC%88Opq" from "-999" - grapheme_substr = false == false +substring of "aa%CC%8Abco%CC%88Opq" from "-999" - grapheme_substr: grapheme_substr(): Argument #2 ($start) must be contained in argument #1 ($string) + = q == false **FAILED** substring of "aa%CC%8Abco%CC%88Opq" from "-8" - grapheme_substr with length 8 = aa%CC%8Abco%CC%88Opq == aa%CC%8Abco%CC%88Opq substring of "aa%CC%8Abco%CC%88Opq" from "-8" - grapheme_substr with length 7 = aa%CC%8Abco%CC%88Op == aa%CC%8Abco%CC%88Op substring of "aa%CC%8Abco%CC%88Opq" from "-8" - grapheme_substr with length 6 = aa%CC%8Abco%CC%88O == aa%CC%8Abco%CC%88O @@ -1010,7 +1032,8 @@ substring of "aa%CC%8Abco%CC%88Opq" from "-8" - grapheme_substr with length 3 = substring of "aa%CC%8Abco%CC%88Opq" from "-8" - grapheme_substr with length 2 = aa%CC%8A == aa%CC%8A substring of "aa%CC%8Abco%CC%88Opq" from "-8" - grapheme_substr with length 1 = a == a substring of "aa%CC%8Abco%CC%88Opq" from "-8" - grapheme_substr with length 0 = == -substring of "aa%CC%8Abco%CC%88Opq" from "-8" - grapheme_substr with length -999 = false == false +substring of "aa%CC%8Abco%CC%88Opq" from "-8" - grapheme_substr with length -999: grapheme_substr(): Argument #3 ($length) must be contained in argument #1 ($string) + = == false **FAILED** substring of "aa%CC%8Abco%CC%88Opq" from "-8" - grapheme_substr with length -1 = aa%CC%8Abco%CC%88Op == aa%CC%8Abco%CC%88Op substring of "aa%CC%8Abco%CC%88Opq" from "-8" - grapheme_substr with length -2 = aa%CC%8Abco%CC%88O == aa%CC%8Abco%CC%88O substring of "aa%CC%8Abco%CC%88Opq" from "-8" - grapheme_substr with length -3 = aa%CC%8Abco%CC%88 == aa%CC%8Abco%CC%88 @@ -1019,7 +1042,8 @@ substring of "aa%CC%8Abco%CC%88Opq" from "-8" - grapheme_substr with length -5 = substring of "aa%CC%8Abco%CC%88Opq" from "-8" - grapheme_substr with length -6 = aa%CC%8A == aa%CC%8A substring of "aa%CC%8Abco%CC%88Opq" from "-8" - grapheme_substr with length -7 = a == a substring of "aa%CC%8Abco%CC%88Opq" from "-8" - grapheme_substr with length -8 = == -substring of "aa%CC%8Abco%CC%88Opq" from "-8" - grapheme_substr with length -9 = false == false +substring of "aa%CC%8Abco%CC%88Opq" from "-8" - grapheme_substr with length -9: grapheme_substr(): Argument #3 ($length) must be contained in argument #1 ($string) + = == false **FAILED** function grapheme_strstr($haystack, $needle, $before_needle = FALSE) {} diff --git a/ext/intl/tests/grapheme2.phpt b/ext/intl/tests/grapheme2.phpt index 4595b781286ec..90af00732fa7f 100644 --- a/ext/intl/tests/grapheme2.phpt +++ b/ext/intl/tests/grapheme2.phpt @@ -397,23 +397,27 @@ function ut_main() ); foreach( $tests as $test ) { - $arg0 = urlencode($test[0]); - $res_str .= "substring of \"$arg0\" from \"$test[1]\" - grapheme_substr"; - if ( 3 == count( $test ) ) { - $result = grapheme_substr($test[0], $test[1]); - } - else { - $res_str .= " with length $test[2]"; - $result = grapheme_substr($test[0], $test[1], $test[2]); - } - $res_str .= " = "; - if ( $result === false ) { - $res_str .= 'false'; - } - else { - $res_str .= urlencode($result); + try { + $arg0 = urlencode($test[0]); + $res_str .= "substring of \"$arg0\" from \"$test[1]\" - grapheme_substr"; + if ( 3 == count( $test ) ) { + $result = grapheme_substr($test[0], $test[1]); + } + else { + $res_str .= " with length $test[2]"; + $result = grapheme_substr($test[0], $test[1], $test[2]); + } + $res_str .= " = "; + if ( $result === false ) { + $res_str .= 'false'; + } + else { + $res_str .= urlencode($result); + } + $res_str .= " == " . urlencode($test[count($test)-1]) . check_result($result, $test[count($test)-1]) . "\n"; + } catch (ValueError $exception) { + $res_str .= ": " . $exception->getMessage() . "\n"; } - $res_str .= " == " . urlencode($test[count($test)-1]) . check_result($result, $test[count($test)-1]) . "\n"; } @@ -957,7 +961,7 @@ find "a%CC%8ABca%CC%8A" in "o%CC%88a%CC%8AaA%CC%8AbCa%CC%8Adef" - grapheme_strri function grapheme_substr($string, $start, $length = -1) {} -substring of "abc" from "3" - grapheme_substr = false == false +substring of "abc" from "3" - grapheme_substr: grapheme_substr(): Argument #2 ($start) must be contained in argument #1 ($string) substring of "aa%CC%8Abco%CC%88" from "5" - grapheme_substr = false == false substring of "aoa%CC%8Abco%CC%88O" from "2" - grapheme_substr = a%CC%8Abco%CC%88O == a%CC%8Abco%CC%88O substring of "o%CC%88a%CC%8AaA%CC%8Abc" from "2" - grapheme_substr = aA%CC%8Abc == aA%CC%8Abc @@ -966,14 +970,14 @@ substring of "aa%CC%8Abco%CC%88" from "5" - grapheme_substr = false == false substring of "aa%CC%8AbcO%CC%88" from "4" - grapheme_substr = O%CC%88 == O%CC%88 substring of "o%CC%88aa%CC%8Abc" from "2" - grapheme_substr = a%CC%8Abc == a%CC%8Abc substring of "aA%CC%8Abc" from "1" - grapheme_substr = A%CC%8Abc == A%CC%8Abc -substring of "Abc" from "-5" - grapheme_substr = false == false +substring of "Abc" from "-5" - grapheme_substr: grapheme_substr(): Argument #2 ($start) must be contained in argument #1 ($string) substring of "a%CC%8Abc" from "3" - grapheme_substr = false == false -substring of "abc" from "4" - grapheme_substr = false == false +substring of "abc" from "4" - grapheme_substr: grapheme_substr(): Argument #2 ($start) must be contained in argument #1 ($string) substring of "abC" from "2" - grapheme_substr = C == C substring of "abc" from "1" - grapheme_substr = bc == bc substring of "Abc" from "1" - grapheme_substr with length 1 = b == b substring of "abc" from "0" - grapheme_substr with length 2 = ab == ab -substring of "Abc" from "-4" - grapheme_substr with length 1 = false == false +substring of "Abc" from "-4" - grapheme_substr with length 1: grapheme_substr(): Argument #2 ($start) must be contained in argument #1 ($string) substring of "ababc" from "1" - grapheme_substr with length 2 = ba == ba substring of "ababc" from "0" - grapheme_substr with length 10 = ababc == ababc substring of "aa%CC%8Abco%CC%88Opq" from "0" - grapheme_substr with length 10 = aa%CC%8Abco%CC%88Opq == aa%CC%8Abco%CC%88Opq @@ -991,7 +995,7 @@ substring of "aa%CC%8Abco%CC%88Opq" from "0" - grapheme_substr with length -5 = substring of "aa%CC%8Abco%CC%88Opq" from "0" - grapheme_substr with length -6 = aa%CC%8A == aa%CC%8A substring of "aa%CC%8Abco%CC%88Opq" from "0" - grapheme_substr with length -7 = a == a substring of "aa%CC%8Abco%CC%88Opq" from "0" - grapheme_substr with length -8 = == -substring of "aa%CC%8Abco%CC%88Opq" from "0" - grapheme_substr with length -9 = false == false +substring of "aa%CC%8Abco%CC%88Opq" from "0" - grapheme_substr with length -9: grapheme_substr(): Argument #3 ($length) must be contained in argument #1 ($string) substring of "aa%CC%8Abco%CC%88Opq" from "-8" - grapheme_substr = aa%CC%8Abco%CC%88Opq == aa%CC%8Abco%CC%88Opq substring of "aa%CC%8Abco%CC%88Opq" from "-7" - grapheme_substr = a%CC%8Abco%CC%88Opq == a%CC%8Abco%CC%88Opq substring of "aa%CC%8Abco%CC%88Opq" from "-6" - grapheme_substr = bco%CC%88Opq == bco%CC%88Opq @@ -1000,7 +1004,7 @@ substring of "aa%CC%8Abco%CC%88Opq" from "-4" - grapheme_substr = o%CC%88Opq == substring of "aa%CC%8Abco%CC%88Opq" from "-3" - grapheme_substr = Opq == Opq substring of "aa%CC%8Abco%CC%88Opq" from "-2" - grapheme_substr = pq == pq substring of "aa%CC%8Abco%CC%88Opq" from "-1" - grapheme_substr = q == q -substring of "aa%CC%8Abco%CC%88Opq" from "-999" - grapheme_substr = false == false +substring of "aa%CC%8Abco%CC%88Opq" from "-999" - grapheme_substr: grapheme_substr(): Argument #2 ($start) must be contained in argument #1 ($string) substring of "aa%CC%8Abco%CC%88Opq" from "-8" - grapheme_substr with length 8 = aa%CC%8Abco%CC%88Opq == aa%CC%8Abco%CC%88Opq substring of "aa%CC%8Abco%CC%88Opq" from "-8" - grapheme_substr with length 7 = aa%CC%8Abco%CC%88Op == aa%CC%8Abco%CC%88Op substring of "aa%CC%8Abco%CC%88Opq" from "-8" - grapheme_substr with length 6 = aa%CC%8Abco%CC%88O == aa%CC%8Abco%CC%88O @@ -1010,7 +1014,7 @@ substring of "aa%CC%8Abco%CC%88Opq" from "-8" - grapheme_substr with length 3 = substring of "aa%CC%8Abco%CC%88Opq" from "-8" - grapheme_substr with length 2 = aa%CC%8A == aa%CC%8A substring of "aa%CC%8Abco%CC%88Opq" from "-8" - grapheme_substr with length 1 = a == a substring of "aa%CC%8Abco%CC%88Opq" from "-8" - grapheme_substr with length 0 = == -substring of "aa%CC%8Abco%CC%88Opq" from "-8" - grapheme_substr with length -999 = false == false +substring of "aa%CC%8Abco%CC%88Opq" from "-8" - grapheme_substr with length -999: grapheme_substr(): Argument #3 ($length) must be contained in argument #1 ($string) substring of "aa%CC%8Abco%CC%88Opq" from "-8" - grapheme_substr with length -1 = aa%CC%8Abco%CC%88Op == aa%CC%8Abco%CC%88Op substring of "aa%CC%8Abco%CC%88Opq" from "-8" - grapheme_substr with length -2 = aa%CC%8Abco%CC%88O == aa%CC%8Abco%CC%88O substring of "aa%CC%8Abco%CC%88Opq" from "-8" - grapheme_substr with length -3 = aa%CC%8Abco%CC%88 == aa%CC%8Abco%CC%88 @@ -1019,7 +1023,7 @@ substring of "aa%CC%8Abco%CC%88Opq" from "-8" - grapheme_substr with length -5 = substring of "aa%CC%8Abco%CC%88Opq" from "-8" - grapheme_substr with length -6 = aa%CC%8A == aa%CC%8A substring of "aa%CC%8Abco%CC%88Opq" from "-8" - grapheme_substr with length -7 = a == a substring of "aa%CC%8Abco%CC%88Opq" from "-8" - grapheme_substr with length -8 = == -substring of "aa%CC%8Abco%CC%88Opq" from "-8" - grapheme_substr with length -9 = false == false +substring of "aa%CC%8Abco%CC%88Opq" from "-8" - grapheme_substr with length -9: grapheme_substr(): Argument #3 ($length) must be contained in argument #1 ($string) function grapheme_strstr($haystack, $needle, $before_needle = FALSE) {} diff --git a/ext/intl/tests/grapheme_empty.phpt b/ext/intl/tests/grapheme_empty.phpt new file mode 100644 index 0000000000000..31b3d8cc4393f --- /dev/null +++ b/ext/intl/tests/grapheme_empty.phpt @@ -0,0 +1,88 @@ +--TEST-- +Test grapheme_strpos-alike functions with empty needle +--SKIPIF-- + +--FILE-- +getMessage() . "\n"; +} + +try { + var_dump(grapheme_strpos("abc", "")); +} catch (ValueError $exception) { + echo $exception->getMessage() . "\n"; +} + +try { + var_dump(grapheme_strpos("abc", "", -1)); +} catch (ValueError $exception) { + echo $exception->getMessage() . "\n"; +} + +try { + var_dump(grapheme_stripos("abc", "")); +} catch (ValueError $exception) { + echo $exception->getMessage() . "\n"; +} + +try { + var_dump(grapheme_stripos("abc", "", -1)); +} catch (ValueError $exception) { + echo $exception->getMessage() . "\n"; +} + +try { + var_dump(grapheme_strrpos("abc", "")); +} catch (ValueError $exception) { + echo $exception->getMessage() . "\n"; +} + +try { + var_dump(grapheme_strrpos("abc", "", -1)); +} catch (ValueError $exception) { + echo $exception->getMessage() . "\n"; +} + +try { + var_dump(grapheme_strripos("abc", "")); +} catch (ValueError $exception) { + echo $exception->getMessage() . "\n"; +} + +try { + var_dump(grapheme_strripos("abc", "", 1)); +} catch (ValueError $exception) { + echo $exception->getMessage() . "\n"; +} + +try { + var_dump(grapheme_strstr("abc", "")); +} catch (ValueError $exception) { + echo $exception->getMessage() . "\n"; +} + +try { + var_dump(grapheme_stristr("abc", "")); +} catch (ValueError $exception) { + echo $exception->getMessage() . "\n"; +} + +?> +--EXPECT-- +grapheme_strpos(): Argument #2 ($needle) cannot be empty +grapheme_strpos(): Argument #2 ($needle) cannot be empty +grapheme_strpos(): Argument #2 ($needle) cannot be empty +grapheme_stripos(): Argument #2 ($needle) cannot be empty +grapheme_stripos(): Argument #2 ($needle) cannot be empty +grapheme_strrpos(): Argument #2 ($needle) cannot be empty +grapheme_strrpos(): Argument #2 ($needle) cannot be empty +grapheme_strripos(): Argument #2 ($needle) cannot be empty +grapheme_strripos(): Argument #2 ($needle) cannot be empty +grapheme_strstr(): Argument #2 ($needle) cannot be empty +grapheme_stristr(): Argument #2 ($needle) cannot be empty diff --git a/ext/intl/tests/locale_compose_locale.phpt b/ext/intl/tests/locale_compose_locale.phpt index e09e104c850ec..653fc450d5841 100644 --- a/ext/intl/tests/locale_compose_locale.phpt +++ b/ext/intl/tests/locale_compose_locale.phpt @@ -113,14 +113,17 @@ function ut_main() $res_str .= $valKey ."->".$valValue." " ; } */ - - $locale = ut_loc_locale_compose( $value); - $res_str .= "\n\nComposed Locale: "; - if( $locale){ - $res_str .= "$locale"; - }else{ - $res_str .= "No values found from Locale compose due to the following error:\n"; - $res_str .= intl_get_error_message() ; + try { + $locale = ut_loc_locale_compose( $value); + $res_str .= "\n\nComposed Locale: "; + if( $locale){ + $res_str .= "$locale"; + }else{ + $res_str .= "No values found from Locale compose due to the following error:\n"; + $res_str .= intl_get_error_message() ; + } + } catch (ValueError $exception) { + echo $exception->getMessage() . "\n"; } } @@ -135,6 +138,9 @@ ut_run(); ?> --EXPECT-- +Locale::composeLocale(): Argument #1 ($subtags) must contain a "language" key +locale_compose(): Argument #1 ($subtags) must contain a "language" key + ------------ Input Array name is : loc1 @@ -169,9 +175,6 @@ Input Array name is : loc8 Composed Locale: en_lng_ing_Hans_CN_nedis_rozaj_x_prv1_prv2 ------------ Input Array name is : loc9 - -Composed Locale: No values found from Locale compose due to the following error: -locale_compose: parameter array does not contain 'language' tag.: U_ILLEGAL_ARGUMENT_ERROR ------------ Input Array name is : loc10 diff --git a/ext/intl/tests/transliterator_transliterate_error.phpt b/ext/intl/tests/transliterator_transliterate_error.phpt index d33e8b3f37fe5..f59b8507985e0 100644 --- a/ext/intl/tests/transliterator_transliterate_error.phpt +++ b/ext/intl/tests/transliterator_transliterate_error.phpt @@ -11,7 +11,12 @@ $tr = Transliterator::create("latin"); //Arguments var_dump(transliterator_transliterate($tr,"str",7)); -var_dump(transliterator_transliterate($tr,"str",7,6)); + +try { + transliterator_transliterate($tr,"str",7,6); +} catch (ValueError $exception) { + echo $exception->getMessage() . "\n"; +} //bad UTF-8 transliterator_transliterate($tr, "\x80\x03"); @@ -21,9 +26,7 @@ echo "Done.\n"; --EXPECTF-- Warning: transliterator_transliterate(): transliterator_transliterate: Neither "start" nor the "end" arguments can exceed the number of UTF-16 code units (in this case, 3) in %s on line %d bool(false) - -Warning: transliterator_transliterate(): transliterator_transliterate: "start" argument should be non-negative and not bigger than "end" (if defined) in %s on line %d -bool(false) +transliterator_transliterate(): Argument #2 ($subject) must be less than or equal to argument #3 ($end) Warning: transliterator_transliterate(): String conversion of string to UTF-16 failed in %s on line %d Done. diff --git a/ext/intl/transliterator/transliterator_class.c b/ext/intl/transliterator/transliterator_class.c index 9b57cf16bb09d..e444f0eef430a 100644 --- a/ext/intl/transliterator/transliterator_class.c +++ b/ext/intl/transliterator/transliterator_class.c @@ -179,8 +179,7 @@ static zend_object *Transliterator_clone_obj( zend_object *object ) else { /* We shouldn't have unconstructed objects in the first place */ - php_error_docref( NULL, E_WARNING, - "Cloning unconstructed transliterator." ); + zend_throw_error(NULL, "Unconstructed Transliterator object cannot be cloned"); } return ret_val; @@ -215,7 +214,7 @@ static zval *Transliterator_read_property( zend_object *object, zend_string *nam ( zend_binary_strcmp( "id", sizeof( "id" ) - 1, ZSTR_VAL( name ), ZSTR_LEN( name ) ) == 0 ) ) { - php_error_docref(NULL, E_WARNING, "The property \"id\" is read-only" ); + zend_throw_error(NULL, "Transliterator::$id is read-only"); retval = &EG( uninitialized_zval ); } else @@ -243,7 +242,7 @@ static zval *Transliterator_write_property( zend_object *object, zend_string *na ( zend_binary_strcmp( "id", sizeof( "id" ) - 1, ZSTR_VAL( name ), ZSTR_LEN( name ) ) == 0 ) ) { - php_error_docref(NULL, E_WARNING, "The property \"id\" is read-only" ); + zend_throw_error(NULL, "Transliterator::$id is read-only"); } else { diff --git a/ext/intl/transliterator/transliterator_methods.c b/ext/intl/transliterator/transliterator_methods.c index faf61e4914580..1a0e2bfffcf58 100644 --- a/ext/intl/transliterator/transliterator_methods.c +++ b/ext/intl/transliterator/transliterator_methods.c @@ -36,8 +36,7 @@ static int create_transliterator( char *str_id, size_t str_id_len, zend_long dir if( ( direction != TRANSLITERATOR_FORWARD ) && (direction != TRANSLITERATOR_REVERSE ) ) { - intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, - "transliterator_create: invalid direction", 0 ); + zend_argument_value_error(2, "must be either Transliterator::FORWARD or Transliterator::REVERSE"); return FAILURE; } @@ -143,9 +142,8 @@ PHP_FUNCTION( transliterator_create_from_rules ) if( ( direction != TRANSLITERATOR_FORWARD ) && (direction != TRANSLITERATOR_REVERSE ) ) { - intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, - "transliterator_create_from_rules: invalid direction", 0 ); - RETURN_NULL(); + zend_argument_value_error(2, "must be either Transliterator::FORWARD or Transliterator::REVERSE"); + RETURN_THROWS(); } object = return_value; @@ -302,10 +300,11 @@ PHP_FUNCTION( transliterator_transliterate ) res = create_transliterator(ZSTR_VAL(arg1_str), ZSTR_LEN(arg1_str), TRANSLITERATOR_FORWARD, object); if( res == FAILURE ) { - zend_string *message = intl_error_get_message( NULL ); - php_error_docref(NULL, E_WARNING, "Could not create " - "transliterator with ID \"%s\" (%s)", ZSTR_VAL(arg1_str), ZSTR_VAL(message) ); - zend_string_free( message ); + if (!EG(exception)) { + zend_string *message = intl_error_get_message( NULL ); + php_error_docref(NULL, E_WARNING, "Could not create transliterator with ID \"%s\" (%s)", ZSTR_VAL(arg1_str), ZSTR_VAL(message) ); + zend_string_free( message ); + } ZVAL_UNDEF(&tmp_object); /* don't set U_ILLEGAL_ARGUMENT_ERROR to allow fetching of inner error */ goto cleanup; @@ -318,21 +317,18 @@ PHP_FUNCTION( transliterator_transliterate ) RETURN_THROWS(); } - if( limit < -1 ) - { - intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, - "transliterator_transliterate: \"end\" argument should be " - "either non-negative or -1", 0 ); - RETVAL_FALSE; + if (limit < -1) { + zend_argument_value_error(object ? 3 : 4, "must be greater than or equal to -1"); goto cleanup_object; } - if( start < 0 || ((limit != -1 ) && (start > limit )) ) - { - intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, - "transliterator_transliterate: \"start\" argument should be " - "non-negative and not bigger than \"end\" (if defined)", 0 ); - RETVAL_FALSE; + if (start < 0) { + zend_argument_value_error(object ? 2 : 3, "must be greater than or equal to 0"); + goto cleanup_object; + } + + if (limit != -1 && start > limit) { + zend_argument_value_error(object ? 2 : 3, "must be less than or equal to argument #%d ($end)", object ? 3 : 4); goto cleanup_object; } @@ -358,7 +354,6 @@ PHP_FUNCTION( transliterator_transliterate ) msg, 1 ); efree( msg ); } - RETVAL_FALSE; goto cleanup; } From 4a2ae84188b904d24c7c26bf2696507c2feb6947 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 7 Sep 2020 21:35:48 +0300 Subject: [PATCH 85/87] Add "const". Move constant strings to read-only memory. --- Zend/zend_strtod.c | 2 +- ext/calendar/calendar.c | 2 +- ext/iconv/iconv.c | 2 +- ext/session/session.c | 6 +++--- ext/soap/php_encoding.c | 2 +- ext/standard/crypt_blowfish.c | 4 ++-- ext/standard/filters.c | 4 ++-- ext/standard/math.c | 4 ++-- ext/standard/php_crypt_r.c | 2 +- ext/standard/soundex.c | 2 +- ext/standard/string.c | 2 +- ext/standard/url.c | 2 +- main/strlcat.c | 2 +- main/strlcpy.c | 2 +- 14 files changed, 19 insertions(+), 19 deletions(-) diff --git a/Zend/zend_strtod.c b/Zend/zend_strtod.c index 2228e2262cf1f..e88fbd001fef6 100644 --- a/Zend/zend_strtod.c +++ b/Zend/zend_strtod.c @@ -1563,7 +1563,7 @@ hexdig_init(void) /* Use of hexdig_init omitted 20121220 to avoid a */ htinit(hexdig, USC "ABCDEF", 0x10 + 10); } #else -static unsigned char hexdig[256] = { +static const unsigned char hexdig[256] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, diff --git a/ext/calendar/calendar.c b/ext/calendar/calendar.c index 4de31ccf7792a..5dd4f1ef49eb5 100644 --- a/ext/calendar/calendar.c +++ b/ext/calendar/calendar.c @@ -101,7 +101,7 @@ enum { CAL_MONTH_GREGORIAN_SHORT, CAL_MONTH_GREGORIAN_LONG, /* For heb_number_to_chars escape sequences of אבגדהוזחטיכלמנסעפצקרשת ISO-8859-8 Hebrew alphabet */ -static char alef_bet[25] = "0\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEB\xEC\xEE\xF0\xF1\xF2\xF4\xF6\xF7\xF8\xF9\xFA"; +static const char alef_bet[25] = "0\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEB\xEC\xEE\xF0\xF1\xF2\xF4\xF6\xF7\xF8\xF9\xFA"; #define CAL_JEWISH_ADD_ALAFIM_GERESH 0x2 #define CAL_JEWISH_ADD_ALAFIM 0x4 diff --git a/ext/iconv/iconv.c b/ext/iconv/iconv.c index 92adc97b123b4..89ae1b43a4a77 100644 --- a/ext/iconv/iconv.c +++ b/ext/iconv/iconv.c @@ -1182,7 +1182,7 @@ static php_iconv_err_t _php_iconv_mime_encode(smart_str *pretval, const char *fn smart_str_appendc(pretval, *(char *)p); char_cnt--; } else { - static char qp_digits[] = "0123456789ABCDEF"; + static const char qp_digits[] = "0123456789ABCDEF"; smart_str_appendc(pretval, '='); smart_str_appendc(pretval, qp_digits[(*p >> 4) & 0x0f]); smart_str_appendc(pretval, qp_digits[(*p & 0x0f)]); diff --git a/ext/session/session.c b/ext/session/session.c index 658b7daf9b46b..9336c05be816c 100644 --- a/ext/session/session.c +++ b/ext/session/session.c @@ -260,7 +260,7 @@ static int php_session_decode(zend_string *data) /* {{{ */ * into URLs. */ -static char hexconvtab[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ,-"; +static const char hexconvtab[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ,-"; static void bin_to_readable(unsigned char *in, size_t inlen, char *out, size_t outlen, char nbits) /* {{{ */ { @@ -1102,12 +1102,12 @@ typedef struct { #define ADD_HEADER(a) sapi_add_header(a, strlen(a), 1); #define MAX_STR 512 -static char *month_names[] = { +static const char *month_names[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; -static char *week_days[] = { +static const char *week_days[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" }; diff --git a/ext/soap/php_encoding.c b/ext/soap/php_encoding.c index affc771b0b07d..b3dd853298fbf 100644 --- a/ext/soap/php_encoding.c +++ b/ext/soap/php_encoding.c @@ -940,7 +940,7 @@ static xmlNodePtr to_xml_base64(encodeTypePtr type, zval *data, int style, xmlNo static xmlNodePtr to_xml_hexbin(encodeTypePtr type, zval *data, int style, xmlNodePtr parent) { - static char hexconvtab[] = "0123456789ABCDEF"; + static const char hexconvtab[] = "0123456789ABCDEF"; xmlNodePtr ret, text; unsigned char *str; zval tmp; diff --git a/ext/standard/crypt_blowfish.c b/ext/standard/crypt_blowfish.c index 1f20debf288eb..3806a290aee40 100644 --- a/ext/standard/crypt_blowfish.c +++ b/ext/standard/crypt_blowfish.c @@ -356,10 +356,10 @@ static BF_ctx BF_init_state = { } }; -static unsigned char BF_itoa64[64 + 1] = +static const unsigned char BF_itoa64[64 + 1] = "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; -static unsigned char BF_atoi64[0x60] = { +static const unsigned char BF_atoi64[0x60] = { 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 0, 1, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 64, 64, 64, 64, 64, 64, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, diff --git a/ext/standard/filters.c b/ext/standard/filters.c index 2d5d0dd150432..d5e6564443906 100644 --- a/ext/standard/filters.c +++ b/ext/standard/filters.c @@ -208,7 +208,7 @@ typedef struct _php_conv_base64_encode { static php_conv_err_t php_conv_base64_encode_convert(php_conv_base64_encode *inst, const char **in_p, size_t *in_left, char **out_p, size_t *out_left); static void php_conv_base64_encode_dtor(php_conv_base64_encode *inst); -static unsigned char b64_tbl_enc[256] = { +static const unsigned char b64_tbl_enc[256] = { 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P', 'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f', 'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v', @@ -656,7 +656,7 @@ static php_conv_err_t php_conv_qprint_encode_convert(php_conv_qprint_encode *ins unsigned int lb_cnt; unsigned int trail_ws; int opts; - static char qp_digits[] = "0123456789ABCDEF"; + static const char qp_digits[] = "0123456789ABCDEF"; line_ccnt = inst->line_ccnt; opts = inst->opts; diff --git a/ext/standard/math.c b/ext/standard/math.c index c5e0234fdeefe..2aedcc259d2cc 100644 --- a/ext/standard/math.c +++ b/ext/standard/math.c @@ -797,7 +797,7 @@ PHPAPI void _php_math_basetozval(zend_string *str, int base, zval *ret) */ PHPAPI zend_string * _php_math_longtobase(zend_long arg, int base) { - static char digits[] = "0123456789abcdefghijklmnopqrstuvwxyz"; + static const char digits[] = "0123456789abcdefghijklmnopqrstuvwxyz"; char buf[(sizeof(zend_ulong) << 3) + 1]; char *ptr, *end; zend_ulong value; @@ -828,7 +828,7 @@ PHPAPI zend_string * _php_math_longtobase(zend_long arg, int base) */ PHPAPI zend_string * _php_math_zvaltobase(zval *arg, int base) { - static char digits[] = "0123456789abcdefghijklmnopqrstuvwxyz"; + static const char digits[] = "0123456789abcdefghijklmnopqrstuvwxyz"; if ((Z_TYPE_P(arg) != IS_LONG && Z_TYPE_P(arg) != IS_DOUBLE) || base < 2 || base > 36) { return ZSTR_EMPTY_ALLOC(); diff --git a/ext/standard/php_crypt_r.c b/ext/standard/php_crypt_r.c index 1e55f5f9b5f79..f8dffe9cc52e5 100644 --- a/ext/standard/php_crypt_r.c +++ b/ext/standard/php_crypt_r.c @@ -83,7 +83,7 @@ void _crypt_extended_init_r(void) #define MD5_MAGIC "$1$" #define MD5_MAGIC_LEN 3 -static unsigned char itoa64[] = /* 0 ... 63 => ascii - 64 */ +static const unsigned char itoa64[] = /* 0 ... 63 => ascii - 64 */ "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; /* Convert a 16/32 bit integer to Base64 string representation */ diff --git a/ext/standard/soundex.c b/ext/standard/soundex.c index afd16142e30d3..5342139f98d00 100644 --- a/ext/standard/soundex.c +++ b/ext/standard/soundex.c @@ -28,7 +28,7 @@ PHP_FUNCTION(soundex) size_t i, _small, str_len, code, last; char soundex[4 + 1]; - static char soundex_table[26] = + static const char soundex_table[26] = {0, /* A */ '1', /* B */ '2', /* C */ diff --git a/ext/standard/string.c b/ext/standard/string.c index 915b6cff5386b..a50ba01fd6fce 100644 --- a/ext/standard/string.c +++ b/ext/standard/string.c @@ -88,7 +88,7 @@ void register_string_constants(INIT_FUNC_ARGS) int php_tag_find(char *tag, size_t len, const char *set); /* this is read-only, so it's ok */ -ZEND_SET_ALIGNED(16, static char hexconvtab[]) = "0123456789abcdef"; +ZEND_SET_ALIGNED(16, static const char hexconvtab[]) = "0123456789abcdef"; /* localeconv mutex */ #ifdef ZTS diff --git a/ext/standard/url.c b/ext/standard/url.c index f710b2fe8a643..1d4869ecd48e5 100644 --- a/ext/standard/url.c +++ b/ext/standard/url.c @@ -442,7 +442,7 @@ static int php_htoi(char *s) For added safety, we only leave -_. unencoded. */ -static unsigned char hexchars[] = "0123456789ABCDEF"; +static const unsigned char hexchars[] = "0123456789ABCDEF"; static zend_always_inline zend_string *php_url_encode_impl(const char *s, size_t len, zend_bool raw) /* {{{ */ { register unsigned char c; diff --git a/main/strlcat.c b/main/strlcat.c index 3c18360e962c5..5556bc31ae94b 100644 --- a/main/strlcat.c +++ b/main/strlcat.c @@ -48,7 +48,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static char *rcsid = "$OpenBSD: strlcat.c,v 1.17 2016/10/14 18:19:04 dtucker Exp $"; +static const char *rcsid = "$OpenBSD: strlcat.c,v 1.17 2016/10/14 18:19:04 dtucker Exp $"; #endif /* LIBC_SCCS and not lint */ #include diff --git a/main/strlcpy.c b/main/strlcpy.c index 55959b2f3a2b3..ef397e267ed70 100644 --- a/main/strlcpy.c +++ b/main/strlcpy.c @@ -48,7 +48,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static char *rcsid = "$OpenBSD: strlcpy.c,v 1.15 2016/10/16 17:37:39 dtucker Exp $"; +static const char *rcsid = "$OpenBSD: strlcpy.c,v 1.15 2016/10/16 17:37:39 dtucker Exp $"; #endif /* LIBC_SCCS and not lint */ #include From af0ba0b2d3641d3372aebbe471c4b194dc3f3440 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Mon, 7 Sep 2020 22:57:09 +0200 Subject: [PATCH 86/87] Reduce input size limit in execute fuzzer We only have 4 Zend test cases > 8k. Large inputs tend to just make things slower. --- sapi/fuzzer/fuzzer-execute.c | 2 +- sapi/fuzzer/generate_execute_corpus.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sapi/fuzzer/fuzzer-execute.c b/sapi/fuzzer/fuzzer-execute.c index 95afab1a3e7a0..1259acb31e10f 100644 --- a/sapi/fuzzer/fuzzer-execute.c +++ b/sapi/fuzzer/fuzzer-execute.c @@ -20,7 +20,7 @@ #include "fuzzer-sapi.h" #define MAX_STEPS 1000 -#define MAX_SIZE (16 * 1024) +#define MAX_SIZE (8 * 1024) static uint32_t steps_left; /* Because the fuzzer is always compiled with clang, diff --git a/sapi/fuzzer/generate_execute_corpus.php b/sapi/fuzzer/generate_execute_corpus.php index c1d8d05cb272d..dd6424127aed6 100644 --- a/sapi/fuzzer/generate_execute_corpus.php +++ b/sapi/fuzzer/generate_execute_corpus.php @@ -13,7 +13,7 @@ if ($argc >= 4) { $maxLen = (int) $argv[3]; } else { - $maxLen = 16 * 1024; + $maxLen = 8 * 1024; } $it = new RecursiveIteratorIterator( From 8a49310f4e1aae962aaecc8bfafaf39877167c52 Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Sat, 5 Sep 2020 16:33:22 +0200 Subject: [PATCH 87/87] Adjust assignment line number for match Otherwise the assignment will have the same number as the default arm which will 1. mis-trigger a breakpoint and 2. mark the line as covered even when it isn't. Closes GH-6083 --- Zend/zend_compile.c | 1 + sapi/phpdbg/tests/match_breakpoints_001.phpt | 30 +++++++++++++++++ sapi/phpdbg/tests/match_breakpoints_002.phpt | 32 ++++++++++++++++++ sapi/phpdbg/tests/match_breakpoints_003.phpt | 32 ++++++++++++++++++ sapi/phpdbg/tests/match_breakpoints_004.phpt | 34 ++++++++++++++++++++ 5 files changed, 129 insertions(+) create mode 100644 sapi/phpdbg/tests/match_breakpoints_001.phpt create mode 100644 sapi/phpdbg/tests/match_breakpoints_002.phpt create mode 100644 sapi/phpdbg/tests/match_breakpoints_003.phpt create mode 100644 sapi/phpdbg/tests/match_breakpoints_004.phpt diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 7eb2d79fe72f5..5d1c4a6207a8d 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -3063,6 +3063,7 @@ void zend_compile_assign(znode *result, zend_ast *ast) /* {{{ */ zend_delayed_compile_var(&var_node, var_ast, BP_VAR_W, 0); zend_compile_expr(&expr_node, expr_ast); zend_delayed_compile_end(offset); + CG(zend_lineno) = zend_ast_get_lineno(var_ast); zend_emit_op_tmp(result, ZEND_ASSIGN, &var_node, &expr_node); return; case ZEND_AST_STATIC_PROP: diff --git a/sapi/phpdbg/tests/match_breakpoints_001.phpt b/sapi/phpdbg/tests/match_breakpoints_001.phpt new file mode 100644 index 0000000000000..9ef74179c1e86 --- /dev/null +++ b/sapi/phpdbg/tests/match_breakpoints_001.phpt @@ -0,0 +1,30 @@ +--TEST-- +Test match default breakpoint with variable assignment +--INI-- +opcache.enable_cli=0 +--PHPDBG-- +b 5 +b 10 +r +q +--EXPECTF-- +[Successful compilation of %s.php] +prompt> [Breakpoint #0 added at %s.php:5] +prompt> [Breakpoint #1 added at %s.php:10] +prompt> [Breakpoint #1 at %s.php:10, hits: 1] +>00010: default => 'bar', // breakpoint #1 + 00011: }; + 00012: +prompt> +--FILE-- + 'foo', + default => 'bar', // breakpoint #0 +}; + +$foo = match (1) { + 0 => 'foo', + default => 'bar', // breakpoint #1 +}; diff --git a/sapi/phpdbg/tests/match_breakpoints_002.phpt b/sapi/phpdbg/tests/match_breakpoints_002.phpt new file mode 100644 index 0000000000000..21b0b4ef3a624 --- /dev/null +++ b/sapi/phpdbg/tests/match_breakpoints_002.phpt @@ -0,0 +1,32 @@ +--TEST-- +Test match default breakpoint with property assignment +--INI-- +opcache.enable_cli=0 +--PHPDBG-- +b 7 +b 12 +r +q +--EXPECTF-- +[Successful compilation of %s.php] +prompt> [Breakpoint #0 added at %s.php:7] +prompt> [Breakpoint #1 added at %s.php:12] +prompt> [Breakpoint #1 at %s.php:12, hits: 1] +>00012: default => 'bar', // breakpoint #1 + 00013: }; + 00014: +prompt> +--FILE-- +bar = match (0) { + 0 => 'foo', + default => 'bar', // breakpoint #0 +}; + +$foo->bar = match (1) { + 0 => 'foo', + default => 'bar', // breakpoint #1 +}; diff --git a/sapi/phpdbg/tests/match_breakpoints_003.phpt b/sapi/phpdbg/tests/match_breakpoints_003.phpt new file mode 100644 index 0000000000000..dbd7eb70ab063 --- /dev/null +++ b/sapi/phpdbg/tests/match_breakpoints_003.phpt @@ -0,0 +1,32 @@ +--TEST-- +Test match default breakpoint with dim assignment +--INI-- +opcache.enable_cli=0 +--PHPDBG-- +b 7 +b 12 +r +q +--EXPECTF-- +[Successful compilation of %s.php] +prompt> [Breakpoint #0 added at %s.php:7] +prompt> [Breakpoint #1 added at %s.php:12] +prompt> [Breakpoint #1 at %s.php:12, hits: 1] +>00012: default => 'bar', // breakpoint #1 + 00013: }; + 00014: +prompt> +--FILE-- + 'foo', + default => 'bar', // breakpoint #0 +}; + +$foo->bar = match (1) { + 0 => 'foo', + default => 'bar', // breakpoint #1 +}; diff --git a/sapi/phpdbg/tests/match_breakpoints_004.phpt b/sapi/phpdbg/tests/match_breakpoints_004.phpt new file mode 100644 index 0000000000000..d59555e69240d --- /dev/null +++ b/sapi/phpdbg/tests/match_breakpoints_004.phpt @@ -0,0 +1,34 @@ +--TEST-- +Test match default breakpoint with static variable assignment +--INI-- +opcache.enable_cli=0 +--PHPDBG-- +b 9 +b 14 +r +q +--EXPECTF-- +[Successful compilation of %s.php] +prompt> [Breakpoint #0 added at %s.php:9] +prompt> [Breakpoint #1 added at %s.php:14] +prompt> [Breakpoint #1 at %s.php:14, hits: 1] +>00014: default => 'bar', // breakpoint #1 + 00015: }; + 00016: +prompt> +--FILE-- + 'foo', + default => 'bar', // breakpoint #0 +}; + +Foo::$bar = match (1) { + 0 => 'foo', + default => 'bar', // breakpoint #1 +};