diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 44f68e61ab628..d5f4a8a6f4bb0 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -20,11 +20,13 @@ /ext/curl @adoy /ext/date @derickr /ext/dba @Girgias +/ext/dom @devnexen /ext/ffi @dstogov /ext/gd @devnexen /ext/gettext @devnexen /ext/gmp @Girgias /ext/intl @devnexen +/ext/libxml @devnexen /ext/json @bukka /ext/lexbor @kocsismate /ext/mbstring @alexdowad @youkidearitai @@ -45,10 +47,16 @@ /ext/random @TimWolla @zeriyoshi /ext/reflection @DanielEScherzer /ext/session @Girgias +/ext/simplexml @devnexen +/ext/soap @devnexen /ext/sockets @devnexen /ext/spl @Girgias /ext/standard @bukka /ext/uri @kocsismate @TimWolla +/ext/xml @devnexen +/ext/xmlreader @devnexen +/ext/xmlwriter @devnexen +/ext/xsl @devnexen /main @bukka /sapi/fpm @bukka /Zend/Optimizer @dstogov diff --git a/NEWS b/NEWS index a7ad6778875b7..f5c9cfa755029 100644 --- a/NEWS +++ b/NEWS @@ -133,6 +133,8 @@ PHP NEWS - SPL: . DirectoryIterator key can now work better with filesystem supporting larger directory indexing. (David Carlier) + . Fix bugs GH-8561, GH-8562, GH-8563, and GH-8564 (Fixing various + SplFileObject iterator desync bugs). (iliaal) - Sqlite3: . Fix NUL byte truncation in sqlite3 TEXT column handling. (ndossche) diff --git a/UPGRADING.INTERNALS b/UPGRADING.INTERNALS index 5da8d205be74b..3a24fcce47727 100644 --- a/UPGRADING.INTERNALS +++ b/UPGRADING.INTERNALS @@ -133,6 +133,7 @@ PHP 8.6 INTERNALS UPGRADE NOTES . Dropped session_options parameter from all methods in mysqlnd_auth. The same information is present in conn->options and should be used instead. + . Removed charsets plugin. - ext/session: . php_session_flush() now returns a bool rather than a zend_result. diff --git a/Zend/tests/gh16799.phpt b/Zend/tests/gh16799.phpt index ce1dbd5b16558..d31d1a5705c67 100644 --- a/Zend/tests/gh16799.phpt +++ b/Zend/tests/gh16799.phpt @@ -15,7 +15,12 @@ Test::test(); --EXPECTF-- Fatal error: Uncaught Exception: Use of "static" in callables is deprecated in %s:%d Stack trace: -#0 %s(%d): {closure:%s:%d}(8192, 'Use of "static"...', %s, %d) +#0 %s(%d): {closure:%s}(8192, 'Use of "static"%s', '%s', %d) #1 %s(%d): Test::test() #2 {main} + +Next TypeError: call_user_func(): Argument #1 ($callback) must be a valid callback, (null) in %s:%d +Stack trace: +#0 %s(%d): Test::test() +#1 {main} thrown in %s on line %d diff --git a/Zend/tests/gh_21699.phpt b/Zend/tests/gh_21699.phpt new file mode 100644 index 0000000000000..49b58365dabfb --- /dev/null +++ b/Zend/tests/gh_21699.phpt @@ -0,0 +1,31 @@ +--TEST-- +GH-21699: Assertion failure in shutdown_executor when error handler throws during self:: callable resolution +--FILE-- +test(); +?> +--EXPECTF-- +Fatal error: Uncaught Exception in %s:%d +Stack trace: +#0 %s(%d): {closure:%s}(%d, 'Use of "self" i%s', '%s', %d) +#1 %s(%d): bar->test() +#2 {main} + +Next TypeError: call_user_func(): Argument #1 ($callback) must be a valid callback, (null) in %s:%d +Stack trace: +#0 %s(%d): bar->test() +#1 {main} + thrown in %s on line %d diff --git a/Zend/tests/gh_21699_parent.phpt b/Zend/tests/gh_21699_parent.phpt new file mode 100644 index 0000000000000..73cae41f3f5bd --- /dev/null +++ b/Zend/tests/gh_21699_parent.phpt @@ -0,0 +1,32 @@ +--TEST-- +GH-21699 (parent::): no shutdown_executor trampoline assertion when error handler throws during parent:: callable resolution +--FILE-- +test(); +?> +--EXPECTF-- +Fatal error: Uncaught Exception in %s:%d +Stack trace: +#0 %s(%d): {closure:%s}(%d, 'Use of "parent"%s', '%s', %d) +#1 %s(%d): Child->test() +#2 {main} + +Next TypeError: call_user_func(): Argument #1 ($callback) must be a valid callback, (null) in %s:%d +Stack trace: +#0 %s(%d): Child->test() +#1 {main} + thrown in %s on line %d diff --git a/Zend/tests/gh_21699_static.phpt b/Zend/tests/gh_21699_static.phpt new file mode 100644 index 0000000000000..4d9604ebe77ba --- /dev/null +++ b/Zend/tests/gh_21699_static.phpt @@ -0,0 +1,31 @@ +--TEST-- +GH-21699 (static::): no shutdown_executor trampoline assertion when error handler throws during static:: callable resolution +--FILE-- +test(); +?> +--EXPECTF-- +Fatal error: Uncaught Exception in %s:%d +Stack trace: +#0 %s(%d): {closure:%s}(%d, 'Use of "static"%s', '%s', %d) +#1 %s(%d): bar->test() +#2 {main} + +Next TypeError: call_user_func(): Argument #1 ($callback) must be a valid callback, (null) in %s:%d +Stack trace: +#0 %s(%d): bar->test() +#1 {main} + thrown in %s on line %d diff --git a/Zend/zend_API.c b/Zend/zend_API.c index 7c38779a564af..2541486c492a2 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -3769,6 +3769,10 @@ static bool zend_is_callable_check_class(zend_string *name, zend_class_entry *sc if (error) zend_spprintf(error, 0, "class \"%.*s\" not found", (int)name_len, ZSTR_VAL(name)); } ZSTR_ALLOCA_FREE(lcname, use_heap); + /* User error handlers may throw from deprecations above; do not report callable as valid. */ + if (UNEXPECTED(EG(exception))) { + return false; + } return ret; } /* }}} */ diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index a4871bc3bebd2..85461eaa15693 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -604,7 +604,7 @@ static zend_never_inline ZEND_COLD zval *zend_wrong_assign_to_variable_reference return zend_assign_to_variable_ex(variable_ptr, value_ptr, IS_TMP_VAR, EX_USES_STRICT_TYPES(), garbage_ptr); } -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_cannot_pass_by_reference(uint32_t arg_num) +ZEND_API zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_cannot_pass_by_reference(uint32_t arg_num) { const zend_execute_data *execute_data = EG(current_execute_data); zend_string *func_name = get_function_or_method_name(EX(call)->func); @@ -646,7 +646,7 @@ static zend_never_inline ZEND_COLD void zend_throw_access_uninit_prop_by_ref_err } /* this should modify object only if it's empty */ -static zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_throw_non_object_error(const zval *object, zval *property OPLINE_DC EXECUTE_DATA_DC) +static zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_throw_non_object_error(const zval *object, const zval *property OPLINE_DC EXECUTE_DATA_DC) { zend_string *tmp_property_name; zend_string *property_name = zval_get_tmp_string(property, &tmp_property_name); @@ -680,7 +680,7 @@ static zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_throw_non_object_erro } } -static ZEND_COLD void zend_verify_type_error_common( +static zend_never_inline ZEND_COLD void zend_verify_type_error_common( const zend_function *zf, const zend_arg_info *arg_info, const zval *value, const char **fname, const char **fsep, const char **fclass, zend_string **need_msg, const char **given_kind) @@ -703,7 +703,7 @@ static ZEND_COLD void zend_verify_type_error_common( } } -ZEND_API ZEND_COLD void zend_verify_arg_error( +ZEND_API zend_never_inline ZEND_COLD void zend_verify_arg_error( const zend_function *zf, const zend_arg_info *arg_info, uint32_t arg_num, const zval *value) { const zend_execute_data *ptr = EG(current_execute_data)->prev_execute_data; @@ -835,7 +835,7 @@ ZEND_API bool zend_verify_scalar_type_hint(uint32_t type_mask, zval *arg, bool s return zend_verify_weak_scalar_type_hint(type_mask, arg); } -ZEND_COLD zend_never_inline void zend_verify_class_constant_type_error(const zend_class_constant *c, const zend_string *name, const zval *constant) +static zend_never_inline ZEND_COLD void zend_verify_class_constant_type_error(const zend_class_constant *c, const zend_string *name, const zval *constant) { zend_string *type_str = zend_type_to_string(c->type); @@ -845,7 +845,7 @@ ZEND_COLD zend_never_inline void zend_verify_class_constant_type_error(const zen zend_string_release(type_str); } -ZEND_COLD zend_never_inline void zend_verify_property_type_error(const zend_property_info *info, const zval *property) +static zend_never_inline ZEND_COLD void zend_verify_property_type_error(const zend_property_info *info, const zval *property) { zend_string *type_str; @@ -863,7 +863,7 @@ ZEND_COLD zend_never_inline void zend_verify_property_type_error(const zend_prop zend_string_release(type_str); } -ZEND_COLD zend_never_inline void zend_magic_get_property_type_inconsistency_error(const zend_property_info *info, const zval *property) +static zend_never_inline ZEND_COLD void zend_magic_get_property_type_inconsistency_error(const zend_property_info *info, const zval *property) { /* we _may_ land here in case reading already errored and runtime cache thus has not been updated (i.e. it contains a valid but unrelated info) */ if (EG(exception)) { @@ -880,7 +880,7 @@ ZEND_COLD zend_never_inline void zend_magic_get_property_type_inconsistency_erro zend_string_release(type_str); } -ZEND_COLD void zend_match_unhandled_error(const zval *value) +zend_never_inline ZEND_COLD void zend_match_unhandled_error(const zval *value) { zend_long max_len = EG(exception_string_param_max_len); smart_str msg = {0}; @@ -900,35 +900,35 @@ ZEND_COLD void zend_match_unhandled_error(const zval *value) smart_str_free(&msg); } -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_readonly_property_modification_error( +ZEND_API zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_readonly_property_modification_error( const zend_property_info *info) { zend_readonly_property_modification_error_ex( ZSTR_VAL(info->ce->name), zend_get_unmangled_property_name(info->name)); } -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_readonly_property_modification_error_ex( +ZEND_API zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_readonly_property_modification_error_ex( const char *class_name, const char *prop_name) { zend_throw_error(NULL, "Cannot modify readonly property %s::$%s", class_name, prop_name); } -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_readonly_property_indirect_modification_error(const zend_property_info *info) +ZEND_API zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_readonly_property_indirect_modification_error(const zend_property_info *info) { zend_throw_error(NULL, "Cannot indirectly modify readonly property %s::$%s", ZSTR_VAL(info->ce->name), zend_get_unmangled_property_name(info->name)); } -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_invalid_class_constant_type_error(const uint8_t type) +ZEND_API zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_invalid_class_constant_type_error(const uint8_t type) { zend_type_error("Cannot use value of type %s as class constant name", zend_get_type_by_const(type)); } -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_object_released_while_assigning_to_property_error(const zend_property_info *info) +ZEND_API zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_object_released_while_assigning_to_property_error(const zend_property_info *info) { zend_throw_error(NULL, "Object was released while assigning to property %s::$%s", ZSTR_VAL(info->ce->name), zend_get_unmangled_property_name(info->name)); } -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_asymmetric_visibility_property_modification_error( +ZEND_API zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_asymmetric_visibility_property_modification_error( const zend_property_info *prop_info, const char *operation ) { const zend_class_entry *scope; @@ -1321,7 +1321,7 @@ ZEND_API bool zend_internal_call_should_throw(const zend_function *fbc, zend_exe return 0; } -ZEND_API ZEND_COLD void zend_internal_call_arginfo_violation(const zend_function *fbc) +ZEND_API zend_never_inline ZEND_COLD void zend_internal_call_arginfo_violation(const zend_function *fbc) { zend_error_noreturn(E_ERROR, "Arginfo / zpp mismatch during call of %s%s%s()", fbc->common.scope ? ZSTR_VAL(fbc->common.scope->name) : "", @@ -1392,7 +1392,7 @@ static void zend_verify_internal_func_info(const zend_function *fn, const zval * } #endif -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_missing_arg_error(const zend_execute_data *execute_data) +ZEND_API zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_missing_arg_error(const zend_execute_data *execute_data) { const zend_execute_data *ptr = EX(prev_execute_data); @@ -1417,7 +1417,7 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_missing_arg_error(const zend_execute_ } } -ZEND_API ZEND_COLD void zend_verify_return_error(const zend_function *zf, const zval *value) +ZEND_API zend_never_inline ZEND_COLD void zend_verify_return_error(const zend_function *zf, const zval *value) { const zend_arg_info *arg_info = &zf->common.arg_info[-1]; const char *fname, *fsep, *fclass; @@ -1433,7 +1433,7 @@ ZEND_API ZEND_COLD void zend_verify_return_error(const zend_function *zf, const zend_string_release(need_msg); } -ZEND_API ZEND_COLD void zend_verify_never_error(const zend_function *zf) +ZEND_API zend_never_inline ZEND_COLD void zend_verify_never_error(const zend_function *zf) { zend_string *func_name = get_function_or_method_name(zf); @@ -1444,7 +1444,7 @@ ZEND_API ZEND_COLD void zend_verify_never_error(const zend_function *zf) } #if ZEND_DEBUG -static ZEND_COLD void zend_verify_internal_return_error(const zend_function *zf, const zval *value) +static zend_never_inline ZEND_COLD void zend_verify_internal_return_error(const zend_function *zf, const zval *value) { const zend_arg_info *arg_info = &zf->common.arg_info[-1]; const char *fname, *fsep, *fclass; @@ -1458,7 +1458,7 @@ static ZEND_COLD void zend_verify_internal_return_error(const zend_function *zf, fclass, fsep, fname, ZSTR_VAL(need_msg), given_msg); } -static ZEND_COLD void zend_verify_void_return_error(const zend_function *zf, const char *returned_msg, const char *returned_kind) +static zend_never_inline ZEND_COLD void zend_verify_void_return_error(const zend_function *zf, const char *returned_msg, const char *returned_kind) { const char *fname = ZSTR_VAL(zf->common.function_name); const char *fsep; @@ -1497,7 +1497,7 @@ ZEND_API bool zend_verify_internal_return_type(const zend_function *zf, zval *re } #endif -static ZEND_COLD void zend_verify_missing_return_type(const zend_function *zf) +static zend_never_inline ZEND_COLD void zend_verify_missing_return_type(const zend_function *zf) { /* VERIFY_RETURN_TYPE is not emitted for "void" functions, so this is always an error. */ zend_verify_return_error(zf, NULL); @@ -1709,7 +1709,7 @@ static zend_never_inline void zend_binary_assign_op_typed_prop(const zend_proper } } -static zend_never_inline zend_long zend_check_string_offset(zval *dim, int type EXECUTE_DATA_DC) +static zend_never_inline zend_long zend_check_string_offset(const zval *dim, int type EXECUTE_DATA_DC) { zend_long offset; @@ -1754,7 +1754,7 @@ static zend_never_inline zend_long zend_check_string_offset(zval *dim, int type return zval_get_long_func(dim, /* is_strict */ false); } -ZEND_API ZEND_COLD void zend_wrong_string_offset_error(void) +ZEND_API zend_never_inline ZEND_COLD void zend_wrong_string_offset_error(void) { const char *msg = NULL; const zend_execute_data *execute_data = EG(current_execute_data); @@ -2184,7 +2184,7 @@ static zend_property_info *zend_get_prop_not_accepting_double(zend_reference *re return NULL; } -static ZEND_COLD zend_long zend_throw_incdec_ref_error(zend_property_info *error_prop OPLINE_DC) +static zend_never_inline ZEND_COLD zend_long zend_throw_incdec_ref_error(const zend_property_info *error_prop OPLINE_DC) { zend_string *type_str = zend_type_to_string(error_prop->type); if (ZEND_IS_INCREMENT(opline->opcode)) { @@ -2206,7 +2206,7 @@ static ZEND_COLD zend_long zend_throw_incdec_ref_error(zend_property_info *error } } -static ZEND_COLD zend_long zend_throw_incdec_prop_error(zend_property_info *prop OPLINE_DC) { +static zend_never_inline ZEND_COLD zend_long zend_throw_incdec_prop_error(const zend_property_info *prop OPLINE_DC) { zend_string *type_str = zend_type_to_string(prop->type); if (ZEND_IS_INCREMENT(opline->opcode)) { zend_type_error("Cannot increment property %s::$%s of type %s past its maximal value", @@ -2257,7 +2257,7 @@ static void zend_incdec_typed_ref(zend_reference *ref, zval *copy OPLINE_DC EXEC } } -static void zend_incdec_typed_prop(zend_property_info *prop_info, zval *var_ptr, zval *copy OPLINE_DC EXECUTE_DATA_DC) +static void zend_incdec_typed_prop(const zend_property_info *prop_info, zval *var_ptr, zval *copy OPLINE_DC EXECUTE_DATA_DC) { zval tmp; @@ -2287,7 +2287,7 @@ static void zend_incdec_typed_prop(zend_property_info *prop_info, zval *var_ptr, } } -static void zend_pre_incdec_property_zval(zval *prop, zend_property_info *prop_info OPLINE_DC EXECUTE_DATA_DC) +static void zend_pre_incdec_property_zval(zval *prop, const zend_property_info *prop_info OPLINE_DC EXECUTE_DATA_DC) { if (EXPECTED(Z_TYPE_P(prop) == IS_LONG)) { if (ZEND_IS_INCREMENT(opline->opcode)) { @@ -2325,7 +2325,7 @@ static void zend_pre_incdec_property_zval(zval *prop, zend_property_info *prop_i } } -static void zend_post_incdec_property_zval(zval *prop, zend_property_info *prop_info OPLINE_DC EXECUTE_DATA_DC) +static void zend_post_incdec_property_zval(zval *prop, const zend_property_info *prop_info OPLINE_DC EXECUTE_DATA_DC) { if (EXPECTED(Z_TYPE_P(prop) == IS_LONG)) { ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(prop)); @@ -2553,13 +2553,13 @@ ZEND_API zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_undefined_method(co zend_throw_error(NULL, "Call to undefined method %s::%s()", ZSTR_VAL(ce->name), ZSTR_VAL(method)); } -static zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_invalid_method_call(zval *object, zval *function_name) +static zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_invalid_method_call(const zval *object, const zval *function_name) { zend_throw_error(NULL, "Call to a member function %s() on %s", Z_STRVAL_P(function_name), zend_zval_value_name(object)); } -ZEND_API void ZEND_FASTCALL zend_non_static_method_call(const zend_function *fbc) +ZEND_API zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_non_static_method_call(const zend_function *fbc) { zend_throw_error( zend_ce_error, @@ -2617,7 +2617,7 @@ ZEND_API zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_call_stack_size_err } #endif /* ZEND_CHECK_STACK_LIMIT */ -static ZEND_COLD void zend_binary_assign_op_dim_slow(zval *container, zval *dim OPLINE_DC EXECUTE_DATA_DC) +static ZEND_COLD void zend_binary_assign_op_dim_slow(const zval *container, const zval *dim OPLINE_DC EXECUTE_DATA_DC) { if (UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) { if (opline->op2_type == IS_UNUSED) { @@ -3051,7 +3051,7 @@ static zend_never_inline void ZEND_FASTCALL zend_fetch_dimension_address_UNSET(z zend_fetch_dimension_address(result, container_ptr, dim, dim_type, BP_VAR_UNSET EXECUTE_DATA_CC); } -static zend_always_inline void zend_fetch_dimension_address_read(zval *result, zval *container, zval *dim, int dim_type, int type, bool is_list, bool slow EXECUTE_DATA_DC) +static zend_always_inline void zend_fetch_dimension_address_read(zval *result, const zval *container, zval *dim, int dim_type, int type, bool is_list, bool slow EXECUTE_DATA_DC) { zval *retval; @@ -3205,36 +3205,36 @@ static zend_always_inline void zend_fetch_dimension_address_read(zval *result, z } } -static zend_never_inline void ZEND_FASTCALL zend_fetch_dimension_address_read_R(zval *container, zval *dim, int dim_type OPLINE_DC EXECUTE_DATA_DC) +static zend_never_inline void ZEND_FASTCALL zend_fetch_dimension_address_read_R(const zval *container, zval *dim, int dim_type OPLINE_DC EXECUTE_DATA_DC) { zval *result = EX_VAR(opline->result.var); zend_fetch_dimension_address_read(result, container, dim, dim_type, BP_VAR_R, 0, 0 EXECUTE_DATA_CC); } -static zend_never_inline void zend_fetch_dimension_address_read_R_slow(zval *container, zval *dim OPLINE_DC EXECUTE_DATA_DC) +static zend_never_inline void zend_fetch_dimension_address_read_R_slow(const zval *container, zval *dim OPLINE_DC EXECUTE_DATA_DC) { zval *result = EX_VAR(opline->result.var); zend_fetch_dimension_address_read(result, container, dim, IS_CV, BP_VAR_R, 0, 1 EXECUTE_DATA_CC); } -static zend_never_inline void ZEND_FASTCALL zend_fetch_dimension_address_read_IS(zval *container, zval *dim, int dim_type OPLINE_DC EXECUTE_DATA_DC) +static zend_never_inline void ZEND_FASTCALL zend_fetch_dimension_address_read_IS(const zval *container, zval *dim, int dim_type OPLINE_DC EXECUTE_DATA_DC) { zval *result = EX_VAR(opline->result.var); zend_fetch_dimension_address_read(result, container, dim, dim_type, BP_VAR_IS, 0, 0 EXECUTE_DATA_CC); } -static zend_never_inline void ZEND_FASTCALL zend_fetch_dimension_address_LIST_r(zval *container, zval *dim, int dim_type OPLINE_DC EXECUTE_DATA_DC) +static zend_never_inline void ZEND_FASTCALL zend_fetch_dimension_address_LIST_r(const zval *container, zval *dim, int dim_type OPLINE_DC EXECUTE_DATA_DC) { zval *result = EX_VAR(opline->result.var); zend_fetch_dimension_address_read(result, container, dim, dim_type, BP_VAR_R, 1, 0 EXECUTE_DATA_CC); } -ZEND_API void zend_fetch_dimension_const(zval *result, zval *container, zval *dim, int type) +ZEND_API void zend_fetch_dimension_const(zval *result, const zval *container, zval *dim, int type) { zend_fetch_dimension_address_read(result, container, dim, IS_TMP_VAR, type, 0, 0 NO_EXECUTE_DATA_CC); } -static zend_never_inline zval* ZEND_FASTCALL zend_find_array_dim_slow(HashTable *ht, zval *offset EXECUTE_DATA_DC) +static zend_never_inline zval* ZEND_FASTCALL zend_find_array_dim_slow(HashTable *ht, const zval *offset EXECUTE_DATA_DC) { zend_ulong hval; @@ -3289,7 +3289,7 @@ static zend_never_inline zval* ZEND_FASTCALL zend_find_array_dim_slow(HashTable } } -static zend_never_inline bool ZEND_FASTCALL zend_isset_dim_slow(zval *container, zval *offset EXECUTE_DATA_DC) +static zend_never_inline bool ZEND_FASTCALL zend_isset_dim_slow(const zval *container, zval *offset EXECUTE_DATA_DC) { if (/*OP2_TYPE == IS_CV &&*/ UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) { offset = ZVAL_UNDEFINED_OP2(); @@ -3328,7 +3328,7 @@ static zend_never_inline bool ZEND_FASTCALL zend_isset_dim_slow(zval *container, } } -static zend_never_inline bool ZEND_FASTCALL zend_isempty_dim_slow(zval *container, zval *offset EXECUTE_DATA_DC) +static zend_never_inline bool ZEND_FASTCALL zend_isempty_dim_slow(const zval *container, zval *offset EXECUTE_DATA_DC) { if (/*OP2_TYPE == IS_CV &&*/ UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) { offset = ZVAL_UNDEFINED_OP2(); @@ -3367,7 +3367,7 @@ static zend_never_inline bool ZEND_FASTCALL zend_isempty_dim_slow(zval *containe } } -static zend_never_inline bool ZEND_FASTCALL zend_array_key_exists_fast(HashTable *ht, zval *key OPLINE_DC EXECUTE_DATA_DC) +static zend_never_inline bool ZEND_FASTCALL zend_array_key_exists_fast(HashTable *ht, const zval *key OPLINE_DC EXECUTE_DATA_DC) { zend_string *str; zend_ulong hval; @@ -3425,8 +3425,8 @@ static zend_never_inline bool ZEND_FASTCALL zend_array_key_exists_fast(HashTable } } -static ZEND_COLD void ZEND_FASTCALL zend_array_key_exists_error( - zval *subject, zval *key OPLINE_DC EXECUTE_DATA_DC) +static zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_array_key_exists_error( + const zval *subject, const zval *key OPLINE_DC EXECUTE_DATA_DC) { if (Z_TYPE_P(key) == IS_UNDEF) { ZVAL_UNDEFINED_OP1(); @@ -3440,7 +3440,7 @@ static ZEND_COLD void ZEND_FASTCALL zend_array_key_exists_error( } } -static zend_always_inline bool promotes_to_array(zval *val) { +static zend_always_inline bool promotes_to_array(const zval *val) { return Z_TYPE_P(val) <= IS_FALSE || (Z_ISREF_P(val) && Z_TYPE_P(Z_REFVAL_P(val)) <= IS_FALSE); } @@ -3504,8 +3504,18 @@ static zend_never_inline bool zend_handle_fetch_obj_flags( return 1; } -static zend_always_inline void zend_fetch_property_address(zval *result, zval *container, uint32_t container_op_type, zval *prop_ptr, uint32_t prop_op_type, void **cache_slot, int type, uint32_t flags, zend_property_info **prop_info_p OPLINE_DC EXECUTE_DATA_DC) -{ +static zend_always_inline void zend_fetch_property_address( + zval *result, + const zval *container, + uint32_t container_op_type, + const zval *prop_ptr, + uint32_t prop_op_type, + void **cache_slot, + int type, + uint32_t flags, + zend_property_info **prop_info_p + OPLINE_DC EXECUTE_DATA_DC +) { zval *ptr; zend_object *zobj; zend_string *name, *tmp_name; @@ -3650,8 +3660,14 @@ static zend_always_inline void zend_fetch_property_address(zval *result, zval *c } } -static zend_always_inline void zend_assign_to_property_reference(zval *container, uint32_t container_op_type, zval *prop_ptr, uint32_t prop_op_type, zval *value_ptr OPLINE_DC EXECUTE_DATA_DC) -{ +static zend_always_inline void zend_assign_to_property_reference( + const zval *container, + uint32_t container_op_type, + const zval *prop_ptr, + uint32_t prop_op_type, + zval *value_ptr + OPLINE_DC EXECUTE_DATA_DC +) { zval variable, *variable_ptr = &variable; void **cache_addr = (prop_op_type == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_RETURNS_FUNCTION) : NULL; zend_refcounted *garbage = NULL; @@ -3689,25 +3705,25 @@ static zend_always_inline void zend_assign_to_property_reference(zval *container } } -static zend_never_inline void zend_assign_to_property_reference_this_const(zval *container, zval *prop_ptr, zval *value_ptr OPLINE_DC EXECUTE_DATA_DC) +static zend_never_inline void zend_assign_to_property_reference_this_const(const zval *container, const zval *prop_ptr, zval *value_ptr OPLINE_DC EXECUTE_DATA_DC) { zend_assign_to_property_reference(container, IS_UNUSED, prop_ptr, IS_CONST, value_ptr OPLINE_CC EXECUTE_DATA_CC); } -static zend_never_inline void zend_assign_to_property_reference_var_const(zval *container, zval *prop_ptr, zval *value_ptr OPLINE_DC EXECUTE_DATA_DC) +static zend_never_inline void zend_assign_to_property_reference_var_const(const zval *container, const zval *prop_ptr, zval *value_ptr OPLINE_DC EXECUTE_DATA_DC) { zend_assign_to_property_reference(container, IS_VAR, prop_ptr, IS_CONST, value_ptr OPLINE_CC EXECUTE_DATA_CC); } -static zend_never_inline void zend_assign_to_property_reference_this_var(zval *container, zval *prop_ptr, zval *value_ptr OPLINE_DC EXECUTE_DATA_DC) +static zend_never_inline void zend_assign_to_property_reference_this_var(const zval *container, const zval *prop_ptr, zval *value_ptr OPLINE_DC EXECUTE_DATA_DC) { zend_assign_to_property_reference(container, IS_UNUSED, prop_ptr, IS_VAR, value_ptr OPLINE_CC EXECUTE_DATA_CC); } -static zend_never_inline void zend_assign_to_property_reference_var_var(zval *container, zval *prop_ptr, zval *value_ptr OPLINE_DC EXECUTE_DATA_DC) +static zend_never_inline void zend_assign_to_property_reference_var_var(const zval *container, const zval *prop_ptr, zval *value_ptr OPLINE_DC EXECUTE_DATA_DC) { zend_assign_to_property_reference(container, IS_VAR, prop_ptr, IS_VAR, value_ptr OPLINE_CC EXECUTE_DATA_CC); @@ -3878,7 +3894,7 @@ ZEND_API zval* ZEND_FASTCALL zend_fetch_static_property(zend_execute_data *ex, i return result; } -ZEND_API ZEND_COLD void zend_throw_ref_type_error_type(const zend_property_info *prop1, const zend_property_info *prop2, const zval *zv) { +ZEND_API zend_never_inline ZEND_COLD void zend_throw_ref_type_error_type(const zend_property_info *prop1, const zend_property_info *prop2, const zval *zv) { zend_string *type1_str = zend_type_to_string(prop1->type); zend_string *type2_str = zend_type_to_string(prop2->type); zend_type_error("Reference with value of type %s held by property %s::$%s of type %s is not compatible with property %s::$%s of type %s", @@ -3894,7 +3910,7 @@ ZEND_API ZEND_COLD void zend_throw_ref_type_error_type(const zend_property_info zend_string_release(type2_str); } -ZEND_API ZEND_COLD void zend_throw_ref_type_error_zval(const zend_property_info *prop, const zval *zv) { +ZEND_API zend_never_inline ZEND_COLD void zend_throw_ref_type_error_zval(const zend_property_info *prop, const zval *zv) { zend_string *type_str = zend_type_to_string(prop->type); zend_type_error("Cannot assign %s to reference held by property %s::$%s of type %s", zend_zval_value_name(zv), @@ -3905,7 +3921,7 @@ ZEND_API ZEND_COLD void zend_throw_ref_type_error_zval(const zend_property_info zend_string_release(type_str); } -ZEND_API ZEND_COLD void zend_throw_conflicting_coercion_error(const zend_property_info *prop1, const zend_property_info *prop2, const zval *zv) { +static zend_never_inline ZEND_COLD void zend_throw_conflicting_coercion_error(const zend_property_info *prop1, const zend_property_info *prop2, const zval *zv) { zend_string *type1_str = zend_type_to_string(prop1->type); zend_string *type2_str = zend_type_to_string(prop2->type); zend_type_error("Cannot assign %s to reference held by property %s::$%s of type %s and property %s::$%s of type %s, as this would result in an inconsistent type conversion", @@ -4480,7 +4496,7 @@ ZEND_API zend_function * ZEND_FASTCALL zend_fetch_function(zend_string *name) /* ZEND_API zend_function * ZEND_FASTCALL zend_fetch_function_str(const char *name, size_t len) /* {{{ */ { - zval *zv = zend_hash_str_find(EG(function_table), name, len); + const zval *zv = zend_hash_str_find(EG(function_table), name, len); if (EXPECTED(zv != NULL)) { zend_function *fbc = Z_FUNC_P(zv); @@ -4889,9 +4905,7 @@ static void cleanup_unfinished_calls(zend_execute_data *execute_data, uint32_t o static void cleanup_live_vars(zend_execute_data *execute_data, uint32_t op_num, uint32_t catch_op_num) /* {{{ */ { - int i; - - for (i = 0; i < EX(func)->op_array.last_live_range; i++) { + for (uint32_t i = 0; i < EX(func)->op_array.last_live_range; i++) { const zend_live_range *range = &EX(func)->op_array.live_range[i]; if (range->start > op_num) { /* further blocks will not be relevant... */ @@ -4904,7 +4918,7 @@ static void cleanup_live_vars(zend_execute_data *execute_data, uint32_t op_num, /* Handle the split range for loop vars */ if (catch_op_num) { - zend_op *final_op = EX(func)->op_array.opcodes + range->end; + const zend_op *final_op = EX(func)->op_array.opcodes + range->end; if (final_op->extended_value & ZEND_FREE_ON_RETURN && (final_op->opcode == ZEND_FE_FREE || final_op->opcode == ZEND_FREE)) { if (catch_op_num < range->end + final_op->op2.num) { continue; @@ -5192,7 +5206,7 @@ static zend_never_inline zend_execute_data *zend_init_dynamic_call_object(zend_o } /* }}} */ -static zend_never_inline zend_execute_data *zend_init_dynamic_call_array(zend_array *function, uint32_t num_args) /* {{{ */ +static zend_never_inline zend_execute_data *zend_init_dynamic_call_array(const zend_array *function, uint32_t num_args) /* {{{ */ { zend_function *fbc; void *object_or_called_scope; @@ -5283,7 +5297,7 @@ static zend_never_inline zend_execute_data *zend_init_dynamic_call_array(zend_ar #define ZEND_FAKE_OP_ARRAY ((zend_op_array*)(intptr_t)-1) -static zend_never_inline zend_op_array* ZEND_FASTCALL zend_include_or_eval(zval *inc_filename_zv, int type) /* {{{ */ +static zend_never_inline zend_op_array* ZEND_FASTCALL zend_include_or_eval(const zval *inc_filename_zv, int type) /* {{{ */ { zend_op_array *new_op_array = NULL; zend_string *tmp_inc_filename; diff --git a/Zend/zend_execute.h b/Zend/zend_execute.h index cb2c9e1448017..ba48b19bcfe1b 100644 --- a/Zend/zend_execute.h +++ b/Zend/zend_execute.h @@ -60,7 +60,7 @@ ZEND_API zend_result zend_eval_stringl_ex(const char *str, size_t str_len, zval /* export zend_pass_function to allow comparisons against it */ extern ZEND_API const zend_internal_function zend_pass_function; -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_missing_arg_error(const zend_execute_data *execute_data); +ZEND_API zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_missing_arg_error(const zend_execute_data *execute_data); ZEND_API ZEND_COLD void ZEND_FASTCALL zend_deprecated_function(const zend_function *fbc); ZEND_API ZEND_COLD void ZEND_FASTCALL zend_nodiscard_function(const zend_function *fbc); ZEND_API ZEND_COLD void ZEND_FASTCALL zend_deprecated_class_constant(const zend_class_constant *c, const zend_string *constant_name); @@ -80,31 +80,31 @@ typedef enum { ZEND_API bool ZEND_FASTCALL zend_verify_prop_assignable_by_ref_ex(const zend_property_info *prop_info, zval *orig_val, bool strict, zend_verify_prop_assignable_by_ref_context context); ZEND_API bool ZEND_FASTCALL zend_verify_prop_assignable_by_ref(const zend_property_info *prop_info, zval *orig_val, bool strict); -ZEND_API ZEND_COLD void zend_throw_ref_type_error_zval(const zend_property_info *prop, const zval *zv); -ZEND_API ZEND_COLD void zend_throw_ref_type_error_type(const zend_property_info *prop1, const zend_property_info *prop2, const zval *zv); +ZEND_API zend_never_inline ZEND_COLD void zend_throw_ref_type_error_zval(const zend_property_info *prop, const zval *zv); +ZEND_API zend_never_inline ZEND_COLD void zend_throw_ref_type_error_type(const zend_property_info *prop1, const zend_property_info *prop2, const zval *zv); ZEND_API ZEND_COLD zval* ZEND_FASTCALL zend_undefined_offset_write(HashTable *ht, zend_long lval); ZEND_API ZEND_COLD zval* ZEND_FASTCALL zend_undefined_index_write(HashTable *ht, zend_string *offset); -ZEND_API ZEND_COLD void zend_wrong_string_offset_error(void); +ZEND_API zend_never_inline ZEND_COLD void zend_wrong_string_offset_error(void); -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_readonly_property_modification_error(const zend_property_info *info); -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_readonly_property_modification_error_ex(const char *class_name, const char *prop_name); -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_readonly_property_indirect_modification_error(const zend_property_info *info); +ZEND_API zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_readonly_property_modification_error(const zend_property_info *info); +ZEND_API zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_readonly_property_modification_error_ex(const char *class_name, const char *prop_name); +ZEND_API zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_readonly_property_indirect_modification_error(const zend_property_info *info); -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_invalid_class_constant_type_error(uint8_t type); +ZEND_API zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_invalid_class_constant_type_error(uint8_t type); -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_object_released_while_assigning_to_property_error(const zend_property_info *info); +ZEND_API zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_object_released_while_assigning_to_property_error(const zend_property_info *info); -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_cannot_add_element(void); +ZEND_API zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_cannot_add_element(void); ZEND_API bool ZEND_FASTCALL zend_asymmetric_property_has_set_access(const zend_property_info *prop_info); -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_asymmetric_visibility_property_modification_error(const zend_property_info *prop_info, const char *operation); +ZEND_API zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_asymmetric_visibility_property_modification_error(const zend_property_info *prop_info, const char *operation); ZEND_API bool zend_verify_scalar_type_hint(uint32_t type_mask, zval *arg, bool strict, bool is_internal_arg); -ZEND_API ZEND_COLD void zend_verify_arg_error( +ZEND_API zend_never_inline ZEND_COLD void zend_verify_arg_error( const zend_function *zf, const zend_arg_info *arg_info, uint32_t arg_num, const zval *value); -ZEND_API ZEND_COLD void zend_verify_return_error( +ZEND_API zend_never_inline ZEND_COLD void zend_verify_return_error( const zend_function *zf, const zval *value); -ZEND_API ZEND_COLD void zend_verify_never_error( +ZEND_API zend_never_inline ZEND_COLD void zend_verify_never_error( const zend_function *zf); ZEND_API bool zend_verify_ref_array_assignable(zend_reference *ref); ZEND_API bool zend_check_user_type_slow( @@ -112,7 +112,7 @@ ZEND_API bool zend_check_user_type_slow( #if ZEND_DEBUG ZEND_API bool zend_internal_call_should_throw(const zend_function *fbc, zend_execute_data *call); -ZEND_API ZEND_COLD void zend_internal_call_arginfo_violation(const zend_function *fbc); +ZEND_API zend_never_inline ZEND_COLD void zend_internal_call_arginfo_violation(const zend_function *fbc); ZEND_API bool zend_verify_internal_return_type(const zend_function *zf, zval *ret); #endif @@ -134,7 +134,7 @@ ZEND_API void ZEND_FASTCALL zend_ref_del_type_source(zend_property_info_source_l ZEND_API zval* zend_assign_to_typed_ref(zval *variable_ptr, zval *value, uint8_t value_type, bool strict); ZEND_API zval* zend_assign_to_typed_ref_ex(zval *variable_ptr, zval *value, uint8_t value_type, bool strict, zend_refcounted **garbage_ptr); -static zend_always_inline void zend_copy_to_variable(zval *variable_ptr, zval *value, uint8_t value_type) +static zend_always_inline void zend_copy_to_variable(zval *variable_ptr, const zval *value, uint8_t value_type) { zend_refcounted *ref = NULL; @@ -210,7 +210,7 @@ static zend_always_inline zval* zend_assign_to_variable_ex(zval *variable_ptr, z return variable_ptr; } -static zend_always_inline void zend_safe_assign_to_variable_noref(zval *variable_ptr, zval *value) { +static zend_always_inline void zend_safe_assign_to_variable_noref(zval *variable_ptr, const zval *value) { if (Z_REFCOUNTED_P(variable_ptr)) { ZEND_ASSERT(Z_TYPE_P(variable_ptr) != IS_REFERENCE); zend_refcounted *ref = Z_COUNTED_P(variable_ptr); @@ -471,7 +471,7 @@ ZEND_API zend_string *zend_get_executed_filename_ex(void); ZEND_API uint32_t zend_get_executed_lineno(void); ZEND_API zend_class_entry *zend_get_executed_scope(void); ZEND_API bool zend_is_executing(void); -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_cannot_pass_by_reference(uint32_t arg_num); +ZEND_API zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_cannot_pass_by_reference(uint32_t arg_num); ZEND_API void zend_set_timeout(zend_long seconds, bool reset_signals); ZEND_API void zend_unset_timeout(void); @@ -484,7 +484,7 @@ ZEND_API zend_function * ZEND_FASTCALL zend_fetch_function(zend_string *name); ZEND_API zend_function * ZEND_FASTCALL zend_fetch_function_str(const char *name, size_t len); ZEND_API void ZEND_FASTCALL zend_init_func_run_time_cache(zend_op_array *op_array); -ZEND_API void zend_fetch_dimension_const(zval *result, zval *container, zval *dim, int type); +ZEND_API void zend_fetch_dimension_const(zval *result, const zval *container, zval *dim, int type); ZEND_API zval* zend_get_compiled_variable_value(const zend_execute_data *execute_data_ptr, uint32_t var); @@ -511,7 +511,7 @@ ZEND_API ZEND_ATTRIBUTE_DEPRECATED HashTable *zend_unfinished_execution_gc(zend_ ZEND_API HashTable *zend_unfinished_execution_gc_ex(zend_execute_data *execute_data, zend_execute_data *call, zend_get_gc_buffer *gc_buffer, bool suspended_by_yield); ZEND_API zval* ZEND_FASTCALL zend_fetch_static_property(zend_execute_data *ex, int fetch_type); ZEND_API zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_undefined_method(const zend_class_entry *ce, const zend_string *method); -ZEND_API void ZEND_FASTCALL zend_non_static_method_call(const zend_function *fbc); +ZEND_API zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_non_static_method_call(const zend_function *fbc); ZEND_API void zend_frameless_observed_call(zend_execute_data *execute_data); @@ -585,11 +585,8 @@ ZEND_API zend_result ZEND_FASTCALL zend_handle_undef_args(zend_execute_data *cal ZEND_API bool zend_verify_class_constant_type(const zend_class_constant *c, const zend_string *name, zval *constant); -ZEND_COLD void zend_verify_class_constant_type_error(const zend_class_constant *c, const zend_string *name, const zval *constant); ZEND_API bool zend_verify_property_type(const zend_property_info *info, zval *property, bool strict); -ZEND_COLD void zend_verify_property_type_error(const zend_property_info *info, const zval *property); -ZEND_COLD void zend_magic_get_property_type_inconsistency_error(const zend_property_info *info, const zval *property); #define ZEND_REF_ADD_TYPE_SOURCE(ref, source) \ zend_ref_add_type_source(&ZEND_REF_TYPE_SOURCES(ref), source) @@ -618,7 +615,7 @@ ZEND_COLD void zend_magic_get_property_type_inconsistency_error(const zend_prope } \ } while (0) -ZEND_COLD void zend_match_unhandled_error(const zval *value); +zend_never_inline ZEND_COLD void zend_match_unhandled_error(const zval *value); /* Call this to handle the timeout or the interrupt function. It will set * EG(vm_interrupt) to false. diff --git a/ext/mysqlnd/mysqlnd_charset.c b/ext/mysqlnd/mysqlnd_charset.c index b9ba0577c84a8..eacf74240fd18 100644 --- a/ext/mysqlnd/mysqlnd_charset.c +++ b/ext/mysqlnd/mysqlnd_charset.c @@ -967,40 +967,6 @@ PHPAPI zend_ulong mysqlnd_cset_escape_slashes(const MYSQLND_CHARSET * const cset /* }}} */ -static struct st_mysqlnd_plugin_charsets mysqlnd_plugin_charsets_plugin = -{ - { - MYSQLND_PLUGIN_API_VERSION, - "charsets", - MYSQLND_VERSION_ID, - PHP_MYSQLND_VERSION, - "Modified BSD License (BSD-3-Clause)", - "Andrey Hristov , Ulf Wendel , Georg Richter ", - { - NULL, /* no statistics , will be filled later if there are some */ - NULL, /* no statistics */ - }, - { - NULL /* plugin shutdown */ - } - }, - {/* methods */ - mysqlnd_find_charset_nr, - mysqlnd_find_charset_name, - mysqlnd_cset_escape_quotes, - mysqlnd_cset_escape_slashes - } -}; - - -/* {{{ mysqlnd_charsets_plugin_register */ -void -mysqlnd_charsets_plugin_register(void) -{ - mysqlnd_plugin_register_ex((struct st_mysqlnd_plugin_header *) &mysqlnd_plugin_charsets_plugin); -} -/* }}} */ - #if MYSQLND_CHARSETS_SANITY_CHECK void mysqlnd_charsets_sanity_check(void) { diff --git a/ext/mysqlnd/mysqlnd_charset.h b/ext/mysqlnd/mysqlnd_charset.h index 401d6d98cec8c..d5e621e38eb13 100644 --- a/ext/mysqlnd/mysqlnd_charset.h +++ b/ext/mysqlnd/mysqlnd_charset.h @@ -26,18 +26,4 @@ PHPAPI zend_ulong mysqlnd_cset_escape_quotes(const MYSQLND_CHARSET * const chars PHPAPI zend_ulong mysqlnd_cset_escape_slashes(const MYSQLND_CHARSET * const cset, char * newstr, const char * escapestr, const size_t escapestr_len); -struct st_mysqlnd_plugin_charsets -{ - const struct st_mysqlnd_plugin_header plugin_header; - struct - { - const MYSQLND_CHARSET * (*const find_charset_by_nr)(unsigned int charsetnr); - const MYSQLND_CHARSET * (*const find_charset_by_name)(const char * const name); - zend_ulong (*const escape_quotes)(const MYSQLND_CHARSET * const cset, char * newstr, const char * escapestr, const size_t escapestr_len); - zend_ulong (*const escape_slashes)(const MYSQLND_CHARSET * const cset, char * newstr, const char * escapestr, const size_t escapestr_len); - } methods; -}; - -void mysqlnd_charsets_plugin_register(void); - #endif /* MYSQLND_CHARSET_H */ diff --git a/ext/odbc/php_odbc.c b/ext/odbc/php_odbc.c index 96e1b87961409..95c872c293f17 100644 --- a/ext/odbc/php_odbc.c +++ b/ext/odbc/php_odbc.c @@ -1340,12 +1340,11 @@ static void php_odbc_fetch(INTERNAL_FUNCTION_PARAMETERS, bool return_array, php_ result = Z_ODBC_RESULT_P(pv_res); CHECK_ODBC_RESULT(result); - /* TODO deprecate $row argument values less than 1 after PHP 8.4 - * for functions other than odbc_fetch_row (see GH-13910) - */ - if (!result_type && !pv_row_is_null && pv_row < 1) { - php_error_docref(NULL, E_WARNING, "Argument #3 ($row) must be greater than or equal to 1"); - RETURN_FALSE; + if (!pv_row_is_null && pv_row < 1) { + /* row arg no differs between callers */ + zend_argument_value_error(pv_res_arr == return_value ? 2 : 3, + "must be greater than or equal to 1"); + RETURN_THROWS(); } if (result->numcols == 0) { diff --git a/ext/odbc/tests/odbc_fetch_array_001.phpt b/ext/odbc/tests/odbc_fetch_array_001.phpt index bf13ed25e4d64..e7d4ccf328b60 100644 --- a/ext/odbc/tests/odbc_fetch_array_001.phpt +++ b/ext/odbc/tests/odbc_fetch_array_001.phpt @@ -17,7 +17,7 @@ odbc_exec($conn, 'INSERT INTO fetch_array VALUES (1), (2)'); $res = odbc_exec($conn, 'SELECT * FROM fetch_array'); var_dump(odbc_fetch_array($res)); -var_dump(odbc_fetch_array($res, 0)); +var_dump(odbc_fetch_array($res, null)); var_dump(odbc_fetch_array($res, 2)); var_dump(odbc_fetch_array($res, 4)); diff --git a/ext/odbc/tests/odbc_fetch_into_001.phpt b/ext/odbc/tests/odbc_fetch_into_001.phpt index 19f7f79268c58..e420475f02ccb 100644 --- a/ext/odbc/tests/odbc_fetch_into_001.phpt +++ b/ext/odbc/tests/odbc_fetch_into_001.phpt @@ -20,7 +20,7 @@ $arr = []; var_dump(odbc_fetch_into($res, $arr)); var_dump($arr); $arr = []; -var_dump(odbc_fetch_into($res, $arr, 0)); +var_dump(odbc_fetch_into($res, $arr, null)); var_dump($arr); $arr = []; var_dump(odbc_fetch_into($res, $arr, 2)); diff --git a/ext/odbc/tests/odbc_fetch_object_001.phpt b/ext/odbc/tests/odbc_fetch_object_001.phpt index 62a8fc3b2c7e5..eb553409639f8 100644 --- a/ext/odbc/tests/odbc_fetch_object_001.phpt +++ b/ext/odbc/tests/odbc_fetch_object_001.phpt @@ -17,7 +17,7 @@ odbc_exec($conn, 'INSERT INTO fetch_object VALUES (1), (2)'); $res = odbc_exec($conn, 'SELECT * FROM fetch_object'); var_dump(odbc_fetch_object($res)); -var_dump(odbc_fetch_object($res, 0)); +var_dump(odbc_fetch_object($res, null)); var_dump(odbc_fetch_object($res, 2)); var_dump(odbc_fetch_object($res, 4)); diff --git a/ext/odbc/tests/odbc_fetch_row_001.phpt b/ext/odbc/tests/odbc_fetch_row_001.phpt index 576bb15414ceb..fbadc82725905 100644 --- a/ext/odbc/tests/odbc_fetch_row_001.phpt +++ b/ext/odbc/tests/odbc_fetch_row_001.phpt @@ -17,7 +17,11 @@ odbc_exec($conn, 'INSERT INTO fetch_row VALUES (1), (2)'); $res = odbc_exec($conn, 'SELECT * FROM fetch_row'); -var_dump(odbc_fetch_row($res, 0)); +try { + var_dump(odbc_fetch_row($res, 0)); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} var_dump(odbc_fetch_row($res, null)); var_dump(odbc_result($res, 'test')); @@ -39,9 +43,8 @@ require 'config.inc'; $conn = odbc_connect($dsn, $user, $pass); odbc_exec($conn, 'DROP TABLE fetch_row'); ?> ---EXPECTF-- -Warning: odbc_fetch_row(): Argument #3 ($row) must be greater than or equal to 1 in %s on line %d -bool(false) +--EXPECT-- +odbc_fetch_row(): Argument #2 ($row) must be greater than or equal to 1 bool(true) string(1) "1" bool(true) diff --git a/ext/pdo_odbc/odbc_stmt.c b/ext/pdo_odbc/odbc_stmt.c index a5601b04e7823..dfc42147c30f8 100644 --- a/ext/pdo_odbc/odbc_stmt.c +++ b/ext/pdo_odbc/odbc_stmt.c @@ -726,7 +726,7 @@ static int odbc_stmt_get_col(pdo_stmt_t *stmt, int colno, zval *result, enum pdo str = zend_string_realloc(str, used + to_fetch_byte, 0); memcpy(ZSTR_VAL(str) + used, buf2, to_fetch_byte); used = used + to_fetch_len; - } else if (rc==SQL_SUCCESS) { + } else if (rc == SQL_SUCCESS && C->fetched_len != 0) { str = zend_string_realloc(str, used + C->fetched_len, 0); memcpy(ZSTR_VAL(str) + used, buf2, C->fetched_len); used = used + C->fetched_len; diff --git a/ext/snmp/snmp.c b/ext/snmp/snmp.c index 9b520bce902cb..ecea48883d520 100644 --- a/ext/snmp/snmp.c +++ b/ext/snmp/snmp.c @@ -654,7 +654,7 @@ static void php_free_objid_query(struct objid_query *objid_query, HashTable* oid static bool 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, - uint32_t oid_argument_offset, uint32_t type_argument_offset, uint32_t value_argument_offset + uint32_t oid_arg_num, uint32_t type_arg_num, uint32_t value_arg_num ) { char *pptr; uint32_t idx_type = 0, idx_value = 0; @@ -681,7 +681,7 @@ static bool php_snmp_parse_oid( ZEND_ASSERT(type_str && value_str); if (ZSTR_LEN(type_str) != 1) { - zend_argument_value_error(type_argument_offset, "must be a single character"); + zend_argument_value_error(type_arg_num, "must be a single character"); efree(objid_query->vars); return false; } @@ -692,7 +692,7 @@ static bool php_snmp_parse_oid( objid_query->count++; } else if (oid_ht) { /* we got objid array */ if (zend_hash_num_elements(oid_ht) == 0) { - zend_argument_value_error(oid_argument_offset, "must not be empty when passed as an array"); + zend_argument_value_error(oid_arg_num, "must not be empty when passed as an array"); return false; } objid_query->vars = (snmpobjarg *)safe_emalloc(sizeof(snmpobjarg), zend_hash_num_elements(oid_ht), 0); @@ -737,14 +737,14 @@ static bool php_snmp_parse_oid( char ptype = *ZSTR_VAL(type); zend_string_release(type); if (len != 1) { - zend_argument_value_error(type_argument_offset, "must be a single character"); + zend_argument_value_error(type_arg_num, "must be a single character"); php_free_objid_query(objid_query, oid_ht, value_ht, st); return false; } objid_query->vars[objid_query->count].type = ptype; idx_type++; } else { - zend_argument_value_error(type_argument_offset, "must contain a type for object ID '%s'", ZSTR_VAL(tmp)); + zend_argument_value_error(type_arg_num, "must contain a type for object ID '%s'", ZSTR_VAL(tmp)); php_free_objid_query(objid_query, oid_ht, value_ht, st); return false; } @@ -779,7 +779,7 @@ static bool php_snmp_parse_oid( objid_query->vars[objid_query->count].value = ZSTR_VAL(tmp); idx_value++; } else { - zend_argument_value_error(value_argument_offset, "must contain a value for object ID '%s'", ZSTR_VAL(tmp)); + zend_argument_value_error(value_arg_num, "must contain a value for object ID '%s'", ZSTR_VAL(tmp)); php_free_objid_query(objid_query, oid_ht, value_ht, st); return false; } @@ -826,7 +826,7 @@ static bool php_snmp_parse_oid( /* {{{ snmp_session_init allocates memory for session and session->peername, caller should free it manually using snmp_session_free() and efree() */ -static bool snmp_session_init(php_snmp_session **session_p, int version, zend_string *hostname, zend_string *community, zend_long timeout, zend_long retries, int hostname_argument_offset, int timeout_argument_offset) +static bool snmp_session_init(php_snmp_session **session_p, int version, zend_string *hostname, zend_string *community, zend_long timeout, zend_long retries, uint32_t hostname_arg_num, uint32_t timeout_arg_num) { php_snmp_session *session; char *pptr, *host_ptr; @@ -841,23 +841,23 @@ static bool snmp_session_init(php_snmp_session **session_p, int version, zend_st ZEND_ASSERT(community != NULL); if (ZSTR_LEN(hostname) >= MAX_NAME_LEN) { - zend_argument_value_error(hostname_argument_offset, "length must be lower than %d", MAX_NAME_LEN); + zend_argument_value_error(hostname_arg_num, "length must be lower than %d", MAX_NAME_LEN); return false; } if (ZSTR_LEN(community) == 0) { - zend_argument_must_not_be_empty_error(hostname_argument_offset + 1); + zend_argument_must_not_be_empty_error(hostname_arg_num + 1); return false; } - if (timeout_argument_offset != -1) { + if (timeout_arg_num != 0) { if (timeout < -1 || timeout > LONG_MAX) { - zend_argument_value_error(timeout_argument_offset, "must be between -1 and %ld", LONG_MAX); + zend_argument_value_error(timeout_arg_num, "must be between -1 and %ld", LONG_MAX); return false; } if (retries < -1 || retries > INT_MAX) { - zend_argument_value_error(timeout_argument_offset + 1, "must be between -1 and %d", INT_MAX); + zend_argument_value_error(timeout_arg_num + 1, "must be between -1 and %d", INT_MAX); return false; } } @@ -888,14 +888,14 @@ static bool snmp_session_init(php_snmp_session **session_p, int version, zend_st char *pport = pptr + 2; tmp_port = atoi(pport); if (tmp_port < 0 || tmp_port > USHRT_MAX) { - zend_argument_value_error(hostname_argument_offset, "remote port must be between 0 and %u", USHRT_MAX); + zend_argument_value_error(hostname_arg_num, "remote port must be between 0 and %u", USHRT_MAX); return false; } remote_port = (unsigned short)tmp_port; } *pptr = '\0'; } else { - zend_argument_value_error(hostname_argument_offset, "has a malformed IPv6 address, closing square bracket missing"); + zend_argument_value_error(hostname_arg_num, "has a malformed IPv6 address, closing square bracket missing"); return false; } } else { /* IPv4 address */ @@ -903,7 +903,7 @@ static bool snmp_session_init(php_snmp_session **session_p, int version, zend_st char *pport = pptr + 1; tmp_port = atoi(pport); if (tmp_port < 0 || tmp_port > USHRT_MAX) { - zend_argument_value_error(hostname_argument_offset, "remote port must be between 0 and %u", USHRT_MAX); + zend_argument_value_error(hostname_arg_num, "remote port must be between 0 and %u", USHRT_MAX); return false; } remote_port = (unsigned short)tmp_port; @@ -1112,13 +1112,13 @@ static ZEND_ATTRIBUTE_NONNULL bool snmp_session_gen_sec_key(struct snmp_session /* }}} */ /* {{{ Set context Engine Id in the snmpv3 session */ -static bool snmp_session_set_contextEngineID(struct snmp_session *s, zend_string * contextEngineID, uint32_t contextEngineID_argument_offset) +static bool snmp_session_set_contextEngineID(struct snmp_session *s, zend_string *contextEngineID, uint32_t context_engine_id_arg_num) { size_t ebuf_len = 32, eout_len = 0; uint8_t *ebuf = (uint8_t *) emalloc(ebuf_len); if (!snmp_hex_to_binary(&ebuf, &ebuf_len, &eout_len, 1, ZSTR_VAL(contextEngineID))) { - zend_argument_value_error(contextEngineID_argument_offset, "must be a valid context engine ID"); + zend_argument_value_error(context_engine_id_arg_num, "must be a valid context engine ID"); efree(ebuf); return false; } @@ -1134,13 +1134,13 @@ static bool snmp_session_set_contextEngineID(struct snmp_session *s, zend_string /* }}} */ /* {{{ Set all snmpv3-related security options - * auth_protocol_argnum and contextEngineID_argument_offset are the userland + * auth_protocol_arg_num and context_engine_id_arg_num are the userland * argument numbers used for error reporting. */ static ZEND_ATTRIBUTE_NONNULL_ARGS(2) bool snmp_session_set_security(struct snmp_session *session, zend_string *sec_level, zend_string *auth_protocol, zend_string *auth_passphrase, zend_string *priv_protocol, zend_string *priv_passphrase, zend_string *contextName, zend_string *contextEngineID, - uint32_t auth_protocol_argnum, uint32_t contextEngineID_argument_offset) + uint32_t auth_protocol_arg_num, uint32_t context_engine_id_arg_num) { /* Setting the security level. */ @@ -1152,7 +1152,7 @@ static ZEND_ATTRIBUTE_NONNULL_ARGS(2) bool snmp_session_set_security(struct snmp if (session->securityLevel == SNMP_SEC_LEVEL_AUTHNOPRIV || session->securityLevel == SNMP_SEC_LEVEL_AUTHPRIV) { if (!auth_protocol) { - zend_argument_value_error(auth_protocol_argnum, "cannot be null when security level is \"authNoPriv\" or \"authPriv\""); + zend_argument_value_error(auth_protocol_arg_num, "cannot be null when security level is \"authNoPriv\" or \"authPriv\""); return false; } @@ -1163,7 +1163,7 @@ static ZEND_ATTRIBUTE_NONNULL_ARGS(2) bool snmp_session_set_security(struct snmp } if (!auth_passphrase) { - zend_argument_value_error(auth_protocol_argnum + 1, "cannot be null when security level is \"authNoPriv\" or \"authPriv\""); + zend_argument_value_error(auth_protocol_arg_num + 1, "cannot be null when security level is \"authNoPriv\" or \"authPriv\""); return false; } @@ -1176,7 +1176,7 @@ static ZEND_ATTRIBUTE_NONNULL_ARGS(2) bool snmp_session_set_security(struct snmp if (session->securityLevel == SNMP_SEC_LEVEL_AUTHPRIV) { if (!priv_protocol) { - zend_argument_value_error(auth_protocol_argnum + 2, "cannot be null when security level is \"authPriv\""); + zend_argument_value_error(auth_protocol_arg_num + 2, "cannot be null when security level is \"authPriv\""); return false; } @@ -1187,7 +1187,7 @@ static ZEND_ATTRIBUTE_NONNULL_ARGS(2) bool snmp_session_set_security(struct snmp } if (!priv_passphrase) { - zend_argument_value_error(auth_protocol_argnum + 3, "cannot be null when security level is \"authPriv\""); + zend_argument_value_error(auth_protocol_arg_num + 3, "cannot be null when security level is \"authPriv\""); return false; } @@ -1206,7 +1206,7 @@ static ZEND_ATTRIBUTE_NONNULL_ARGS(2) bool snmp_session_set_security(struct snmp } /* Setting contextEngineIS if specified */ - if (contextEngineID && ZSTR_LEN(contextEngineID) && !snmp_session_set_contextEngineID(session, contextEngineID, contextEngineID_argument_offset)) { + if (contextEngineID && ZSTR_LEN(contextEngineID) && !snmp_session_set_contextEngineID(session, contextEngineID, context_engine_id_arg_num)) { /* Warning message sent already, just bail out */ return false; } @@ -1226,15 +1226,17 @@ static void php_snmp(INTERNAL_FUNCTION_PARAMETERS, int st, int version) { zend_string *oid_str, *type_str = NULL, *value_str = NULL; HashTable *oid_ht, *type_ht = NULL, *value_ht = NULL; - zend_string *a1 = NULL, *a2 = NULL, *a3 = NULL, *a4 = NULL, *a5 = NULL, *a6 = NULL, *a7 = NULL; + zend_string *hostname = NULL, *community_or_security_name = NULL; + zend_string *security_level = NULL, *auth_protocol = NULL, *auth_passphrase = NULL; + zend_string *privacy_protocol = NULL, *privacy_passphrase = NULL; bool use_orignames = 0, suffix_keys = 0; zend_long timeout = SNMP_DEFAULT_TIMEOUT; zend_long retries = SNMP_DEFAULT_RETRIES; struct objid_query objid_query; php_snmp_session *session; int session_less_mode = (getThis() == NULL); - int timeout_argument_offset = -1; - uint32_t oid_argument_offset = 1, type_argument_offset = 0, value_argument_offset = 0; + uint32_t timeout_arg_num = 0; + uint32_t oid_arg_num = 1, type_arg_num = 0, value_arg_num = 0; php_snmp_object *snmp_object; php_snmp_object glob_snmp_object; @@ -1247,13 +1249,13 @@ static void php_snmp(INTERNAL_FUNCTION_PARAMETERS, int st, int version) if (version == SNMP_VERSION_3) { if (st & SNMP_CMD_SET) { ZEND_PARSE_PARAMETERS_START(10, 12) - Z_PARAM_PATH_STR(a1) - Z_PARAM_PATH_STR(a2) - Z_PARAM_STR(a3) - Z_PARAM_STR(a4) - Z_PARAM_STR(a5) - Z_PARAM_STR(a6) - Z_PARAM_STR(a7) + Z_PARAM_PATH_STR(hostname) + Z_PARAM_PATH_STR(community_or_security_name) + Z_PARAM_STR(security_level) + Z_PARAM_STR(auth_protocol) + Z_PARAM_STR(auth_passphrase) + Z_PARAM_STR(privacy_protocol) + Z_PARAM_STR(privacy_passphrase) Z_PARAM_ARRAY_HT_OR_STR(oid_ht, oid_str) Z_PARAM_ARRAY_HT_OR_STR(type_ht, type_str) Z_PARAM_ARRAY_HT_OR_STR(value_ht, value_str) @@ -1262,37 +1264,37 @@ static void php_snmp(INTERNAL_FUNCTION_PARAMETERS, int st, int version) Z_PARAM_LONG(retries) ZEND_PARSE_PARAMETERS_END(); - timeout_argument_offset = 10; - oid_argument_offset = 8; - type_argument_offset = 9; - value_argument_offset = 10; + timeout_arg_num = 10; + oid_arg_num = 8; + type_arg_num = 9; + value_arg_num = 10; } else { /* SNMP_CMD_GET * SNMP_CMD_GETNEXT * SNMP_CMD_WALK */ ZEND_PARSE_PARAMETERS_START(8, 10) - Z_PARAM_PATH_STR(a1) - Z_PARAM_PATH_STR(a2) - Z_PARAM_STR(a3) - Z_PARAM_STR(a4) - Z_PARAM_STR(a5) - Z_PARAM_STR(a6) - Z_PARAM_STR(a7) + Z_PARAM_PATH_STR(hostname) + Z_PARAM_PATH_STR(community_or_security_name) + Z_PARAM_STR(security_level) + Z_PARAM_STR(auth_protocol) + Z_PARAM_STR(auth_passphrase) + Z_PARAM_STR(privacy_protocol) + Z_PARAM_STR(privacy_passphrase) Z_PARAM_ARRAY_HT_OR_STR(oid_ht, oid_str) Z_PARAM_OPTIONAL Z_PARAM_LONG(timeout) Z_PARAM_LONG(retries) ZEND_PARSE_PARAMETERS_END(); - timeout_argument_offset = 9; - oid_argument_offset = 8; + timeout_arg_num = 9; + oid_arg_num = 8; } } else { if (st & SNMP_CMD_SET) { ZEND_PARSE_PARAMETERS_START(5, 7) - Z_PARAM_PATH_STR(a1) - Z_PARAM_PATH_STR(a2) + Z_PARAM_PATH_STR(hostname) + Z_PARAM_PATH_STR(community_or_security_name) Z_PARAM_ARRAY_HT_OR_STR(oid_ht, oid_str) Z_PARAM_ARRAY_HT_OR_STR(type_ht, type_str) Z_PARAM_ARRAY_HT_OR_STR(value_ht, value_str) @@ -1301,26 +1303,26 @@ static void php_snmp(INTERNAL_FUNCTION_PARAMETERS, int st, int version) Z_PARAM_LONG(retries) ZEND_PARSE_PARAMETERS_END(); - timeout_argument_offset = 6; - oid_argument_offset = 3; - type_argument_offset = 4; - value_argument_offset = 5; + timeout_arg_num = 6; + oid_arg_num = 3; + type_arg_num = 4; + value_arg_num = 5; } else { /* SNMP_CMD_GET * SNMP_CMD_GETNEXT * SNMP_CMD_WALK */ ZEND_PARSE_PARAMETERS_START(3, 5) - Z_PARAM_PATH_STR(a1) - Z_PARAM_PATH_STR(a2) + Z_PARAM_PATH_STR(hostname) + Z_PARAM_PATH_STR(community_or_security_name) Z_PARAM_ARRAY_HT_OR_STR(oid_ht, oid_str) Z_PARAM_OPTIONAL Z_PARAM_LONG(timeout) Z_PARAM_LONG(retries) ZEND_PARSE_PARAMETERS_END(); - timeout_argument_offset = 4; - oid_argument_offset = 3; + timeout_arg_num = 4; + oid_arg_num = 3; } } } else { @@ -1330,8 +1332,8 @@ static void php_snmp(INTERNAL_FUNCTION_PARAMETERS, int st, int version) Z_PARAM_ARRAY_HT_OR_STR(type_ht, type_str) Z_PARAM_ARRAY_HT_OR_STR(value_ht, value_str) ZEND_PARSE_PARAMETERS_END(); - type_argument_offset = 2; - value_argument_offset = 3; + type_arg_num = 2; + value_arg_num = 3; } else if (st & SNMP_CMD_WALK) { ZEND_PARSE_PARAMETERS_START(1, 4) Z_PARAM_ARRAY_HT_OR_STR(oid_ht, oid_str) @@ -1362,17 +1364,17 @@ 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_str, type_ht, value_str, value_ht, - oid_argument_offset, type_argument_offset, value_argument_offset)) { + oid_arg_num, type_arg_num, value_arg_num)) { RETURN_FALSE; } if (session_less_mode) { - if (!snmp_session_init(&session, version, a1, a2, timeout, retries, 1, timeout_argument_offset)) { + if (!snmp_session_init(&session, version, hostname, community_or_security_name, timeout, retries, 1, timeout_arg_num)) { php_free_objid_query(&objid_query, oid_ht, value_ht, st); snmp_session_free(&session); RETURN_FALSE; } - if (version == SNMP_VERSION_3 && !snmp_session_set_security(session, a3, a4, a5, a6, a7, NULL, NULL, 4, 0)) { + if (version == SNMP_VERSION_3 && !snmp_session_set_security(session, security_level, auth_protocol, auth_passphrase, privacy_protocol, privacy_passphrase, NULL, NULL, 4, 0)) { php_free_objid_query(&objid_query, oid_ht, value_ht, st); snmp_session_free(&session); /* An error has already been emitted, just bail out. */ @@ -1729,7 +1731,11 @@ PHP_METHOD(SNMP, setSecurity) { php_snmp_object *snmp_object; zval *object = ZEND_THIS; - zend_string *a1 = NULL, *a2 = NULL, *a3 = NULL, *a4 = NULL, *a5 = NULL, *a6 = NULL, *a7 = NULL; + zend_string *security_level = NULL, *auth_protocol = NULL, *auth_passphrase = NULL; + zend_string *privacy_protocol = NULL, *privacy_passphrase = NULL; + zend_string *context_name = NULL, *context_engine_id = NULL; + uint32_t auth_protocol_arg_num = 2; + uint32_t context_engine_id_arg_num = 7; snmp_object = Z_SNMP_P(object); if (!snmp_object->session) { @@ -1737,12 +1743,11 @@ PHP_METHOD(SNMP, setSecurity) RETURN_THROWS(); } - if (zend_parse_parameters(ZEND_NUM_ARGS(), "S|SSSSSS", &a1, &a2, &a3, &a4,&a5, &a6, &a7) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "S|SSSSSS", &security_level, &auth_protocol, &auth_passphrase, &privacy_protocol, &privacy_passphrase, &context_name, &context_engine_id) == FAILURE) { RETURN_THROWS(); } - /* authProtocol is argument #2 and contextEngineId is argument #7. */ - if (!snmp_session_set_security(snmp_object->session, a1, a2, a3, a4, a5, a6, a7, 2, 7)) { + if (!snmp_session_set_security(snmp_object->session, security_level, auth_protocol, auth_passphrase, privacy_protocol, privacy_passphrase, context_name, context_engine_id, auth_protocol_arg_num, context_engine_id_arg_num)) { /* An error has already been emitted, just bail out. */ RETURN_FALSE; } diff --git a/ext/spl/spl_directory.c b/ext/spl/spl_directory.c index cae8ffabc6721..1468cec6ccf3d 100644 --- a/ext/spl/spl_directory.c +++ b/ext/spl/spl_directory.c @@ -1811,21 +1811,24 @@ static zend_result spl_filesystem_file_read_ex(spl_filesystem_object *intern, bo } if (!buf) { - intern->u.file.current_line = ZSTR_EMPTY_ALLOC(); - } else { - if (!csv && SPL_HAS_FLAG(intern->flags, SPL_FILE_OBJECT_DROP_NEW_LINE)) { - if (line_len > 0 && buf[line_len - 1] == '\n') { + if (!silent) { + spl_filesystem_file_cannot_read(intern); + } + return FAILURE; + } + + if (!csv && SPL_HAS_FLAG(intern->flags, SPL_FILE_OBJECT_DROP_NEW_LINE)) { + if (line_len > 0 && buf[line_len - 1] == '\n') { + line_len--; + if (line_len > 0 && buf[line_len - 1] == '\r') { line_len--; - if (line_len > 0 && buf[line_len - 1] == '\r') { - line_len--; - } - buf[line_len] = '\0'; } + buf[line_len] = '\0'; } - - intern->u.file.current_line = zend_string_init(buf, line_len, /* persistent */ false); - efree(buf); } + + intern->u.file.current_line = zend_string_init(buf, line_len, /* persistent */ false); + efree(buf); intern->u.file.current_line_num += line_add; return SUCCESS; @@ -2091,10 +2094,17 @@ PHP_METHOD(SplFileObject, fgets) CHECK_SPL_FILE_OBJECT_IS_INITIALIZED(intern); - if (spl_filesystem_file_read_ex(intern, /* silent */ false, /* line_add */ 1, /* csv */ false) == FAILURE) { - RETURN_THROWS(); + if (intern->u.file.current_line) { + RETVAL_STR_COPY(intern->u.file.current_line); + spl_filesystem_file_free_line(intern); + intern->u.file.current_line_num++; + } else { + if (spl_filesystem_file_read_ex(intern, /* silent */ false, /* line_add */ 1, /* csv */ false) == FAILURE) { + RETURN_THROWS(); + } + RETVAL_STR_COPY(intern->u.file.current_line); + spl_filesystem_file_free_line(intern); } - RETURN_STR_COPY(intern->u.file.current_line); } /* }}} */ /* {{{ Return current line from file */ @@ -2140,6 +2150,12 @@ PHP_METHOD(SplFileObject, next) ZEND_PARSE_PARAMETERS_NONE(); + if (!intern->u.file.current_line && Z_ISUNDEF(intern->u.file.current_zval)) { + if (spl_filesystem_file_read_line(ZEND_THIS, intern, true) == FAILURE) { + return; + } + } + spl_filesystem_file_free_line(intern); if (SPL_HAS_FLAG(intern->flags, SPL_FILE_OBJECT_READ_AHEAD)) { spl_filesystem_file_read_line(ZEND_THIS, intern, true); @@ -2627,7 +2643,7 @@ PHP_METHOD(SplFileObject, seek) for (i = 0; i < line_pos; i++) { if (spl_filesystem_file_read_line(ZEND_THIS, intern, true) == FAILURE) { - return; + break; } } if (line_pos > 0 && !SPL_HAS_FLAG(intern->flags, SPL_FILE_OBJECT_READ_AHEAD)) { @@ -2646,9 +2662,8 @@ PHP_METHOD(SplFileObject, __toString) if (!intern->u.file.current_line) { ZEND_ASSERT(Z_ISUNDEF(intern->u.file.current_zval)); - zend_result result = spl_filesystem_file_read_line(ZEND_THIS, intern, false); - if (UNEXPECTED(result != SUCCESS)) { - RETURN_THROWS(); + if (spl_filesystem_file_read_line(ZEND_THIS, intern, true) == FAILURE) { + RETURN_EMPTY_STRING(); } } diff --git a/ext/spl/tests/SplFileObject/SplFileObject_key_error001.phpt b/ext/spl/tests/SplFileObject/SplFileObject_key_error001.phpt index 0c21d0b905e95..7d0e3ae8d9698 100644 --- a/ext/spl/tests/SplFileObject/SplFileObject_key_error001.phpt +++ b/ext/spl/tests/SplFileObject/SplFileObject_key_error001.phpt @@ -18,5 +18,5 @@ var_dump($s->key()); var_dump($s->valid()); ?> --EXPECT-- -int(14) +int(12) bool(false) diff --git a/ext/spl/tests/SplFileObject/SplFileObject_key_error002.phpt b/ext/spl/tests/SplFileObject/SplFileObject_key_error002.phpt index 8fc9b7fef0a58..0834dbc0524fc 100644 --- a/ext/spl/tests/SplFileObject/SplFileObject_key_error002.phpt +++ b/ext/spl/tests/SplFileObject/SplFileObject_key_error002.phpt @@ -18,5 +18,5 @@ var_dump($s->key()); var_dump($s->valid()); ?> --EXPECT-- -int(13) +int(12) bool(false) diff --git a/ext/spl/tests/SplFileObject/bug81477.phpt b/ext/spl/tests/SplFileObject/bug81477.phpt index f7730a791aa03..421c74dc4d68e 100644 --- a/ext/spl/tests/SplFileObject/bug81477.phpt +++ b/ext/spl/tests/SplFileObject/bug81477.phpt @@ -21,7 +21,6 @@ string(8) "baz,bat " string(10) "more,data " -string(0) "" --CLEAN-- rewind(); var_dump($file->fgetcsv()); ?> --EXPECT-- -array(1) { - [0]=> - NULL -} +bool(false) bool(false) diff --git a/ext/spl/tests/SplFileObject/gh8561.phpt b/ext/spl/tests/SplFileObject/gh8561.phpt new file mode 100644 index 0000000000000..adf36afb8b294 --- /dev/null +++ b/ext/spl/tests/SplFileObject/gh8561.phpt @@ -0,0 +1,30 @@ +--TEST-- +GH-8561 (SplFileObject: key() and current() unsynchronized after fgets()) +--FILE-- +fwrite("line {$i}" . PHP_EOL); +} + +// Case 1: rewind + fgets, then key/current +$file->rewind(); +$file->fgets(); +echo "After rewind+fgets: key=" . $file->key() . " current=" . trim($file->current()) . "\n"; + +// Case 2: multiple fgets +$file->rewind(); +$file->fgets(); +$file->fgets(); +echo "After rewind+fgets+fgets: key=" . $file->key() . " current=" . trim($file->current()) . "\n"; + +// Case 3: current then fgets +$file->rewind(); +$file->current(); +$file->fgets(); +echo "After current+fgets: key=" . $file->key() . " current=" . trim($file->current()) . "\n"; +?> +--EXPECT-- +After rewind+fgets: key=1 current=line 1 +After rewind+fgets+fgets: key=2 current=line 2 +After current+fgets: key=1 current=line 1 diff --git a/ext/spl/tests/SplFileObject/gh8563.phpt b/ext/spl/tests/SplFileObject/gh8563.phpt new file mode 100644 index 0000000000000..03891750f8bf8 --- /dev/null +++ b/ext/spl/tests/SplFileObject/gh8563.phpt @@ -0,0 +1,29 @@ +--TEST-- +GH-8563 (Different results for seek() on SplFileObject and SplTempFileObject) +--FILE-- +fwrite("line {$i}" . PHP_EOL); + $file_02->fwrite("line {$i}" . PHP_EOL); +} + +$file_01->rewind(); +$file_02->rewind(); + +$file_01->seek(10); +$file_02->seek(10); + +echo 'SplFileObject: ' . $file_01->key() . "\n"; +echo 'SplTempFileObject: ' . $file_02->key() . "\n"; +?> +--CLEAN-- + +--EXPECT-- +SplFileObject: 5 +SplTempFileObject: 5 diff --git a/ext/spl/tests/SplFileObject/gh8564.phpt b/ext/spl/tests/SplFileObject/gh8564.phpt new file mode 100644 index 0000000000000..ff16893c4c6b7 --- /dev/null +++ b/ext/spl/tests/SplFileObject/gh8564.phpt @@ -0,0 +1,20 @@ +--TEST-- +GH-8564 (SplFileObject: next() moves to nonexistent indexes) +--FILE-- +fwrite("line {$i}" . PHP_EOL); +} + +$file->rewind(); +for ($i = 0; $i < 10; $file->next(), $i++); +echo "next() 10x: key=" . $file->key() . " valid=" . var_export($file->valid(), true) . "\n"; + +$file->rewind(); +$file->seek(10); +echo "seek(10): key=" . $file->key() . " valid=" . var_export($file->valid(), true) . "\n"; +?> +--EXPECT-- +next() 10x: key=5 valid=false +seek(10): key=5 valid=false diff --git a/ext/spl/tests/gh13685.phpt b/ext/spl/tests/gh13685.phpt index 0f679d0e93fc9..2bdddec4584e5 100644 --- a/ext/spl/tests/gh13685.phpt +++ b/ext/spl/tests/gh13685.phpt @@ -44,9 +44,9 @@ try { string(14) ""A", "B", "C" " string(13) ""D", "E", "F"" -Cannot read from file php://temp +string(0) "" --- Use csv control --- string(14) ""A", "B", "C" " string(13) ""D", "E", "F"" -Cannot read from file php://temp +string(0) "" diff --git a/ext/spl/tests/gh8562.phpt b/ext/spl/tests/gh8562.phpt new file mode 100644 index 0000000000000..40b2554f57941 --- /dev/null +++ b/ext/spl/tests/gh8562.phpt @@ -0,0 +1,27 @@ +--TEST-- +GH-8562 (SplFileObject::current() returns wrong result after call to next()) +--FILE-- +fwrite("line {$i}" . PHP_EOL); +} + +$file->rewind(); +$file->next(); +echo "After rewind+next: key=" . $file->key() . " current=" . trim($file->current()) . "\n"; + +$file->rewind(); +$file->next(); +$file->next(); +echo "After rewind+next+next: key=" . $file->key() . " current=" . trim($file->current()) . "\n"; + +$file->rewind(); +$file->current(); +$file->next(); +echo "After current+next: key=" . $file->key() . " current=" . trim($file->current()) . "\n"; +?> +--EXPECT-- +After rewind+next: key=1 current=line 1 +After rewind+next+next: key=2 current=line 2 +After current+next: key=1 current=line 1 diff --git a/run-tests.php b/run-tests.php index b0bdc15518ee3..c08d07cdd7c18 100755 --- a/run-tests.php +++ b/run-tests.php @@ -302,6 +302,7 @@ function main(): void 'zend.exception_ignore_args=0', 'zend.exception_string_param_max_len=15', 'short_open_tag=0', + 'date.timezone=UTC', ]; $no_file_cache = '-d opcache.file_cache= -d opcache.file_cache_only=0';