diff --git a/NEWS b/NEWS index 434a132d78f31..3d76a45011bce 100644 --- a/NEWS +++ b/NEWS @@ -1,12 +1,18 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| -?? ??? ????, PHP 8.0.0rc1 +?? ??? ????, PHP 8.0.0RC1 + + +17 Sep 2020, PHP 8.0.0beta4 - 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) + . Fixed bug #80096 (Segmentation fault with named arguments in nested call). + (Nikita) + . Fixed faulty generator cleanup with yield from. (Bob) - Date: . Fixed bug #80057 (DateTimeImmutable::createFromFormat() does not populate diff --git a/UPGRADING.INTERNALS b/UPGRADING.INTERNALS index 462850993ada9..249cd553bab53 100644 --- a/UPGRADING.INTERNALS +++ b/UPGRADING.INTERNALS @@ -370,19 +370,19 @@ PHP 8.0 INTERNALS UPGRADE NOTES u. Instead of overwriting zend_error_cb extensions with debugging, monitoring use-cases catching Errors/Exceptions are strongly encouraged to use - the new error notification API instead. + the new error observer API instead. - Error notification callbacks are guaranteed to be called regardless of + Error observering callbacks are guaranteed to be called regardless of the users error_reporting setting or userland error handler return values. - Register notification callbacks during MINIT of an extension: + Register observer callbacks during MINIT of an extension: - void my_error_notify_cb(int type, + void my_error_observer_cb(int type, const char *error_filename, uint32_t error_lineno, zend_string *message) { } - zend_register_error_notify_callback(my_error_notify_cb); + zend_observer_error_register(my_error_observer_cb); v. The following APIs have been removed from the Zend Engine: - zend_ts_hash_init_ex(), drop the last argument and use zend_ts_hash_init() instead diff --git a/Zend/tests/bug31720.phpt b/Zend/tests/bug31720.phpt index e1ef782138c28..083ea78a01163 100644 --- a/Zend/tests/bug31720.phpt +++ b/Zend/tests/bug31720.phpt @@ -12,4 +12,4 @@ try { ?> --EXPECTF-- Warning: Undefined variable $nonesuchvar in %s on line %d -array_walk(): Argument #2 ($funcname) must be a valid callback, first array member is not a valid class name or object +array_walk(): Argument #2 ($callback) must be a valid callback, first array member is not a valid class name or object diff --git a/Zend/tests/bug41026.phpt b/Zend/tests/bug41026.phpt index 055e5f574dc04..0dde757d84cec 100644 --- a/Zend/tests/bug41026.phpt +++ b/Zend/tests/bug41026.phpt @@ -23,4 +23,4 @@ echo "Done\n"; --EXPECT-- Done -Warning: (Registered shutdown functions) Unable to call self::on_shutdown() - function does not exist in Unknown on line 0 +Fatal error: Registered shutdown function self::on_shutdown() cannot be called, function does not exist in Unknown on line 0 diff --git a/Zend/tests/bug52355.phpt b/Zend/tests/bug52355.phpt index 7f46c71d46ee9..0c207be2beeb6 100644 --- a/Zend/tests/bug52355.phpt +++ b/Zend/tests/bug52355.phpt @@ -10,11 +10,15 @@ $foo = -sin(0); var_dump($foo); -var_dump(@(1.0 / -0.0)); +try { + var_dump(1.0 / -0.0); +} catch (\DivisionByZeroError $e) { + echo $e->getMessage() . \PHP_EOL; +} ?> --EXPECT-- float(-0) float(-0) float(-0) -float(-INF) +Division by zero diff --git a/Zend/tests/bug69957.phpt b/Zend/tests/bug69957.phpt index 188e56405b806..d72d588978fbb 100644 --- a/Zend/tests/bug69957.phpt +++ b/Zend/tests/bug69957.phpt @@ -60,23 +60,26 @@ try { } ?> ---EXPECTF-- -Warning: Division by zero in %sbug69957.php on line %d -float(INF) +--EXPECT-- +Variable div +Type: DivisionByZeroError +Message: Division by zero Variable mod Type: DivisionByZeroError Message: Modulo by zero -Warning: Division by zero in %sbug69957.php on line %d -float(INF) +Literal div +Type: DivisionByZeroError +Message: Division by zero Literal mod Type: DivisionByZeroError Message: Modulo by zero -Warning: Division by zero in %sbug69957.php on line %d -float(INF) +Double div +Type: DivisionByZeroError +Message: Division by zero Double mod Type: DivisionByZeroError diff --git a/Zend/tests/bug76667.phpt b/Zend/tests/bug76667.phpt index cc5abb437262f..03bd490a04090 100644 --- a/Zend/tests/bug76667.phpt +++ b/Zend/tests/bug76667.phpt @@ -16,23 +16,14 @@ class T { } $x = new T; -$x->x = 1; +try { + $x->x = 1; +} catch (\DivisionByZeroError $e) { + echo $e->getMessage() . \PHP_EOL; +} ?> --EXPECTF-- Warning: Undefined variable $undefined in %s on line %d Warning: Attempt to read property "1" on null in %s on line %d - -Warning: Division by zero in %s on line %d - -Warning: Undefined variable $undefined in %s on line %d - -Warning: Attempt to read property "NAN" on null in %s on line %d - -Warning: Division by zero in %s on line %d - -Warning: Undefined variable $undefined in %s on line %d - -Warning: Attempt to read property "NAN" on null in %s on line %d - -Warning: Division by zero in %s on line %d +Division by zero diff --git a/Zend/tests/bug80096.phpt b/Zend/tests/bug80096.phpt new file mode 100644 index 0000000000000..d1d2d0249be1b --- /dev/null +++ b/Zend/tests/bug80096.phpt @@ -0,0 +1,14 @@ +--TEST-- +Bug #80096: Segmentation fault with named arguments in nested call +--FILE-- + +--EXPECT-- +The < character is encoded as < diff --git a/Zend/tests/generators/repeated_yield_from_with_immediate_release.phpt b/Zend/tests/generators/repeated_yield_from_with_immediate_release.phpt new file mode 100644 index 0000000000000..48813704b68fa --- /dev/null +++ b/Zend/tests/generators/repeated_yield_from_with_immediate_release.phpt @@ -0,0 +1,19 @@ +--TEST-- +A generator can be yielded from multiple times, testing immediate release of the yield from'ing generator +--FILE-- +current()); +var_dump(yield_from($gen)->current()); + +?> +--EXPECT-- +int(42) +int(42) diff --git a/Zend/tests/generators/yield_from_aborted_generator_with_children.phpt b/Zend/tests/generators/yield_from_aborted_generator_with_children.phpt new file mode 100644 index 0000000000000..7074e40ab67f7 --- /dev/null +++ b/Zend/tests/generators/yield_from_aborted_generator_with_children.phpt @@ -0,0 +1,31 @@ +--TEST-- +Impossible to yield from a generator which already failed, nested version +--FILE-- +next(); +} catch (Exception $e) { + unset($gen2); +} +$gen3->next(); + +?> +--EXPECTF-- +Fatal error: Uncaught Error: Generator passed to yield from was aborted without proper return and is unable to continue in %s:%d +Stack trace: +#0 [internal function]: gen(Object(Generator)) +#1 %s(%d): Generator->next() +#2 {main} + thrown in %s on line %d diff --git a/Zend/tests/generators/yield_from_multi_tree_single_nodes.phpt b/Zend/tests/generators/yield_from_multi_tree_single_nodes.phpt new file mode 100644 index 0000000000000..2d78ffdc68d6c --- /dev/null +++ b/Zend/tests/generators/yield_from_multi_tree_single_nodes.phpt @@ -0,0 +1,328 @@ +--TEST-- +yield from on multiple trees needing merge, with intermediary nodes having only one child +--FILE-- +> 1], $level); + } + } + + while (1) { + foreach ($all as $gen) { + var_dump($gen->current()); + $gen->next(); + if (!$gen->valid()) { + break 2; + } + } + } + + print "\n\n"; +} +?> +--EXPECT-- +0 levels + +int(0) +int(1) +int(2) + + +1 level + +int(0) +int(1) +int(2) +int(3) +int(4) + + +2 levels + +int(0) +int(1) +int(2) +int(3) +int(4) +int(5) +int(6) +int(7) +int(8) + + +3 levels + +int(0) +int(1) +int(2) +int(3) +int(4) +int(5) +int(6) +int(7) +int(8) +int(9) +int(10) +int(11) +int(12) +int(13) +int(14) +int(15) +int(16) + + +4 levels + +int(0) +int(1) +int(2) +int(3) +int(4) +int(5) +int(6) +int(7) +int(8) +int(9) +int(10) +int(11) +int(12) +int(13) +int(14) +int(15) +int(16) +int(17) +int(18) +int(19) +int(20) +int(21) +int(22) +int(23) +int(24) +int(25) +int(26) +int(27) +int(28) +int(29) +int(30) +int(31) +int(32) + + +5 levels + +int(0) +int(1) +int(2) +int(3) +int(4) +int(5) +int(6) +int(7) +int(8) +int(9) +int(10) +int(11) +int(12) +int(13) +int(14) +int(15) +int(16) +int(17) +int(18) +int(19) +int(20) +int(21) +int(22) +int(23) +int(24) +int(25) +int(26) +int(27) +int(28) +int(29) +int(30) +int(31) +int(32) +int(33) +int(34) +int(35) +int(36) +int(37) +int(38) +int(39) +int(40) +int(41) +int(42) +int(43) +int(44) +int(45) +int(46) +int(47) +int(48) +int(49) +int(50) +int(51) +int(52) +int(53) +int(54) +int(55) +int(56) +int(57) +int(58) +int(59) +int(60) +int(61) +int(62) +int(63) +int(64) + + +6 levels + +int(0) +int(1) +int(2) +int(3) +int(4) +int(5) +int(6) +int(7) +int(8) +int(9) +int(10) +int(11) +int(12) +int(13) +int(14) +int(15) +int(16) +int(17) +int(18) +int(19) +int(20) +int(21) +int(22) +int(23) +int(24) +int(25) +int(26) +int(27) +int(28) +int(29) +int(30) +int(31) +int(32) +int(33) +int(34) +int(35) +int(36) +int(37) +int(38) +int(39) +int(40) +int(41) +int(42) +int(43) +int(44) +int(45) +int(46) +int(47) +int(48) +int(49) +int(50) +int(51) +int(52) +int(53) +int(54) +int(55) +int(56) +int(57) +int(58) +int(59) +int(60) +int(61) +int(62) +int(63) +int(64) +int(65) +int(66) +int(67) +int(68) +int(69) +int(70) +int(71) +int(72) +int(73) +int(74) +int(75) +int(76) +int(77) +int(78) +int(79) +int(80) +int(81) +int(82) +int(83) +int(84) +int(85) +int(86) +int(87) +int(88) +int(89) +int(90) +int(91) +int(92) +int(93) +int(94) +int(95) +int(96) +int(97) +int(98) +int(99) +int(100) +int(101) +int(102) +int(103) +int(104) +int(105) +int(106) +int(107) +int(108) +int(109) +int(110) +int(111) +int(112) +int(113) +int(114) +int(115) +int(116) +int(117) +int(118) +int(119) +int(120) +int(121) +int(122) +int(123) +int(124) +int(125) +int(126) +int(127) +int(128) diff --git a/Zend/tests/named_params/missing_param.phpt b/Zend/tests/named_params/missing_param.phpt index 3ee2feae0a41f..f8b0b356ceebc 100644 --- a/Zend/tests/named_params/missing_param.phpt +++ b/Zend/tests/named_params/missing_param.phpt @@ -25,13 +25,13 @@ try { } // This works fine, as search_value is explicitly specified. -var_dump(array_keys([41, 42], search_value: 42, strict: true)); +var_dump(array_keys([41, 42], filter_value: 42, strict: true)); ?> --EXPECT-- test(): Argument #2 ($b) not passed array_keys(): Argument #1 ($array) not passed -array_keys(): Argument #2 ($search_value) must be passed explicitly, because the default value is not known +array_keys(): Argument #2 ($filter_value) must be passed explicitly, because the default value is not known array(1) { [0]=> int(1) diff --git a/Zend/tests/named_params/runtime_cache_init.phpt b/Zend/tests/named_params/runtime_cache_init.phpt new file mode 100644 index 0000000000000..e55db1a72de4c --- /dev/null +++ b/Zend/tests/named_params/runtime_cache_init.phpt @@ -0,0 +1,17 @@ +--TEST-- +Uninitialized run-time cache when resolving default values +--FILE-- + +--EXPECT-- +a = 42, b = 0 diff --git a/Zend/tests/nullsafe_operator/039.phpt b/Zend/tests/nullsafe_operator/039.phpt new file mode 100644 index 0000000000000..92983c1592e0a --- /dev/null +++ b/Zend/tests/nullsafe_operator/039.phpt @@ -0,0 +1,18 @@ +--TEST-- +Handling of undef variable exception in JMP_NULL +--FILE-- +foo; +} catch (Exception $e) { + echo $e->getMessage(), "\n"; +} + +?> +--EXPECT-- +Undefined variable $foo diff --git a/Zend/tests/numeric_strings/invalid_numeric_strings_must_generate_warning.phpt b/Zend/tests/numeric_strings/invalid_numeric_strings_must_generate_warning.phpt index 3ffe78a119e96..2b76f538f46ed 100644 --- a/Zend/tests/numeric_strings/invalid_numeric_strings_must_generate_warning.phpt +++ b/Zend/tests/numeric_strings/invalid_numeric_strings_must_generate_warning.phpt @@ -198,9 +198,9 @@ Unsupported operand types: int ^ string Warning: A non-numeric value encountered in %s on line %d int(149) -Unsupported operand types: int * string +Unsupported operand types: string * int --- Warning: A non-numeric value encountered in %s on line %d int(-151) -Unsupported operand types: int * string +Unsupported operand types: string * int diff --git a/Zend/tests/property_guard_hash_val.phpt b/Zend/tests/property_guard_hash_val.phpt new file mode 100644 index 0000000000000..69f1959a03b26 --- /dev/null +++ b/Zend/tests/property_guard_hash_val.phpt @@ -0,0 +1,16 @@ +--TEST-- +Test property guard hash value assumption +--FILE-- +{$var.''}; + } +} + +$test = new Test; +var_dump($test->x); +?> +--EXPECTF-- +Warning: Undefined property: Test::$x in %s on line %d +NULL diff --git a/Zend/tests/runtime_compile_time_binary_operands.phpt b/Zend/tests/runtime_compile_time_binary_operands.phpt index 9fe76b2efbdce..14195141b111e 100644 --- a/Zend/tests/runtime_compile_time_binary_operands.phpt +++ b/Zend/tests/runtime_compile_time_binary_operands.phpt @@ -5,7 +5,7 @@ memory_limit=256M --FILE-- getMessage()); + $line .= "try { $compare; $error } catch (Error \$e) { if (\$e->getMessage() !== $msg) { $error } }"; + } + return $line; +} $filename = __DIR__ . DIRECTORY_SEPARATOR . 'compare_binary_operands_temp.php'; $file = fopen($filename, "w"); @@ -126,14 +147,22 @@ fwrite($file, "error_function; @@ -865,7 +858,7 @@ void zend_startup(zend_utility_functions *utility_functions) /* {{{ */ zend_execute_ex = dtrace_execute_ex; zend_execute_internal = dtrace_execute_internal; - zend_register_error_notify_callback(dtrace_error_notify_cb); + zend_observer_error_register(dtrace_error_notify_cb); } else { zend_compile_file = compile_file; zend_execute_ex = execute_ex; @@ -1093,7 +1086,6 @@ void zend_shutdown(void) /* {{{ */ zend_hash_destroy(GLOBAL_AUTO_GLOBALS_TABLE); free(GLOBAL_AUTO_GLOBALS_TABLE); - zend_shutdown_error_notify_callbacks(); zend_shutdown_extensions(); free(zend_version_info); @@ -1329,7 +1321,7 @@ static ZEND_COLD void zend_error_impl( } } - zend_error_notify_all_callbacks(type, error_filename, error_lineno, message); + zend_observer_error_notify(type, error_filename, error_lineno, message); /* if we don't have a user defined error handler */ if (Z_TYPE(EG(user_error_handler)) == IS_UNDEF @@ -1792,29 +1784,3 @@ ZEND_API void zend_map_ptr_extend(size_t last) CG(map_ptr_last) = last; } } - -void zend_startup_error_notify_callbacks(void) -{ - zend_llist_init(&zend_error_notify_callbacks, sizeof(zend_error_notify_cb), NULL, 1); -} - -void zend_shutdown_error_notify_callbacks(void) -{ - zend_llist_destroy(&zend_error_notify_callbacks); -} - -ZEND_API void zend_register_error_notify_callback(zend_error_notify_cb cb) -{ - zend_llist_add_element(&zend_error_notify_callbacks, &cb); -} - -void zend_error_notify_all_callbacks(int type, const char *error_filename, uint32_t error_lineno, zend_string *message) -{ - zend_llist_element *element; - zend_error_notify_cb callback; - - for (element = zend_error_notify_callbacks.head; element; element = element->next) { - callback = *(zend_error_notify_cb *) (element->data); - callback(type, error_filename, error_lineno, message); - } -} diff --git a/Zend/zend.h b/Zend/zend.h index 47b938e2cd79e..c10fadd0d014c 100644 --- a/Zend/zend.h +++ b/Zend/zend.h @@ -350,15 +350,6 @@ ZEND_API void zend_save_error_handling(zend_error_handling *current); ZEND_API void zend_replace_error_handling(zend_error_handling_t error_handling, zend_class_entry *exception_class, zend_error_handling *current); ZEND_API void zend_restore_error_handling(zend_error_handling *saved); -typedef void (*zend_error_notify_cb)(int type, const char *error_filename, uint32_t error_lineno, zend_string *message); - -BEGIN_EXTERN_C() -ZEND_API void zend_register_error_notify_callback(zend_error_notify_cb callback); -void zend_startup_error_notify_callbacks(void); -void zend_shutdown_error_notify_callbacks(void); -void zend_error_notify_all_callbacks(int type, const char *error_filename, uint32_t error_lineno, zend_string *message); -END_EXTERN_C() - #define DEBUG_BACKTRACE_PROVIDE_OBJECT (1<<0) #define DEBUG_BACKTRACE_IGNORE_ARGS (1<<1) diff --git a/Zend/zend_API.c b/Zend/zend_API.c index 14abdd1a38b64..ee0e361ed9966 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -221,15 +221,21 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_error(int error_code, case ZPP_ERROR_WRONG_CLASS_OR_NULL: zend_wrong_parameter_class_or_null_error(num, name, arg); break; - case ZPP_ERROR_WRONG_ARG: - zend_wrong_parameter_type_error(num, expected_type, arg); - break; case ZPP_ERROR_WRONG_CLASS_OR_STRING: zend_wrong_parameter_class_or_string_error(num, name, arg); break; case ZPP_ERROR_WRONG_CLASS_OR_STRING_OR_NULL: zend_wrong_parameter_class_or_string_or_null_error(num, name, arg); break; + case ZPP_ERROR_WRONG_CLASS_OR_LONG: + zend_wrong_parameter_class_or_long_error(num, name, arg); + break; + case ZPP_ERROR_WRONG_CLASS_OR_LONG_OR_NULL: + zend_wrong_parameter_class_or_long_or_null_error(num, name, arg); + break; + case ZPP_ERROR_WRONG_ARG: + zend_wrong_parameter_type_error(num, expected_type, arg); + break; case ZPP_ERROR_UNEXPECTED_EXTRA_NAMED: zend_unexpected_extra_named_error(); break; @@ -280,6 +286,26 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_or_null_error(u } /* }}} */ +ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_or_long_error(uint32_t num, const char *name, zval *arg) /* {{{ */ +{ + if (EG(exception)) { + return; + } + + zend_argument_type_error(num, "must be of type %s|int, %s given", name, zend_zval_type_name(arg)); +} +/* }}} */ + +ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_or_long_or_null_error(uint32_t num, const char *name, zval *arg) /* {{{ */ +{ + if (EG(exception)) { + return; + } + + zend_argument_type_error(num, "must be of type %s|int|null, %s given", name, zend_zval_type_name(arg)); +} +/* }}} */ + ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_or_string_error(uint32_t num, const char *name, zval *arg) /* {{{ */ { if (EG(exception)) { diff --git a/Zend/zend_API.h b/Zend/zend_API.h index c4743e775d19d..da9a57d5c66dd 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_ARRAY_OR_LONG, "of type array|int") \ + _(Z_EXPECTED_ARRAY_OR_LONG_OR_NULL, "of type array|int|null") \ _(Z_EXPECTED_ITERABLE, "of type iterable") \ _(Z_EXPECTED_ITERABLE_OR_NULL, "of type ?iterable") \ _(Z_EXPECTED_FUNC, "a valid callback") \ @@ -1248,6 +1250,8 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_error(int error_code, ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_type_error(uint32_t num, zend_expected_type expected_type, zval *arg); ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_error(uint32_t num, const char *name, zval *arg); ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_or_null_error(uint32_t num, const char *name, zval *arg); +ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_or_long_error(uint32_t num, const char *name, zval *arg); +ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_or_long_or_null_error(uint32_t num, const char *name, zval *arg); ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_or_string_error(uint32_t num, const char *name, zval *arg); ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_or_string_or_null_error(uint32_t num, const char *name, zval *arg); ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_callback_error(uint32_t num, char *error); @@ -1261,11 +1265,13 @@ ZEND_API ZEND_COLD void zend_argument_value_error(uint32_t arg_num, const char * #define ZPP_ERROR_WRONG_CALLBACK 2 #define ZPP_ERROR_WRONG_CLASS 3 #define ZPP_ERROR_WRONG_CLASS_OR_NULL 4 -#define ZPP_ERROR_WRONG_ARG 5 -#define ZPP_ERROR_WRONG_COUNT 6 -#define ZPP_ERROR_WRONG_CLASS_OR_STRING 7 -#define ZPP_ERROR_WRONG_CLASS_OR_STRING_OR_NULL 8 -#define ZPP_ERROR_UNEXPECTED_EXTRA_NAMED 9 +#define ZPP_ERROR_WRONG_CLASS_OR_STRING 5 +#define ZPP_ERROR_WRONG_CLASS_OR_STRING_OR_NULL 6 +#define ZPP_ERROR_WRONG_CLASS_OR_LONG 7 +#define ZPP_ERROR_WRONG_CLASS_OR_LONG_OR_NULL 8 +#define ZPP_ERROR_WRONG_ARG 9 +#define ZPP_ERROR_WRONG_COUNT 10 +#define ZPP_ERROR_UNEXPECTED_EXTRA_NAMED 11 #define ZEND_PARSE_PARAMETERS_START_EX(flags, min_num_args, max_num_args) do { \ const int _flags = (flags); \ @@ -1530,6 +1536,20 @@ ZEND_API ZEND_COLD void zend_argument_value_error(uint32_t arg_num, const char * #define Z_PARAM_ARRAY_HT_OR_NULL(dest) \ Z_PARAM_ARRAY_HT_EX(dest, 1, 0) +#define Z_PARAM_ARRAY_HT_OR_LONG_EX(dest_ht, dest_long, is_null, allow_null) \ + Z_PARAM_PROLOGUE(0, 0); \ + if (UNEXPECTED(!zend_parse_arg_array_ht_or_long(_arg, &dest_ht, &dest_long, &is_null, allow_null))) { \ + _expected_type = allow_null ? Z_EXPECTED_ARRAY_OR_LONG_OR_NULL : Z_EXPECTED_ARRAY_OR_LONG; \ + _error_code = ZPP_ERROR_WRONG_ARG; \ + break; \ + } + +#define Z_PARAM_ARRAY_HT_OR_LONG(dest_ht, dest_long) \ + Z_PARAM_ARRAY_HT_OR_LONG_EX(dest_ht, dest_long, _dummy, 0) + +#define Z_PARAM_ARRAY_HT_OR_LONG_OR_NULL(dest_ht, dest_long, is_null) \ + Z_PARAM_ARRAY_HT_OR_LONG_EX(dest_ht, dest_long, is_null, 1) + /* old "H" */ #define Z_PARAM_ARRAY_OR_OBJECT_HT_EX2(dest, check_null, deref, separate) \ Z_PARAM_PROLOGUE(deref, separate); \ @@ -1638,6 +1658,44 @@ ZEND_API ZEND_COLD void zend_argument_value_error(uint32_t arg_num, const char * #define Z_PARAM_OBJECT_OF_CLASS_OR_NULL(dest, _ce) \ Z_PARAM_OBJECT_OF_CLASS_EX(dest, _ce, 1, 0) +/* The same as Z_PARAM_OBJECT_OF_CLASS_EX2 except that dest is a zend_object rather than a zval */ +#define Z_PARAM_OBJ_OF_CLASS_EX2(dest, _ce, check_null, deref, separate) \ + Z_PARAM_PROLOGUE(deref, separate); \ + if (UNEXPECTED(!zend_parse_arg_obj(_arg, &dest, _ce, check_null))) { \ + if (_ce) { \ + _error = ZSTR_VAL((_ce)->name); \ + _error_code = check_null ? ZPP_ERROR_WRONG_CLASS_OR_NULL : ZPP_ERROR_WRONG_CLASS; \ + break; \ + } else { \ + _expected_type = check_null ? Z_EXPECTED_OBJECT_OR_NULL : Z_EXPECTED_OBJECT; \ + _error_code = ZPP_ERROR_WRONG_ARG; \ + break; \ + } \ + } + +#define Z_PARAM_OBJ_OF_CLASS_EX(dest, _ce, check_null, separate) \ + Z_PARAM_OBJ_OF_CLASS_EX2(dest, _ce, check_null, separate, separate) + +#define Z_PARAM_OBJ_OF_CLASS(dest, _ce) \ + Z_PARAM_OBJ_OF_CLASS_EX(dest, _ce, 0, 0) + +#define Z_PARAM_OBJ_OF_CLASS_OR_NULL(dest, _ce) \ + Z_PARAM_OBJ_OF_CLASS_EX(dest, _ce, 1, 0) + +#define Z_PARAM_OBJ_OF_CLASS_OR_LONG_EX(dest_obj, _ce, dest_long, is_null, allow_null) \ + Z_PARAM_PROLOGUE(0, 0); \ + if (UNEXPECTED(!zend_parse_arg_obj_or_long(_arg, &dest_obj, _ce, &dest_long, &is_null, allow_null))) { \ + _error = ZSTR_VAL((_ce)->name); \ + _error_code = allow_null ? ZPP_ERROR_WRONG_CLASS_OR_LONG_OR_NULL : ZPP_ERROR_WRONG_CLASS_OR_LONG; \ + break; \ + } + +#define Z_PARAM_OBJ_OF_CLASS_OR_LONG(dest_obj, _ce, dest_long) \ + Z_PARAM_OBJ_OF_CLASS_OR_LONG_EX(dest_obj, _ce, dest_long, _dummy, 0) + +#define Z_PARAM_OBJ_OF_CLASS_OR_LONG_OR_NULL(dest_obj, _ce, dest_long, is_null) \ + Z_PARAM_OBJ_OF_CLASS_OR_LONG_EX(dest_obj, _ce, dest_long, is_null, 1) + /* old "p" */ #define Z_PARAM_PATH_EX2(dest, dest_len, check_null, deref, separate) \ Z_PARAM_PROLOGUE(deref, separate); \ @@ -1991,6 +2049,29 @@ static zend_always_inline bool zend_parse_arg_array_ht(zval *arg, HashTable **de return 1; } +static zend_always_inline bool zend_parse_arg_array_ht_or_long( + zval *arg, HashTable **dest_ht, zend_long *dest_long, zend_bool *is_null, bool allow_null +) { + if (allow_null) { + *is_null = 0; + } + + if (EXPECTED(Z_TYPE_P(arg) == IS_ARRAY)) { + *dest_ht = Z_ARRVAL_P(arg); + } else if (EXPECTED(Z_TYPE_P(arg) == IS_LONG)) { + *dest_ht = NULL; + *dest_long = Z_LVAL_P(arg); + } else if (allow_null && EXPECTED(Z_TYPE_P(arg) == IS_NULL)) { + *dest_ht = NULL; + *is_null = 1; + } else { + *dest_ht = NULL; + return zend_parse_arg_long_slow(arg, dest_long); + } + + return 1; +} + static zend_always_inline bool zend_parse_arg_object(zval *arg, zval **dest, zend_class_entry *ce, bool check_null) { if (EXPECTED(Z_TYPE_P(arg) == IS_OBJECT) && @@ -2017,6 +2098,29 @@ static zend_always_inline bool zend_parse_arg_obj(zval *arg, zend_object **dest, return 1; } +static zend_always_inline bool zend_parse_arg_obj_or_long( + zval *arg, zend_object **dest_obj, zend_class_entry *ce, zend_long *dest_long, zend_bool *is_null, bool allow_null +) { + if (allow_null) { + *is_null = 0; + } + + if (EXPECTED(Z_TYPE_P(arg) == IS_OBJECT) && EXPECTED(instanceof_function(Z_OBJCE_P(arg), ce) != 0)) { + *dest_obj = Z_OBJ_P(arg); + } else if (EXPECTED(Z_TYPE_P(arg) == IS_LONG)) { + *dest_obj = NULL; + *dest_long = Z_LVAL_P(arg); + } else if (allow_null && EXPECTED(Z_TYPE_P(arg) == IS_NULL)) { + *dest_obj = NULL; + *is_null = 1; + } else { + *dest_obj = NULL; + return zend_parse_arg_long_slow(arg, dest_long); + } + + 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)) { diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 6d07abe3e0980..719e7aaffeff0 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -7913,18 +7913,32 @@ static inline zend_bool zend_try_ct_eval_binary_op(zval *result, uint32_t opcode } /* }}} */ -static inline void zend_ct_eval_unary_op(zval *result, uint32_t opcode, zval *op) /* {{{ */ +zend_bool zend_unary_op_produces_error(uint32_t opcode, zval *op) { + if (opcode == ZEND_BW_NOT) { + return Z_TYPE_P(op) <= IS_TRUE || Z_TYPE_P(op) == IS_ARRAY; + } + + return 0; +} + +static inline zend_bool zend_try_ct_eval_unary_op(zval *result, uint32_t opcode, zval *op) /* {{{ */ +{ + if (zend_unary_op_produces_error(opcode, op)) { + return 0; + } + unary_op_type fn = get_unary_op(opcode); fn(result, op); + return 1; } /* }}} */ static inline zend_bool zend_try_ct_eval_unary_pm(zval *result, zend_ast_kind kind, zval *op) /* {{{ */ { - zval left; - ZVAL_LONG(&left, (kind == ZEND_AST_UNARY_PLUS) ? 1 : -1); - return zend_try_ct_eval_binary_op(result, ZEND_MUL, &left, op); + zval right; + ZVAL_LONG(&right, (kind == ZEND_AST_UNARY_PLUS) ? 1 : -1); + return zend_try_ct_eval_binary_op(result, ZEND_MUL, op, &right); } /* }}} */ @@ -8185,10 +8199,9 @@ void zend_compile_unary_op(znode *result, zend_ast *ast) /* {{{ */ znode expr_node; zend_compile_expr(&expr_node, expr_ast); - if (expr_node.op_type == IS_CONST) { + if (expr_node.op_type == IS_CONST + && zend_try_ct_eval_unary_op(&result->u.constant, opcode, &expr_node.u.constant)) { result->op_type = IS_CONST; - zend_ct_eval_unary_op(&result->u.constant, opcode, - &expr_node.u.constant); zval_ptr_dtor(&expr_node.u.constant); return; } @@ -8200,8 +8213,7 @@ void zend_compile_unary_op(znode *result, zend_ast *ast) /* {{{ */ void zend_compile_unary_pm(znode *result, zend_ast *ast) /* {{{ */ { zend_ast *expr_ast = ast->child[0]; - znode expr_node; - znode lefthand_node; + znode expr_node, right_node; ZEND_ASSERT(ast->kind == ZEND_AST_UNARY_PLUS || ast->kind == ZEND_AST_UNARY_MINUS); @@ -8214,9 +8226,9 @@ void zend_compile_unary_pm(znode *result, zend_ast *ast) /* {{{ */ return; } - lefthand_node.op_type = IS_CONST; - ZVAL_LONG(&lefthand_node.u.constant, (ast->kind == ZEND_AST_UNARY_PLUS) ? 1 : -1); - zend_emit_op_tmp(result, ZEND_MUL, &lefthand_node, &expr_node); + right_node.op_type = IS_CONST; + ZVAL_LONG(&right_node.u.constant, (ast->kind == ZEND_AST_UNARY_PLUS) ? 1 : -1); + zend_emit_op_tmp(result, ZEND_MUL, &expr_node, &right_node); } /* }}} */ @@ -9752,7 +9764,9 @@ void zend_eval_const_expr(zend_ast **ast_ptr) /* {{{ */ return; } - zend_ct_eval_unary_op(&result, ast->attr, zend_ast_get_zval(ast->child[0])); + if (!zend_try_ct_eval_unary_op(&result, ast->attr, zend_ast_get_zval(ast->child[0]))) { + return; + } break; case ZEND_AST_UNARY_PLUS: case ZEND_AST_UNARY_MINUS: diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index 505e625270ebb..ab1e0d2401690 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -238,7 +238,7 @@ typedef struct _zend_oparray_context { /* op_array or class is preloaded | | | */ #define ZEND_ACC_PRELOADED (1 << 10) /* X | X | | */ /* | | | */ -/* Class Flags (unused: 14, 15, 24...) | | | */ +/* Class Flags (unused: 22...) | | | */ /* =========== | | | */ /* | | | */ /* Special class types | | | */ @@ -264,30 +264,30 @@ typedef struct _zend_oparray_context { #define ZEND_ACC_NO_DYNAMIC_PROPERTIES (1 << 13) /* X | | | */ /* | | | */ /* User class has methods with static variables | | | */ -#define ZEND_HAS_STATIC_IN_METHODS (1 << 16) /* X | | | */ +#define ZEND_HAS_STATIC_IN_METHODS (1 << 14) /* X | | | */ /* | | | */ /* Whether all property types are resolved to CEs | | | */ -#define ZEND_ACC_PROPERTY_TYPES_RESOLVED (1 << 17) /* X | | | */ +#define ZEND_ACC_PROPERTY_TYPES_RESOLVED (1 << 15) /* X | | | */ /* | | | */ /* Children must reuse parent get_iterator() | | | */ -#define ZEND_ACC_REUSE_GET_ITERATOR (1 << 18) /* X | | | */ +#define ZEND_ACC_REUSE_GET_ITERATOR (1 << 16) /* X | | | */ /* | | | */ /* Parent class is resolved (CE). | | | */ -#define ZEND_ACC_RESOLVED_PARENT (1 << 19) /* X | | | */ +#define ZEND_ACC_RESOLVED_PARENT (1 << 17) /* X | | | */ /* | | | */ /* Interfaces are resolved (CEs). | | | */ -#define ZEND_ACC_RESOLVED_INTERFACES (1 << 20) /* X | | | */ +#define ZEND_ACC_RESOLVED_INTERFACES (1 << 18) /* X | | | */ /* | | | */ /* Class has unresolved variance obligations. | | | */ -#define ZEND_ACC_UNRESOLVED_VARIANCE (1 << 21) /* X | | | */ +#define ZEND_ACC_UNRESOLVED_VARIANCE (1 << 19) /* X | | | */ /* | | | */ /* Class is linked apart from variance obligations. | | | */ -#define ZEND_ACC_NEARLY_LINKED (1 << 22) /* X | | | */ +#define ZEND_ACC_NEARLY_LINKED (1 << 20) /* X | | | */ /* | | | */ /* Whether this class was used in its unlinked state. | | | */ -#define ZEND_ACC_HAS_UNLINKED_USES (1 << 23) /* X | | | */ +#define ZEND_ACC_HAS_UNLINKED_USES (1 << 21) /* X | | | */ /* | | | */ -/* Function Flags (unused: 17, 23, 26, 29) | | | */ +/* Function Flags (unused: 27-30) | | | */ /* ============== | | | */ /* | | | */ /* deprecation flag | | | */ @@ -309,6 +309,9 @@ typedef struct _zend_oparray_context { /* ZEND_DECLARE_CLASS_DELAYED opcodes | | | */ #define ZEND_ACC_EARLY_BINDING (1 << 16) /* | X | | */ /* | | | */ +/* closure uses $this | | | */ +#define ZEND_ACC_USES_THIS (1 << 17) /* | X | | */ +/* | | | */ /* call through user function trampoline. e.g. | | | */ /* __call, __callstatic | | | */ #define ZEND_ACC_CALL_VIA_TRAMPOLINE (1 << 18) /* | X | | */ @@ -316,15 +319,15 @@ typedef struct _zend_oparray_context { /* disable inline caching | | | */ #define ZEND_ACC_NEVER_CACHE (1 << 19) /* | X | | */ /* | | | */ -/* Closure related | | | */ -#define ZEND_ACC_CLOSURE (1 << 20) /* | X | | */ -#define ZEND_ACC_FAKE_CLOSURE (1 << 21) /* | X | | */ +/* op_array is a clone of trait method | | | */ +#define ZEND_ACC_TRAIT_CLONE (1 << 20) /* | X | | */ /* | | | */ -/* run_time_cache allocated on heap (user only) | | | */ -#define ZEND_ACC_HEAP_RT_CACHE (1 << 22) /* | X | | */ +/* functions is a constructor | | | */ +#define ZEND_ACC_CTOR (1 << 21) /* | X | | */ /* | | | */ -/* method flag used by Closure::__invoke() (int only) | | | */ -#define ZEND_ACC_USER_ARG_INFO (1 << 22) /* | X | | */ +/* Closure related | | | */ +#define ZEND_ACC_CLOSURE (1 << 22) /* | X | | */ +#define ZEND_ACC_FAKE_CLOSURE (1 << 23) /* | X | | */ /* Same as ZEND_CALL_FAKE_CLOSURE */ /* | | | */ #define ZEND_ACC_GENERATOR (1 << 24) /* | X | | */ /* | | | */ @@ -334,14 +337,11 @@ typedef struct _zend_oparray_context { /* internal function is allocated at arena (int only) | | | */ #define ZEND_ACC_ARENA_ALLOCATED (1 << 25) /* | X | | */ /* | | | */ -/* op_array is a clone of trait method | | | */ -#define ZEND_ACC_TRAIT_CLONE (1 << 27) /* | X | | */ -/* | | | */ -/* functions is a constructor | | | */ -#define ZEND_ACC_CTOR (1 << 28) /* | X | | */ +/* run_time_cache allocated on heap (user only) | | | */ +#define ZEND_ACC_HEAP_RT_CACHE (1 << 26) /* | X | | */ /* | | | */ -/* closure uses $this | | | */ -#define ZEND_ACC_USES_THIS (1 << 30) /* | X | | */ +/* method flag used by Closure::__invoke() (int only) | | | */ +#define ZEND_ACC_USER_ARG_INFO (1 << 26) /* | X | | */ /* | | | */ /* op_array uses strict mode types | | | */ #define ZEND_ACC_STRICT_TYPES (1U << 31) /* | X | | */ @@ -526,7 +526,7 @@ struct _zend_execute_data { #define ZEND_CALL_HAS_SYMBOL_TABLE (1 << 20) #define ZEND_CALL_RELEASE_THIS (1 << 21) #define ZEND_CALL_CLOSURE (1 << 22) -#define ZEND_CALL_FAKE_CLOSURE (1 << 23) +#define ZEND_CALL_FAKE_CLOSURE (1 << 23) /* Same as ZEND_ACC_FAKE_CLOSURE */ #define ZEND_CALL_GENERATOR (1 << 24) #define ZEND_CALL_DYNAMIC (1 << 25) #define ZEND_CALL_MAY_HAVE_UNDEF (1 << 26) diff --git a/Zend/zend_exceptions.c b/Zend/zend_exceptions.c index 7184f5bf68c6b..1a0b7d581a726 100644 --- a/Zend/zend_exceptions.c +++ b/Zend/zend_exceptions.c @@ -28,6 +28,7 @@ #include "zend_dtrace.h" #include "zend_smart_str.h" #include "zend_exceptions_arginfo.h" +#include "zend_observer.h" ZEND_API zend_class_entry *zend_ce_throwable; ZEND_API zend_class_entry *zend_ce_exception; @@ -900,7 +901,7 @@ static void zend_error_va(int type, const char *file, uint32_t lineno, const cha va_list args; va_start(args, format); zend_string *message = zend_vstrpprintf(0, format, args); - zend_error_notify_all_callbacks(type, file, lineno, message); + zend_observer_error_notify(type, file, lineno, message); zend_error_cb(type, file, lineno, message); zend_string_release(message); va_end(args); @@ -923,7 +924,7 @@ ZEND_API ZEND_COLD zend_result zend_exception_error(zend_object *ex, int severit zend_long line = zval_get_long(GET_PROPERTY_SILENT(&exception, ZEND_STR_LINE)); int type = (ce_exception == zend_ce_parse_error ? E_PARSE : E_COMPILE_ERROR) | E_DONT_BAIL; - zend_error_notify_all_callbacks(type, ZSTR_VAL(file), line, message); + zend_observer_error_notify(type, ZSTR_VAL(file), line, message); zend_error_cb(type, ZSTR_VAL(file), line, message); zend_string_release_ex(file, 0); diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 55466a1e07e4b..3c1931109463d 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -4016,27 +4016,29 @@ static zend_never_inline zend_execute_data *zend_init_dynamic_call_object(zend_o void *object_or_called_scope; zend_class_entry *called_scope; zend_object *object; - uint32_t call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_DYNAMIC; + uint32_t call_info; if (EXPECTED(function->handlers->get_closure) && EXPECTED(function->handlers->get_closure(function, &called_scope, &fbc, &object, 0) == SUCCESS)) { - object_or_called_scope = called_scope; - if (fbc->common.fn_flags & ZEND_ACC_CLOSURE) { + object_or_called_scope = called_scope; + if (EXPECTED(fbc->common.fn_flags & ZEND_ACC_CLOSURE)) { /* Delay closure destruction until its invocation */ GC_ADDREF(ZEND_CLOSURE_OBJECT(fbc)); - call_info |= ZEND_CALL_CLOSURE; - if (fbc->common.fn_flags & ZEND_ACC_FAKE_CLOSURE) { - call_info |= ZEND_CALL_FAKE_CLOSURE; - } + ZEND_ASSERT(ZEND_ACC_FAKE_CLOSURE == ZEND_CALL_FAKE_CLOSURE); + call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_DYNAMIC | ZEND_CALL_CLOSURE | + (fbc->common.fn_flags & ZEND_ACC_FAKE_CLOSURE); if (object) { call_info |= ZEND_CALL_HAS_THIS; object_or_called_scope = object; } - } else if (object) { - call_info |= ZEND_CALL_RELEASE_THIS | ZEND_CALL_HAS_THIS; - GC_ADDREF(object); /* For $this pointer */ - object_or_called_scope = object; + } else { + call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_DYNAMIC; + if (object) { + call_info |= ZEND_CALL_RELEASE_THIS | ZEND_CALL_HAS_THIS; + GC_ADDREF(object); /* For $this pointer */ + object_or_called_scope = object; + } } } else { zend_throw_error(NULL, "Object of type %s is not callable", ZSTR_VAL(function->ce->name)); @@ -4430,17 +4432,18 @@ zval * ZEND_FASTCALL zend_handle_named_arg( return arg; } -static void start_fake_frame(zend_execute_data *call, const zend_op *opline) { - zend_execute_data *prev_execute_data = EG(current_execute_data); - call->prev_execute_data = prev_execute_data; +static zend_execute_data *start_fake_frame(zend_execute_data *call, const zend_op *opline) { + zend_execute_data *old_prev_execute_data = call->prev_execute_data; + call->prev_execute_data = EG(current_execute_data); call->opline = opline; EG(current_execute_data) = call; + return old_prev_execute_data; } -static void end_fake_frame(zend_execute_data *call) { +static void end_fake_frame(zend_execute_data *call, zend_execute_data *old_prev_execute_data) { zend_execute_data *prev_execute_data = call->prev_execute_data; EG(current_execute_data) = prev_execute_data; - call->prev_execute_data = NULL; + call->prev_execute_data = old_prev_execute_data; if (UNEXPECTED(EG(exception)) && ZEND_USER_CODE(prev_execute_data->func->common.type)) { zend_rethrow_exception(prev_execute_data); } @@ -4461,6 +4464,10 @@ ZEND_API zend_result ZEND_FASTCALL zend_handle_undef_args(zend_execute_data *cal if (EXPECTED(opline->opcode == ZEND_RECV_INIT)) { zval *default_value = RT_CONSTANT(opline, opline->op2); if (Z_OPT_TYPE_P(default_value) == IS_CONSTANT_AST) { + if (UNEXPECTED(!RUN_TIME_CACHE(op_array))) { + init_func_run_time_cache(op_array); + } + void *run_time_cache = RUN_TIME_CACHE(op_array); zval *cache_val = (zval *) ((char *) run_time_cache + Z_CACHE_SLOT_P(default_value)); @@ -4473,9 +4480,9 @@ ZEND_API zend_result ZEND_FASTCALL zend_handle_undef_args(zend_execute_data *cal * value is not accessible through back traces. */ zval tmp; ZVAL_COPY(&tmp, default_value); - start_fake_frame(call, opline); + zend_execute_data *old = start_fake_frame(call, opline); zend_result ret = zval_update_constant_ex(&tmp, fbc->op_array.scope); - end_fake_frame(call); + end_fake_frame(call, old); if (UNEXPECTED(ret == FAILURE)) { zval_ptr_dtor_nogc(&tmp); return FAILURE; @@ -4490,9 +4497,9 @@ ZEND_API zend_result ZEND_FASTCALL zend_handle_undef_args(zend_execute_data *cal } } else { ZEND_ASSERT(opline->opcode == ZEND_RECV); - start_fake_frame(call, opline); + zend_execute_data *old = start_fake_frame(call, opline); zend_argument_error(zend_ce_argument_count_error, i + 1, "not passed"); - end_fake_frame(call); + end_fake_frame(call, old); return FAILURE; } } @@ -4513,25 +4520,25 @@ ZEND_API zend_result ZEND_FASTCALL zend_handle_undef_args(zend_execute_data *cal zend_internal_arg_info *arg_info = &fbc->internal_function.arg_info[i]; if (i < fbc->common.required_num_args) { - start_fake_frame(call, NULL); + zend_execute_data *old = start_fake_frame(call, NULL); zend_argument_error(zend_ce_argument_count_error, i + 1, "not passed"); - end_fake_frame(call); + end_fake_frame(call, old); return FAILURE; } zval default_value; if (zend_get_default_from_internal_arg_info(&default_value, arg_info) == FAILURE) { - start_fake_frame(call, NULL); + zend_execute_data *old = start_fake_frame(call, NULL); zend_argument_error(zend_ce_argument_count_error, i + 1, "must be passed explicitly, because the default value is not known"); - end_fake_frame(call); + end_fake_frame(call, old); return FAILURE; } if (Z_TYPE(default_value) == IS_CONSTANT_AST) { - start_fake_frame(call, NULL); + zend_execute_data *old = start_fake_frame(call, NULL); zend_result ret = zval_update_constant_ex(&default_value, fbc->common.scope); - end_fake_frame(call); + end_fake_frame(call, old); if (ret == FAILURE) { return FAILURE; } diff --git a/Zend/zend_execute.h b/Zend/zend_execute.h index 43b88dbd2c5a0..ab96d43c4c351 100644 --- a/Zend/zend_execute.h +++ b/Zend/zend_execute.h @@ -311,7 +311,7 @@ ZEND_API const char *get_active_class_name(const char **space); ZEND_API const char *get_active_function_name(void); ZEND_API const char *get_active_function_arg_name(uint32_t arg_num); ZEND_API const char *get_function_arg_name(const zend_function *func, uint32_t arg_num); -ZEND_API zend_string *get_active_function_or_method_name(); +ZEND_API zend_string *get_active_function_or_method_name(void); ZEND_API zend_string *get_function_or_method_name(const zend_function *func); ZEND_API const char *zend_get_executed_filename(void); ZEND_API zend_string *zend_get_executed_filename_ex(void); diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c index cbb0a10d06e62..baca12f66b56d 100644 --- a/Zend/zend_generators.c +++ b/Zend/zend_generators.c @@ -163,6 +163,52 @@ ZEND_API void zend_generator_close(zend_generator *generator, zend_bool finished static zend_generator *zend_generator_get_child(zend_generator_node *node, zend_generator *leaf); +static void zend_generator_update_leaf_of_child(zend_generator_node *node, zend_generator *from_leaf, zend_generator *to_leaf) +{ + ZEND_ASSERT(node->children >= 1); + if (node->ptr.leaf == from_leaf) { + node->ptr.leaf = to_leaf; + } + if (node->children == 1) { + node->child.single.leaf = to_leaf; + } else { + HashTable *ht = node->child.ht; + zend_generator *child = zend_hash_index_find_ptr(ht, (zend_ulong) from_leaf); + ZEND_ASSERT(child != NULL); + zend_hash_index_del(ht, (zend_ulong) from_leaf); + zend_hash_index_add_ptr(ht, (zend_ulong) to_leaf, child); + } +} + +static void zend_generator_remove_leaf_child(zend_generator_node *node, zend_generator *leaf, zend_generator *replace_leaf) { + if (node->children > 1) { + HashTable *ht = node->child.ht; + zend_ulong child_leaf; + zend_generator *child_generator; + zend_hash_index_del(ht, (zend_ulong) leaf); + if (--node->children == 1) { + ZEND_HASH_FOREACH_NUM_KEY_PTR(ht, child_leaf, child_generator) { + node->child.single.leaf = (zend_generator *) child_leaf; + node->child.single.child = child_generator; + if (node->ptr.leaf == leaf) { + node->ptr.leaf = (zend_generator *) child_leaf; + } + break; + } ZEND_HASH_FOREACH_END(); + zend_hash_destroy(ht); + efree(ht); + } else if (node->ptr.leaf == leaf) { + ZEND_HASH_FOREACH_NUM_KEY_PTR(ht, child_leaf, child_generator) { + node->ptr.leaf = (zend_generator *) child_leaf; + break; + } ZEND_HASH_FOREACH_END(); + } + } else if (node->ptr.leaf == leaf) { + ZEND_ASSERT(replace_leaf != leaf); + node->ptr.leaf = replace_leaf; + } +} + static void zend_generator_dtor_storage(zend_object *object) /* {{{ */ { zend_generator *generator = (zend_generator*) object; @@ -176,14 +222,47 @@ static void zend_generator_dtor_storage(zend_object *object) /* {{{ */ ZVAL_UNDEF(&generator->values); } + if (UNEXPECTED(generator->node.children != 0) && generator->node.parent) { + /* we're called out of order - this must only happen during shutdown sequence: we call our (direct) child nodes destructors first, to clean it from the bottom up */ + while (generator->node.children != 0) { + zend_generator *child; + if (generator->node.children == 1) { + child = generator->node.child.single.child; + } else { + child = (zend_generator *) Z_PTR_P(zend_hash_get_current_data(generator->node.child.ht)); + } + GC_ADD_FLAGS(&child->std, IS_OBJ_DESTRUCTOR_CALLED); + GC_ADDREF(&child->std); /* must not be released during destructor */ + zend_generator_dtor_storage(&child->std); + OBJ_RELEASE(&child->std); + } + } if (EXPECTED(generator->node.children == 0)) { - zend_generator *root = generator->node.ptr.root, *next; - while (UNEXPECTED(root != generator)) { - next = zend_generator_get_child(&root->node, generator); - generator->node.ptr.root = next; - next->node.parent = NULL; - OBJ_RELEASE(&root->std); - root = next; + zend_generator_update_current(generator, generator); /* ensure we remove it from a *live* root */ + zend_generator *root = generator->node.ptr.root, *parent = generator->node.parent, *next, *toproot = root; + if (parent) { + zend_bool parent_becomes_leaf = parent->node.children == 1; + if (parent_becomes_leaf) { + while (UNEXPECTED(root != generator)) { + next = zend_generator_get_child(&root->node, generator); + zend_generator_update_leaf_of_child(&root->node, generator, parent); + root = next; + } + parent->node.ptr.root = toproot; + parent->node.children = 0; + } else { + zend_generator_remove_leaf_child(&parent->node, generator, NULL); + while (UNEXPECTED(root != parent)) { + next = zend_generator_get_child(&root->node, generator); + zend_generator_remove_leaf_child(&root->node, generator, parent->node.ptr.leaf); + OBJ_RELEASE(&root->std); + root = next; + } + } + OBJ_RELEASE(&parent->std); + /* Reset for resuming in finally */ + generator->node.parent = NULL; + generator->node.ptr.root = generator; } } @@ -465,10 +544,13 @@ static void zend_generator_add_single_child(zend_generator_node *node, zend_gene node->child.ht = ht; } - zend_hash_index_add_ptr(node->child.ht, (zend_ulong) leaf, child); + if (zend_hash_index_add_ptr(node->child.ht, (zend_ulong) leaf, child) == NULL) { + ZEND_ASSERT(node->children > 1); + return; + } } - node->children++; + ++node->children; } static void zend_generator_merge_child_nodes(zend_generator_node *dest, zend_generator_node *src, zend_generator *child) @@ -507,7 +589,6 @@ static void zend_generator_add_child(zend_generator *generator, zend_generator * } else if (generator->node.children == 1) { multi_children_node = zend_generator_search_multi_children_node(&generator->node); if (multi_children_node) { - generator->node.children = 0; zend_generator_merge_child_nodes(&generator->node, multi_children_node, generator->node.child.single.child); } } @@ -518,6 +599,7 @@ static void zend_generator_add_child(zend_generator *generator, zend_generator * multi_children_node = (zend_generator_node *) 0x1; } + /* for allowing zend_generator_get_child() to work, we need every multi children node to have ALL its leaf descendents present, linking to their respective child */ { zend_generator *parent = generator->node.parent, *cur = generator; @@ -574,7 +656,7 @@ ZEND_API zend_generator *zend_generator_update_current(zend_generator *generator if (root->node.parent) { if (root->node.parent->execute_data == NULL) { - if (EXPECTED(EG(exception) == NULL)) { + if (EXPECTED(EG(exception) == NULL) && EXPECTED((OBJ_FLAGS(&generator->std) & IS_OBJ_DESTRUCTOR_CALLED) == 0)) { zend_op *yield_from = (zend_op *) root->execute_data->opline - 1; if (yield_from->opcode == ZEND_YIELD_FROM) { diff --git a/Zend/zend_hash.c b/Zend/zend_hash.c index abda03edf631e..c92b869569fcb 100644 --- a/Zend/zend_hash.c +++ b/Zend/zend_hash.c @@ -2658,13 +2658,9 @@ ZEND_API int zend_hash_compare(HashTable *ht1, HashTable *ht2, compare_func_t co zend_error_noreturn(E_ERROR, "Nesting level too deep - recursive dependency?"); } - if (!(GC_FLAGS(ht1) & GC_IMMUTABLE)) { - GC_PROTECT_RECURSION(ht1); - } + GC_TRY_PROTECT_RECURSION(ht1); result = zend_hash_compare_impl(ht1, ht2, compar, ordered); - if (!(GC_FLAGS(ht1) & GC_IMMUTABLE)) { - GC_UNPROTECT_RECURSION(ht1); - } + GC_TRY_UNPROTECT_RECURSION(ht1); return result; } diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index a4ee0feda8a83..ecf5c71ed8dd1 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -508,8 +508,8 @@ ZEND_API uint32_t *zend_get_property_guard(zend_object *zobj, zend_string *membe if (EXPECTED(Z_TYPE_P(zv) == IS_STRING)) { zend_string *str = Z_STR_P(zv); if (EXPECTED(str == member) || - /* hash values are always pred-calculated here */ - (EXPECTED(ZSTR_H(str) == ZSTR_H(member)) && + /* "str" always has a pre-calculated hash value here */ + (EXPECTED(ZSTR_H(str) == zend_string_hash_val(member)) && EXPECTED(zend_string_equal_content(str, member)))) { return &Z_PROPERTY_GUARD_P(zv); } else if (EXPECTED(Z_PROPERTY_GUARD_P(zv) == 0)) { @@ -1776,8 +1776,8 @@ ZEND_API HashTable *zend_std_get_properties_for(zend_object *obj, zend_prop_purp if (obj->handlers->get_debug_info) { int is_temp; ht = obj->handlers->get_debug_info(obj, &is_temp); - if (ht && !is_temp && !(GC_FLAGS(ht) & GC_IMMUTABLE)) { - GC_ADDREF(ht); + if (ht && !is_temp) { + GC_TRY_ADDREF(ht); } return ht; } @@ -1787,8 +1787,8 @@ ZEND_API HashTable *zend_std_get_properties_for(zend_object *obj, zend_prop_purp case ZEND_PROP_PURPOSE_VAR_EXPORT: case ZEND_PROP_PURPOSE_JSON: ht = obj->handlers->get_properties(obj); - if (ht && !(GC_FLAGS(ht) & GC_IMMUTABLE)) { - GC_ADDREF(ht); + if (ht) { + GC_TRY_ADDREF(ht); } return ht; default: diff --git a/Zend/zend_observer.c b/Zend/zend_observer.c index 033551c6e91bd..b124de5cc3699 100644 --- a/Zend/zend_observer.c +++ b/Zend/zend_observer.c @@ -24,6 +24,8 @@ #include "zend_vm.h" zend_llist zend_observers_fcall_list; +zend_llist zend_observer_error_callbacks; + int zend_observer_fcall_op_array_extension = -1; ZEND_TLS zend_arena *fcall_handlers_arena = NULL; @@ -58,6 +60,7 @@ ZEND_API void zend_observer_fcall_register(zend_observer_fcall_init init) { // Called by engine before MINITs ZEND_API void zend_observer_startup(void) { zend_llist_init(&zend_observers_fcall_list, sizeof(zend_observer_fcall_init), NULL, 1); + zend_llist_init(&zend_observer_error_callbacks, sizeof(zend_observer_error_cb), NULL, 1); } ZEND_API void zend_observer_activate(void) { @@ -74,6 +77,7 @@ ZEND_API void zend_observer_deactivate(void) { ZEND_API void zend_observer_shutdown(void) { zend_llist_destroy(&zend_observers_fcall_list); + zend_llist_destroy(&zend_observer_error_callbacks); } ZEND_API void zend_observer_fcall_install(zend_function *function) { @@ -157,4 +161,18 @@ ZEND_API void zend_observe_fcall_end( } } +ZEND_API void zend_observer_error_register(zend_observer_error_cb cb) +{ + zend_llist_add_element(&zend_observer_error_callbacks, &cb); +} + +void zend_observer_error_notify(int type, const char *error_filename, uint32_t error_lineno, zend_string *message) +{ + zend_llist_element *element; + zend_observer_error_cb callback; + for (element = zend_observer_error_callbacks.head; element; element = element->next) { + callback = *(zend_observer_error_cb *) (element->data); + callback(type, error_filename, error_lineno, message); + } +} diff --git a/Zend/zend_observer.h b/Zend/zend_observer.h index 9fb538ce3da0e..0603591c53957 100644 --- a/Zend/zend_observer.h +++ b/Zend/zend_observer.h @@ -110,6 +110,11 @@ ZEND_API zend_always_inline void zend_observer_maybe_fcall_call_end( } } +typedef void (*zend_observer_error_cb)(int type, const char *error_filename, uint32_t error_lineno, zend_string *message); + +ZEND_API void zend_observer_error_register(zend_observer_error_cb callback); +void zend_observer_error_notify(int type, const char *error_filename, uint32_t error_lineno, zend_string *message); + END_EXTERN_C() #endif /* ZEND_OBSERVER_H */ diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c index e126f784cfead..0923741723d48 100644 --- a/Zend/zend_operators.c +++ b/Zend/zend_operators.c @@ -1253,18 +1253,13 @@ ZEND_API zend_result ZEND_FASTCALL pow_function(zval *result, zval *op1, zval *o } /* }}} */ -#ifdef __clang__ -__attribute__((no_sanitize("float-divide-by-zero"))) -#endif static zend_result ZEND_FASTCALL div_function_base(zval *result, zval *op1, zval *op2) /* {{{ */ { zend_uchar type_pair = TYPE_PAIR(Z_TYPE_P(op1), Z_TYPE_P(op2)); if (EXPECTED(type_pair == TYPE_PAIR(IS_LONG, IS_LONG))) { if (Z_LVAL_P(op2) == 0) { - zend_error(E_WARNING, "Division by zero"); - ZVAL_DOUBLE(result, ((double) Z_LVAL_P(op1) / (double) Z_LVAL_P(op2))); - return SUCCESS; + goto division_by_0; } else if (Z_LVAL_P(op2) == -1 && Z_LVAL_P(op1) == ZEND_LONG_MIN) { /* Prevent overflow error/crash */ ZVAL_DOUBLE(result, (double) ZEND_LONG_MIN / -1); @@ -1278,25 +1273,31 @@ static zend_result ZEND_FASTCALL div_function_base(zval *result, zval *op1, zval return SUCCESS; } else if (EXPECTED(type_pair == TYPE_PAIR(IS_DOUBLE, IS_DOUBLE))) { if (Z_DVAL_P(op2) == 0) { - zend_error(E_WARNING, "Division by zero"); + goto division_by_0; } ZVAL_DOUBLE(result, Z_DVAL_P(op1) / Z_DVAL_P(op2)); return SUCCESS; } else if (EXPECTED(type_pair == TYPE_PAIR(IS_DOUBLE, IS_LONG))) { if (Z_LVAL_P(op2) == 0) { - zend_error(E_WARNING, "Division by zero"); + goto division_by_0; } ZVAL_DOUBLE(result, Z_DVAL_P(op1) / (double)Z_LVAL_P(op2)); return SUCCESS; } else if (EXPECTED(type_pair == TYPE_PAIR(IS_LONG, IS_DOUBLE))) { if (Z_DVAL_P(op2) == 0) { - zend_error(E_WARNING, "Division by zero"); + goto division_by_0; } ZVAL_DOUBLE(result, (double)Z_LVAL_P(op1) / Z_DVAL_P(op2)); return SUCCESS; } else { return FAILURE; } +division_by_0: + if (result != op1) { + ZVAL_UNDEF(result); + } + zend_throw_error(zend_ce_division_by_zero_error, "Division by zero"); + return SUCCESS; } /* }}} */ diff --git a/Zend/zend_types.h b/Zend/zend_types.h index 745be6e93830c..3b1ec85452ff3 100644 --- a/Zend/zend_types.h +++ b/Zend/zend_types.h @@ -612,6 +612,7 @@ static zend_always_inline zend_uchar zval_get_type(const zval* pz) { #define GC_DELREF(p) zend_gc_delref(&(p)->gc) #define GC_ADDREF_EX(p, rc) zend_gc_addref_ex(&(p)->gc, rc) #define GC_DELREF_EX(p, rc) zend_gc_delref_ex(&(p)->gc, rc) +#define GC_TRY_ADDREF(p) zend_gc_try_addref(&(p)->gc) #define GC_TYPE_MASK 0x0000000f #define GC_FLAGS_MASK 0x000003f0 @@ -1160,6 +1161,13 @@ static zend_always_inline uint32_t zend_gc_addref(zend_refcounted_h *p) { return ++(p->refcount); } +static zend_always_inline void zend_gc_try_addref(zend_refcounted_h *p) { + if (!(p->u.type_info & GC_IMMUTABLE)) { + ZEND_RC_MOD_CHECK(p); + ++p->refcount; + } +} + static zend_always_inline uint32_t zend_gc_delref(zend_refcounted_h *p) { ZEND_ASSERT(p->refcount > 0); ZEND_RC_MOD_CHECK(p); diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 4e9a2bd467fb3..59a49cb4131ab 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -7376,6 +7376,7 @@ ZEND_VM_HOT_NOCONST_HANDLER(198, ZEND_JMP_NULL, CONST|TMPVARCV, JMP_ADDR) zval *result = EX_VAR(opline->result.var); if (EXPECTED(opline->extended_value == ZEND_SHORT_CIRCUITING_CHAIN_EXPR)) { + ZVAL_NULL(result); if (UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { SAVE_OPLINE(); ZVAL_UNDEFINED_OP1(); @@ -7383,8 +7384,6 @@ ZEND_VM_HOT_NOCONST_HANDLER(198, ZEND_JMP_NULL, CONST|TMPVARCV, JMP_ADDR) HANDLE_EXCEPTION(); } } - - ZVAL_NULL(result); } else if (opline->extended_value == ZEND_SHORT_CIRCUITING_CHAIN_ISSET) { ZVAL_FALSE(result); } else { @@ -8034,7 +8033,12 @@ ZEND_VM_C_LABEL(yield_from_try_again): Z_ADDREF_P(val); FREE_OP1(); - if (Z_ISUNDEF(new_gen->retval)) { + if (UNEXPECTED(new_gen->execute_data == NULL)) { + zend_throw_error(NULL, "Generator passed to yield from was aborted without proper return and is unable to continue"); + zval_ptr_dtor(val); + UNDEF_RESULT(); + HANDLE_EXCEPTION(); + } else if (Z_ISUNDEF(new_gen->retval)) { if (UNEXPECTED(zend_generator_get_current(new_gen) == generator)) { zend_throw_error(NULL, "Impossible to yield from the Generator being currently run"); zval_ptr_dtor(val); @@ -8043,11 +8047,6 @@ ZEND_VM_C_LABEL(yield_from_try_again): } else { zend_generator_yield_from(generator, new_gen); } - } else if (UNEXPECTED(new_gen->execute_data == NULL)) { - zend_throw_error(NULL, "Generator passed to yield from was aborted without proper return and is unable to continue"); - zval_ptr_dtor(val); - UNDEF_RESULT(); - HANDLE_EXCEPTION(); } else { if (RETURN_VALUE_USED(opline)) { ZVAL_COPY(EX_VAR(opline->result.var), &new_gen->retval); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 27f18240508c2..0b1795f3eee30 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -5279,6 +5279,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMP_NULL_SPEC_CON zval *result = EX_VAR(opline->result.var); if (EXPECTED(opline->extended_value == ZEND_SHORT_CIRCUITING_CHAIN_EXPR)) { + ZVAL_NULL(result); if (UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { SAVE_OPLINE(); ZVAL_UNDEFINED_OP1(); @@ -5286,8 +5287,6 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMP_NULL_SPEC_CON HANDLE_EXCEPTION(); } } - - ZVAL_NULL(result); } else if (opline->extended_value == ZEND_SHORT_CIRCUITING_CHAIN_ISSET) { ZVAL_FALSE(result); } else { @@ -5377,7 +5376,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_FROM_SPEC_CONST_HANDLER( Z_ADDREF_P(val); - if (Z_ISUNDEF(new_gen->retval)) { + if (UNEXPECTED(new_gen->execute_data == NULL)) { + zend_throw_error(NULL, "Generator passed to yield from was aborted without proper return and is unable to continue"); + zval_ptr_dtor(val); + UNDEF_RESULT(); + HANDLE_EXCEPTION(); + } else if (Z_ISUNDEF(new_gen->retval)) { if (UNEXPECTED(zend_generator_get_current(new_gen) == generator)) { zend_throw_error(NULL, "Impossible to yield from the Generator being currently run"); zval_ptr_dtor(val); @@ -5386,11 +5390,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_FROM_SPEC_CONST_HANDLER( } else { zend_generator_yield_from(generator, new_gen); } - } else if (UNEXPECTED(new_gen->execute_data == NULL)) { - zend_throw_error(NULL, "Generator passed to yield from was aborted without proper return and is unable to continue"); - zval_ptr_dtor(val); - UNDEF_RESULT(); - HANDLE_EXCEPTION(); } else { if (RETURN_VALUE_USED(opline)) { ZVAL_COPY(EX_VAR(opline->result.var), &new_gen->retval); @@ -12047,6 +12046,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMP_NULL_SPEC_TMPV zval *result = EX_VAR(opline->result.var); if (EXPECTED(opline->extended_value == ZEND_SHORT_CIRCUITING_CHAIN_EXPR)) { + ZVAL_NULL(result); if (UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { SAVE_OPLINE(); ZVAL_UNDEFINED_OP1(); @@ -12054,8 +12054,6 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_JMP_NULL_SPEC_TMPV HANDLE_EXCEPTION(); } } - - ZVAL_NULL(result); } else if (opline->extended_value == ZEND_SHORT_CIRCUITING_CHAIN_ISSET) { ZVAL_FALSE(result); } else { @@ -14617,7 +14615,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_FROM_SPEC_TMPVAR_HANDLER Z_ADDREF_P(val); zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - if (Z_ISUNDEF(new_gen->retval)) { + if (UNEXPECTED(new_gen->execute_data == NULL)) { + zend_throw_error(NULL, "Generator passed to yield from was aborted without proper return and is unable to continue"); + zval_ptr_dtor(val); + UNDEF_RESULT(); + HANDLE_EXCEPTION(); + } else if (Z_ISUNDEF(new_gen->retval)) { if (UNEXPECTED(zend_generator_get_current(new_gen) == generator)) { zend_throw_error(NULL, "Impossible to yield from the Generator being currently run"); zval_ptr_dtor(val); @@ -14626,11 +14629,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_FROM_SPEC_TMPVAR_HANDLER } else { zend_generator_yield_from(generator, new_gen); } - } else if (UNEXPECTED(new_gen->execute_data == NULL)) { - zend_throw_error(NULL, "Generator passed to yield from was aborted without proper return and is unable to continue"); - zval_ptr_dtor(val); - UNDEF_RESULT(); - HANDLE_EXCEPTION(); } else { if (RETURN_VALUE_USED(opline)) { ZVAL_COPY(EX_VAR(opline->result.var), &new_gen->retval); @@ -39263,7 +39261,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_FROM_SPEC_CV_HANDLER(ZEN Z_ADDREF_P(val); - if (Z_ISUNDEF(new_gen->retval)) { + if (UNEXPECTED(new_gen->execute_data == NULL)) { + zend_throw_error(NULL, "Generator passed to yield from was aborted without proper return and is unable to continue"); + zval_ptr_dtor(val); + UNDEF_RESULT(); + HANDLE_EXCEPTION(); + } else if (Z_ISUNDEF(new_gen->retval)) { if (UNEXPECTED(zend_generator_get_current(new_gen) == generator)) { zend_throw_error(NULL, "Impossible to yield from the Generator being currently run"); zval_ptr_dtor(val); @@ -39272,11 +39275,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_FROM_SPEC_CV_HANDLER(ZEN } else { zend_generator_yield_from(generator, new_gen); } - } else if (UNEXPECTED(new_gen->execute_data == NULL)) { - zend_throw_error(NULL, "Generator passed to yield from was aborted without proper return and is unable to continue"); - zval_ptr_dtor(val); - UNDEF_RESULT(); - HANDLE_EXCEPTION(); } else { if (RETURN_VALUE_USED(opline)) { ZVAL_COPY(EX_VAR(opline->result.var), &new_gen->retval); diff --git a/ext/date/php_date.c b/ext/date/php_date.c index d6f66b700e891..88431a22ea205 100644 --- a/ext/date/php_date.c +++ b/ext/date/php_date.c @@ -24,6 +24,7 @@ #include "ext/standard/php_math.h" #include "php_date.h" #include "zend_interfaces.h" +#include "zend_exceptions.h" #include "lib/timelib.h" #include "lib/timelib_private.h" #ifndef PHP_WIN32 @@ -549,7 +550,7 @@ PHPAPI timelib_tzinfo *get_timezone_info(void) tz = guess_timezone(DATE_TIMEZONEDB); tzi = php_date_parse_tzfile(tz, DATE_TIMEZONEDB); if (! tzi) { - php_error_docref(NULL, E_ERROR, "Timezone database is corrupt - this should *never* happen!"); + zend_throw_error(NULL, "Timezone database is corrupt. Please file a bug report as this should never happen"); } return tzi; } @@ -960,7 +961,7 @@ PHP_FUNCTION(idate) ret = php_idate(ZSTR_VAL(format)[0], ts, 0); if (ret == -1) { - php_error_docref(NULL, E_WARNING, "Unrecognized date format token."); + php_error_docref(NULL, E_WARNING, "Unrecognized date format token"); RETURN_FALSE; } RETURN_LONG(ret); @@ -1008,7 +1009,7 @@ PHPAPI zend_long php_parse_date(const char *string, zend_long *now) PHP_FUNCTION(strtotime) { zend_string *times; - int error1, error2; + int parse_error, epoch_does_not_fit_in_zend_long; timelib_error_container *error; zend_long preset_ts, ts; zend_bool preset_ts_is_null = 1; @@ -1021,6 +1022,11 @@ PHP_FUNCTION(strtotime) Z_PARAM_LONG_OR_NULL(preset_ts, preset_ts_is_null) ZEND_PARSE_PARAMETERS_END(); + /* timelib_strtotime() expects the string to not be empty */ + if (ZSTR_LEN(times) == 0) { + RETURN_FALSE; + } + tzi = get_timezone_info(); now = timelib_time_ctor(); @@ -1031,20 +1037,27 @@ PHP_FUNCTION(strtotime) t = timelib_strtotime(ZSTR_VAL(times), ZSTR_LEN(times), &error, DATE_TIMEZONEDB, php_date_parse_tzfile_wrapper); - error1 = error->error_count; + parse_error = error->error_count; timelib_error_container_dtor(error); + if (parse_error) { + timelib_time_dtor(now); + timelib_time_dtor(t); + RETURN_FALSE; + } + timelib_fill_holes(t, now, TIMELIB_NO_CLONE); timelib_update_ts(t, tzi); - ts = timelib_date_to_int(t, &error2); + ts = timelib_date_to_int(t, &epoch_does_not_fit_in_zend_long); timelib_time_dtor(now); timelib_time_dtor(t); - if (error1 || error2) { + if (epoch_does_not_fit_in_zend_long) { + php_error_docref(NULL, E_WARNING, "Epoch doesn't fit in a PHP integer"); RETURN_FALSE; - } else { - RETURN_LONG(ts); } + + RETURN_LONG(ts); } /* }}} */ @@ -1056,7 +1069,7 @@ PHPAPI void php_mktime(INTERNAL_FUNCTION_PARAMETERS, int gmt) timelib_time *now; timelib_tzinfo *tzi = NULL; zend_long ts, adjust_seconds = 0; - int error; + int epoch_does_not_fit_in_zend_long; ZEND_PARSE_PARAMETERS_START(1, 6) Z_PARAM_LONG(hou) @@ -1114,15 +1127,18 @@ PHPAPI void php_mktime(INTERNAL_FUNCTION_PARAMETERS, int gmt) } /* Clean up and return */ - ts = timelib_date_to_int(now, &error); - ts += adjust_seconds; - timelib_time_dtor(now); + ts = timelib_date_to_int(now, &epoch_does_not_fit_in_zend_long); - if (error) { + if (epoch_does_not_fit_in_zend_long) { + timelib_time_dtor(now); + php_error_docref(NULL, E_WARNING, "Epoch doesn't fit in a PHP integer"); RETURN_FALSE; - } else { - RETURN_LONG(ts); } + + ts += adjust_seconds; + timelib_time_dtor(now); + + RETURN_LONG(ts); } /* }}} */ @@ -2780,7 +2796,7 @@ static int php_date_modify(zval *object, char *modify, size_t modify_len) /* {{{ dateobj = Z_PHPDATE_P(object); if (!(dateobj->time)) { - php_error_docref(NULL, E_WARNING, "The DateTime object has not been correctly initialized by its constructor"); + zend_throw_error(NULL, "The DateTime object has not been correctly initialized by its constructor"); return 0; } @@ -3308,7 +3324,7 @@ PHP_FUNCTION(date_timestamp_get) zval *object; php_date_obj *dateobj; zend_long timestamp; - int error; + int epoch_does_not_fit_in_zend_long; if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O", &object, date_ce_interface) == FAILURE) { RETURN_THROWS(); @@ -3317,12 +3333,14 @@ PHP_FUNCTION(date_timestamp_get) DATE_CHECK_INITIALIZED(dateobj->time, DateTime); timelib_update_ts(dateobj->time, NULL); - timestamp = timelib_date_to_int(dateobj->time, &error); - if (error) { - RETURN_FALSE; - } else { - RETVAL_LONG(timestamp); + timestamp = timelib_date_to_int(dateobj->time, &epoch_does_not_fit_in_zend_long); + + if (epoch_does_not_fit_in_zend_long) { + zend_value_error("Epoch doesn't fit in a PHP integer"); + RETURN_THROWS(); } + + RETURN_LONG(timestamp); } /* }}} */ @@ -3386,7 +3404,7 @@ PHP_FUNCTION(timezone_open) php_timezone_obj *tzobj; ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_STR(tz) + Z_PARAM_PATH_STR(tz) /* To prevent null bytes */ ZEND_PARSE_PARAMETERS_END(); tzobj = Z_PHPTIMEZONE_P(php_date_instantiate(date_ce_timezone, return_value)); @@ -3405,7 +3423,7 @@ PHP_METHOD(DateTimeZone, __construct) zend_error_handling error_handling; ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_STR(tz) + Z_PARAM_PATH_STR(tz) /* To prevent null bytes */ ZEND_PARSE_PARAMETERS_END(); zend_replace_error_handling(EH_THROW, NULL, &error_handling); @@ -4117,13 +4135,11 @@ PHP_METHOD(DatePeriod, __construct) timelib_time *clone; zend_error_handling error_handling; - zend_replace_error_handling(EH_THROW, NULL, &error_handling); if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "OOl|l", &start, date_ce_interface, &interval, date_ce_interval, &recurrences, &options) == FAILURE) { if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "OOO|l", &start, date_ce_interface, &interval, date_ce_interval, &end, date_ce_interface, &options) == FAILURE) { if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "s|l", &isostr, &isostr_len, &options) == FAILURE) { - php_error_docref(NULL, E_WARNING, "This constructor accepts either (DateTimeInterface, DateInterval, int) OR (DateTimeInterface, DateInterval, DateTime) OR (string) as arguments."); - zend_restore_error_handling(&error_handling); - return; + zend_type_error("DatePeriod::__construct() accepts (DateTimeInterface, DateInterval, int [, int]), or (DateTimeInterface, DateInterval, DateTime [, int]), or (string [, int]) as arguments"); + RETURN_THROWS(); } } } @@ -4132,15 +4148,30 @@ PHP_METHOD(DatePeriod, __construct) dpobj->current = NULL; if (isostr) { + zend_replace_error_handling(EH_THROW, NULL, &error_handling); date_period_initialize(&(dpobj->start), &(dpobj->end), &(dpobj->interval), &recurrences, isostr, isostr_len); + zend_restore_error_handling(&error_handling); + if (EG(exception)) { + RETURN_THROWS(); + } + if (dpobj->start == NULL) { - php_error_docref(NULL, E_WARNING, "The ISO interval '%s' did not contain a start date.", isostr); + zend_string *func = get_active_function_or_method_name(); + zend_throw_error(zend_ce_exception, "%s(): ISO interval must contain a start date, \"%s\" given", ZSTR_VAL(func), isostr); + zend_string_release(func); + RETURN_THROWS(); } if (dpobj->interval == NULL) { - php_error_docref(NULL, E_WARNING, "The ISO interval '%s' did not contain an interval.", isostr); + zend_string *func = get_active_function_or_method_name(); + zend_throw_error(zend_ce_exception, "%s(): ISO interval must contain an interval, \"%s\" given", ZSTR_VAL(func), isostr); + zend_string_release(func); + RETURN_THROWS(); } if (dpobj->end == NULL && recurrences == 0) { - php_error_docref(NULL, E_WARNING, "The ISO interval '%s' did not contain an end date or a recurrence count.", isostr); + zend_string *func = get_active_function_or_method_name(); + zend_throw_error(zend_ce_exception, "%s(): ISO interval must contain an end date or a recurrence count, \"%s\" given", ZSTR_VAL(func), isostr); + zend_string_release(func); + RETURN_THROWS(); } if (dpobj->start) { @@ -4179,7 +4210,10 @@ PHP_METHOD(DatePeriod, __construct) } if (dpobj->end == NULL && recurrences < 1) { - php_error_docref(NULL, E_WARNING, "The recurrence count '%d' is invalid. Needs to be > 0", (int) recurrences); + zend_string *func = get_active_function_or_method_name(); + zend_throw_error(zend_ce_exception, "%s(): Recurrence count must be greater than 0", ZSTR_VAL(func)); + zend_string_release(func); + RETURN_THROWS(); } /* options */ @@ -4189,8 +4223,6 @@ PHP_METHOD(DatePeriod, __construct) dpobj->recurrences = recurrences + dpobj->include_start_date; dpobj->initialized = 1; - - zend_restore_error_handling(&error_handling); } /* }}} */ @@ -4321,8 +4353,9 @@ PHP_FUNCTION(timezone_identifiers_list) /* Extra validation */ if (what == PHP_DATE_TIMEZONE_PER_COUNTRY && option_len != 2) { - php_error_docref(NULL, E_NOTICE, "A two-letter ISO 3166-1 compatible country code is expected"); - RETURN_FALSE; + zend_argument_value_error(2, "must be a two-letter ISO 3166-1 compatible country code " + "when argument #1 ($timezoneGroup) is DateTimeZone::PER_COUNTRY"); + RETURN_THROWS(); } tzdb = DATE_TIMEZONEDB; diff --git a/ext/date/php_date.stub.php b/ext/date/php_date.stub.php index bb97cf5b86ca8..8a1e86a3a0547 100644 --- a/ext/date/php_date.stub.php +++ b/ext/date/php_date.stub.php @@ -73,7 +73,7 @@ function date_isodate_set(DateTime $object, int $year, int $week, int $day = 1): function date_timestamp_set(DateTime $object, int $timestamp): DateTime {} -function date_timestamp_get(DateTimeInterface $object): int|false {} +function date_timestamp_get(DateTimeInterface $object): int {} function timezone_open(string $timezone): DateTimeZone|false {} @@ -88,7 +88,7 @@ function timezone_transitions_get( function timezone_location_get(DateTimeZone $object): array|false {} -function timezone_identifiers_list(int $timezoneGroup = DateTimeZone::ALL, ?string $countryCode = null): array|false {} +function timezone_identifiers_list(int $timezoneGroup = DateTimeZone::ALL, ?string $countryCode = null): array {} function timezone_abbreviations_list(): array {} @@ -230,7 +230,7 @@ public function setISODate(int $year, int $week, int $dayOfWeek = 1) {} public function setTimestamp(int $timestamp) {} /** - * @return int|false + * @return int * @alias date_timestamp_get */ public function getTimestamp() {} @@ -282,7 +282,7 @@ public function getTimezone() {} public function getOffset() {} /** - * @return int|false + * @return int * @alias date_timestamp_get */ public function getTimestamp() {} diff --git a/ext/date/php_date_arginfo.h b/ext/date/php_date_arginfo.h index bc12d852bb905..19ee60f5c1c99 100644 --- a/ext/date/php_date_arginfo.h +++ b/ext/date/php_date_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: fee95924adec03c89fdd677ec26bb6eea34d4b3c */ + * Stub hash: cb1532309655d85eb2644cdcfbf23063dfa1ddaf */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_strtotime, 0, 1, MAY_BE_LONG|MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(0, datetime, IS_STRING, 0) @@ -151,9 +151,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_date_timestamp_set, 0, 2, DateTim ZEND_ARG_TYPE_INFO(0, timestamp, IS_LONG, 0) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_date_timestamp_get, 0, 1, MAY_BE_LONG|MAY_BE_FALSE) - ZEND_ARG_OBJ_INFO(0, object, DateTimeInterface, 0) -ZEND_END_ARG_INFO() +#define arginfo_date_timestamp_get arginfo_date_offset_get ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_timezone_open, 0, 1, DateTimeZone, MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(0, timezone, IS_STRING, 0) @@ -184,7 +182,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_timezone_location_get, 0, 1, MAY ZEND_ARG_OBJ_INFO(0, object, DateTimeZone, 0) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_timezone_identifiers_list, 0, 0, MAY_BE_ARRAY|MAY_BE_FALSE) +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_timezone_identifiers_list, 0, 0, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, timezoneGroup, IS_LONG, 0, "DateTimeZone::ALL") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, countryCode, IS_STRING, 1, "null") ZEND_END_ARG_INFO() diff --git a/ext/date/tests/005.phpt b/ext/date/tests/005.phpt index 23fff3b731ad2..4bd743ea006db 100644 --- a/ext/date/tests/005.phpt +++ b/ext/date/tests/005.phpt @@ -9,7 +9,6 @@ $t = mktime(0,0,0, 6, 27, 2006); var_dump(idate(1,1)); var_dump(idate("")); var_dump(idate(0)); - var_dump(idate("B", $t)); var_dump(idate("[", $t)); var_dump(idate("'")); @@ -17,19 +16,19 @@ var_dump(idate("'")); echo "Done\n"; ?> --EXPECTF-- -Warning: idate(): Unrecognized date format token. in %s on line %d +Warning: idate(): Unrecognized date format token in %s on line %d bool(false) Warning: idate(): idate format is one char in %s on line %d bool(false) -Warning: idate(): Unrecognized date format token. in %s on line %d +Warning: idate(): Unrecognized date format token in %s on line %d bool(false) int(41) -Warning: idate(): Unrecognized date format token. in %s on line %d +Warning: idate(): Unrecognized date format token in %s on line %d bool(false) -Warning: idate(): Unrecognized date format token. in %s on line %d +Warning: idate(): Unrecognized date format token in %s on line %d bool(false) Done diff --git a/ext/date/tests/DatePeriod_wrong_constructor.phpt b/ext/date/tests/DatePeriod_wrong_constructor.phpt index 8acdc5d38602f..45f99bdb72709 100644 --- a/ext/date/tests/DatePeriod_wrong_constructor.phpt +++ b/ext/date/tests/DatePeriod_wrong_constructor.phpt @@ -7,11 +7,12 @@ Havard Eide date.timezone=UTC --FILE-- getMessage() . "\n"; +} ?> ---EXPECTF-- -Fatal error: Uncaught Exception: DatePeriod::__construct(): This constructor accepts either (DateTimeInterface, DateInterval, int) OR (DateTimeInterface, DateInterval, DateTime) OR (string) as arguments. in %s:%d -Stack trace: -#0 %s(%d): DatePeriod->__construct() -#1 {main} - thrown in %s on line %d +--EXPECT-- +DatePeriod::__construct() accepts (DateTimeInterface, DateInterval, int [, int]), or (DateTimeInterface, DateInterval, DateTime [, int]), or (string [, int]) as arguments diff --git a/ext/date/tests/DatePeriod_wrong_recurrence_on_constructor.phpt b/ext/date/tests/DatePeriod_wrong_recurrence_on_constructor.phpt index f96753b019aed..f2e121db389a3 100644 --- a/ext/date/tests/DatePeriod_wrong_recurrence_on_constructor.phpt +++ b/ext/date/tests/DatePeriod_wrong_recurrence_on_constructor.phpt @@ -9,11 +9,12 @@ try { } try { - new DatePeriod(new DateTime('yesterday'), new DateInterval('P1D'),-1); + new DatePeriod(new DateTime('yesterday'), new DateInterval('P1D'), -1); } catch (Exception $exception) { echo $exception->getMessage(), "\n"; } + ?> --EXPECT-- -DatePeriod::__construct(): The recurrence count '0' is invalid. Needs to be > 0 -DatePeriod::__construct(): The recurrence count '-1' is invalid. Needs to be > 0 +DatePeriod::__construct(): Recurrence count must be greater than 0 +DatePeriod::__construct(): Recurrence count must be greater than 0 diff --git a/ext/date/tests/bug41523.phpt b/ext/date/tests/bug41523.phpt index 6df2006d57e66..2f0e3b1084818 100644 --- a/ext/date/tests/bug41523.phpt +++ b/ext/date/tests/bug41523.phpt @@ -12,7 +12,7 @@ var_dump( $dt = new DateTime('0000-00-00 00:00:00') ); echo $dt->format( DateTime::ISO8601 ), "\n"; ?> ---EXPECT-- +--EXPECTF-- array(12) { ["year"]=> int(0) @@ -43,6 +43,8 @@ array(12) { ["is_localtime"]=> bool(false) } + +Warning: strtotime(): Epoch doesn't fit in a PHP integer in %s on line %d bool(false) object(DateTime)#1 (3) { ["date"]=> diff --git a/ext/date/tests/bug44562.phpt b/ext/date/tests/bug44562.phpt index b4b721168f3eb..5e2a1e55014e2 100644 --- a/ext/date/tests/bug44562.phpt +++ b/ext/date/tests/bug44562.phpt @@ -4,12 +4,9 @@ Bug #44562 (Creating instance of DatePeriod crashes) getMessage(), "\n"; } diff --git a/ext/date/tests/bug52062.phpt b/ext/date/tests/bug52062.phpt index 1196168e19f21..f967773b1cc3c 100644 --- a/ext/date/tests/bug52062.phpt +++ b/ext/date/tests/bug52062.phpt @@ -10,7 +10,11 @@ date.timezone=UTC format('Y-m-d H:i:s U')); -var_dump($d->getTimestamp()); +try { + var_dump($d->getTimestamp()); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} var_dump($d->format('U')); try { @@ -19,16 +23,20 @@ try { echo $e->getMessage(), "\n"; } var_dump($d->format('Y-m-d H:i:s U')); -var_dump($d->getTimestamp()); +try { + var_dump($d->getTimestamp()); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} $i = new DateInterval('PT100000000000S'); var_dump($i->format('%s')); ?> --EXPECT-- string(32) "5138-11-16 09:46:40 100000000000" -bool(false) +Epoch doesn't fit in a PHP integer string(12) "100000000000" DateTime::setTimestamp(): Argument #1 ($timestamp) must be of type int, float given string(32) "5138-11-16 09:46:40 100000000000" -bool(false) +Epoch doesn't fit in a PHP integer string(10) "1215752192" diff --git a/ext/date/tests/bug70277.phpt b/ext/date/tests/bug70277.phpt index 648bd19c7771c..49df2be410379 100644 --- a/ext/date/tests/bug70277.phpt +++ b/ext/date/tests/bug70277.phpt @@ -3,15 +3,17 @@ Bug #70277 (new DateTimeZone($foo) is ignoring text after null byte) --FILE-- getMessage() . \PHP_EOL; +} +try { + var_dump(new DateTimeZone($timezone)); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} ?> ---EXPECTF-- -Warning: timezone_open(): Timezone must not contain null bytes in %sbug70277.php on line %d -bool(false) - -Fatal error: Uncaught Exception: DateTimeZone::__construct(): Timezone must not contain null bytes in %sbug70277.php:%d -Stack trace: -#0 %sbug70277.php(%d): DateTimeZone->__construct('Europe/Zurich\x00F...') -#1 {main} - thrown in %sbug70277.php on line %d +--EXPECT-- +timezone_open(): Argument #1 ($timezone) must not contain any null bytes +DateTimeZone::__construct(): Argument #1 ($timezone) must not contain any null bytes diff --git a/ext/date/tests/date_interval_bad_format_leak.phpt b/ext/date/tests/date_interval_bad_format_leak.phpt index da6982c9bedb2..55cb5b341f16e 100644 --- a/ext/date/tests/date_interval_bad_format_leak.phpt +++ b/ext/date/tests/date_interval_bad_format_leak.phpt @@ -4,13 +4,13 @@ DateInterval with bad format should not leak period getMessage(), "\n"; } try { - $perid = new DatePeriod('P3"D'); + new DatePeriod('P3"D'); } catch (Exception $e) { echo $e->getMessage(), "\n"; } diff --git a/ext/date/tests/date_period_bad_iso_format.phpt b/ext/date/tests/date_period_bad_iso_format.phpt new file mode 100644 index 0000000000000..fecc4fa23ceab --- /dev/null +++ b/ext/date/tests/date_period_bad_iso_format.phpt @@ -0,0 +1,29 @@ +--TEST-- +Test bad ISO date formats passed to DatePeriod constructor +--FILE-- +getMessage(), "\n"; +} + +try { + new DatePeriod("R4/2012-07-01T00:00:00Z"); +} catch (Exception $e) { + echo $e->getMessage(), "\n"; +} + + +try { + new DatePeriod("2012-07-01T00:00:00Z/P7D"); +} catch (Exception $e) { + echo $e->getMessage(), "\n"; +} + +?> +--EXPECT-- +DatePeriod::__construct(): ISO interval must contain a start date, "R4" given +DatePeriod::__construct(): ISO interval must contain an interval, "R4/2012-07-01T00:00:00Z" given +DatePeriod::__construct(): ISO interval must contain an end date or a recurrence count, "2012-07-01T00:00:00Z/P7D" given diff --git a/ext/date/tests/gmdate_variation12.phpt b/ext/date/tests/gmdate_variation12.phpt index 1f74dc14c159e..dab866967aea1 100644 --- a/ext/date/tests/gmdate_variation12.phpt +++ b/ext/date/tests/gmdate_variation12.phpt @@ -1,5 +1,9 @@ --TEST-- -Test gmdate() function : usage variation - Valid and invalid range of timestamp. +Test gmdate() function : usage variation - Valid and invalid range of timestamp 32 bits. +--SKIPIF-- + --FILE-- ---EXPECTREGEX-- -\*\*\* Testing gmdate\(\) : usage variation \*\*\* +--EXPECTF-- +*** Testing gmdate() : usage variation *** + +-- Testing gmdate() function with minimum range of timestamp -- +string(24) "1901-12-13T20:45:54+0000" + +-- Testing gmdate() function with less than the range of timestamp -- --- Testing gmdate\(\) function with minimum range of timestamp -- -string\(24\) "1901-12-13T20:45:54\+0000" +Warning: mktime(): Epoch doesn't fit in a PHP integer in %s on line %d +string(24) "1970-01-01T00:00:00+0000" --- Testing gmdate\(\) function with less than the range of timestamp -- -string\(24\) "(1970-01-01T00:00:00\+0000|1901-12-13T20:45:50\+0000)" +-- Testing gmdate() function with maximum range of timestamp -- +string(24) "2038-01-19T03:14:07+0000" --- Testing gmdate\(\) function with maximum range of timestamp -- -string\(24\) "2038-01-19T03:14:07\+0000" +-- Testing gmdate() function with greater than the range of timestamp -- --- Testing gmdate\(\) function with greater than the range of timestamp -- -string\(24\) "(1970-01-01T00:00:00\+0000|2038-01-19T03:14:10\+0000)" +Warning: mktime(): Epoch doesn't fit in a PHP integer in %s on line %d +string(24) "1970-01-01T00:00:00+0000" diff --git a/ext/date/tests/gmdate_variation12_64bits.phpt b/ext/date/tests/gmdate_variation12_64bits.phpt new file mode 100644 index 0000000000000..5f3c87da09676 --- /dev/null +++ b/ext/date/tests/gmdate_variation12_64bits.phpt @@ -0,0 +1,44 @@ +--TEST-- +Test gmdate() function : usage variation - Valid and invalid range of timestamp 64 bits. +--SKIPIF-- + +--FILE-- + +--EXPECT-- +*** Testing gmdate() : usage variation *** + +-- Testing gmdate() function with minimum range of timestamp -- +string(24) "1901-12-13T20:45:54+0000" + +-- Testing gmdate() function with less than the range of timestamp -- +string(24) "1901-12-13T20:45:50+0000" + +-- Testing gmdate() function with maximum range of timestamp -- +string(24) "2038-01-19T03:14:07+0000" + +-- Testing gmdate() function with greater than the range of timestamp -- +string(24) "2038-01-19T03:14:10+0000" diff --git a/ext/date/tests/gmmktime_variation9.phpt b/ext/date/tests/gmmktime_variation9.phpt index c972e8c9c79a7..dea8e93fab674 100644 --- a/ext/date/tests/gmmktime_variation9.phpt +++ b/ext/date/tests/gmmktime_variation9.phpt @@ -1,5 +1,9 @@ --TEST-- -Test gmmktime() function : usage variation - Passing positive and negative float values to arguments. +Test gmmktime() function : usage variation - Passing positive and negative float values to arguments 32 bits. +--SKIPIF-- + --FILE-- $value) { var_dump( gmmktime($hour, $min, $sec, $mon, $value, $value) ); } ?> ---EXPECTREGEX-- -\*\*\* Testing gmmktime\(\) : usage variation \*\*\* +--EXPECTF-- +*** Testing gmmktime() : usage variation *** --float 123456-- -int\(1662595688\) -int\(1225589768\) -int\(1218306336\) -(bool|int)\((false|325855037288)\) -(bool|int)\((false|3844412784488)\) +int(1662595688) +int(1225589768) +int(1218306336) + +Warning: gmmktime(): Epoch doesn't fit in a PHP integer in %s on line %d +bool(false) + +Warning: gmmktime(): Epoch doesn't fit in a PHP integer in %s on line %d +bool(false) --float -123456-- -int\(773712488\) -int\(1210775048\) -int\(1218059424\) -(bool|int)\((false|-323460834712)\) -(bool|int)\((false|-3968710530712)\) +int(773712488) +int(1210775048) +int(1218059424) + +Warning: gmmktime(): Epoch doesn't fit in a PHP integer in %s on line %d +bool(false) + +Warning: gmmktime(): Epoch doesn't fit in a PHP integer in %s on line %d +bool(false) --float -10.5-- -int\(1218118088\) -int\(1218181808\) -int\(1218182870\) -int\(1170922088\) -(bool|int)\((false|-62465356312)\) +int(1218118088) +int(1218181808) +int(1218182870) +int(1170922088) + +Warning: gmmktime(): Epoch doesn't fit in a PHP integer in %s on line %d +bool(false) diff --git a/ext/date/tests/gmmktime_variation9_64bits.phpt b/ext/date/tests/gmmktime_variation9_64bits.phpt new file mode 100644 index 0000000000000..9c7e8dcc76c0b --- /dev/null +++ b/ext/date/tests/gmmktime_variation9_64bits.phpt @@ -0,0 +1,58 @@ +--TEST-- +Test gmmktime() function : usage variation - Passing positive and negative float values to arguments 64 bits. +--SKIPIF-- + +--FILE-- + 123456, + 'float -123456' => -123456, + 'float -10.5' => -10.5, +); + +// loop through each element of the array for min +foreach($inputs as $key =>$value) { + echo "\n--$key--\n"; + var_dump( gmmktime($value, $min, $sec, $mon, $day, $year) ); + var_dump( gmmktime($hour, $value, $sec, $mon, $day, $year) ); + var_dump( gmmktime($hour, $min, $value, $mon, $day, $year) ); + var_dump( gmmktime($hour, $min, $sec, $value, $day, $year) ); + var_dump( gmmktime($hour, $min, $sec, $mon, $value, $value) ); +} +?> +--EXPECT-- + *** Testing gmmktime() : usage variation *** + +--float 123456-- +int(1662595688) +int(1225589768) +int(1218306336) +int(325855037288) +int(3844412784488) + +--float -123456-- +int(773712488) +int(1210775048) +int(1218059424) +int(-323460834712) +int(-3968710530712) + +--float -10.5-- +int(1218118088) +int(1218181808) +int(1218182870) +int(1170922088) +int(-62465356312) diff --git a/ext/date/tests/mktime-3.phpt b/ext/date/tests/mktime-3.phpt index b054efd076ef9..2aacdee5aab2e 100644 --- a/ext/date/tests/mktime-3.phpt +++ b/ext/date/tests/mktime-3.phpt @@ -14,7 +14,7 @@ foreach ($tzs as $tz) { date_default_timezone_set($tz); foreach ($years as $year) { printf("Y: %4d - ", $year); - $ret = mktime(1, 1, 1, 1, 1, $year); + $ret = @mktime(1, 1, 1, 1, 1, $year); if ($ret == FALSE) { echo "out of range\n"; } else { diff --git a/ext/date/tests/strtotime-mysql.phpt b/ext/date/tests/strtotime-mysql.phpt index c9502e1d3e179..c51f63f1323ba 100644 --- a/ext/date/tests/strtotime-mysql.phpt +++ b/ext/date/tests/strtotime-mysql.phpt @@ -21,7 +21,9 @@ foreach($d as $date) { } } ?> ---EXPECT-- +--EXPECTF-- string(31) "Fri, 23 May 1997 09:15:28 +0000" string(31) "Sun, 31 Dec 2000 18:58:59 +0000" + +Warning: strtotime(): Epoch doesn't fit in a PHP integer in %s on line %d bool(false) diff --git a/ext/date/tests/strtotime3.phpt b/ext/date/tests/strtotime3.phpt index f01af27a4378e..763b77a07da97 100644 --- a/ext/date/tests/strtotime3.phpt +++ b/ext/date/tests/strtotime3.phpt @@ -44,7 +44,7 @@ foreach ($strs as $str) { } ?> ---EXPECT-- +--EXPECTF-- bool(false) bool(false) string(31) "Thu, 15 Jun 2006 00:00:00 +0100" @@ -53,6 +53,8 @@ bool(false) string(31) "Fri, 16 Jun 2006 23:49:12 +0100" bool(false) string(31) "Fri, 16 Jun 2006 02:22:00 +0100" + +Warning: strtotime(): Epoch doesn't fit in a PHP integer in %s on line %d bool(false) string(31) "Fri, 16 Jun 2006 02:22:33 +0100" bool(false) diff --git a/ext/date/tests/timezone_identifiers_list_wrong_constructor.phpt b/ext/date/tests/timezone_identifiers_list_wrong_constructor.phpt index 39c71ab1dbd27..4823027b551c0 100644 --- a/ext/date/tests/timezone_identifiers_list_wrong_constructor.phpt +++ b/ext/date/tests/timezone_identifiers_list_wrong_constructor.phpt @@ -1,15 +1,24 @@ --TEST-- -timezone_identifiers_list: Test that correct notice is given when timezone_identifiers_list is given 4096 as parameter +timezone_identifiers_list: ValueError when timezoneGroup is DateTimeZone::PER_COUNTRY --CREDITS-- Havard Eide #PHPTestFest2009 Norway 2009-06-09 \o/ --INI-- -error_reporting=E_ALL date.timezone=UTC --FILE-- getMessage() . \PHP_EOL; +} +try { + var_dump(timezone_identifiers_list(DateTimeZone::PER_COUNTRY, 'A')); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} ?> --EXPECTF-- -Notice: timezone_identifiers_list(): A two-letter ISO 3166-1 compatible country code is expected in %s on line %d +timezone_identifiers_list(): Argument #2 ($countryCode) must be a two-letter ISO 3166-1 compatible country code when argument #1 ($timezoneGroup) is DateTimeZone::PER_COUNTRY +timezone_identifiers_list(): Argument #2 ($countryCode) must be a two-letter ISO 3166-1 compatible country code when argument #1 ($timezoneGroup) is DateTimeZone::PER_COUNTRY diff --git a/ext/filter/filter.c b/ext/filter/filter.c index 37fac29de93d8..4aa936821322d 100644 --- a/ext/filter/filter.c +++ b/ext/filter/filter.c @@ -524,31 +524,31 @@ PHP_FUNCTION(filter_has_var) } /* }}} */ -static void php_filter_call(zval *filtered, zend_long filter, zval *filter_args, const int copy, zend_long filter_flags) /* {{{ */ -{ +static void php_filter_call( + zval *filtered, zend_long filter, HashTable *filter_args_ht, zend_long filter_args_long, + const int copy, zend_long filter_flags +) /* {{{ */ { zval *options = NULL; zval *option; char *charset = NULL; - if (filter_args && Z_TYPE_P(filter_args) != IS_ARRAY) { - zend_long lval = zval_get_long(filter_args); - + if (!filter_args_ht) { if (filter != -1) { /* handler for array apply */ /* filter_args is the filter_flags */ - filter_flags = lval; + filter_flags = filter_args_long; if (!(filter_flags & FILTER_REQUIRE_ARRAY || filter_flags & FILTER_FORCE_ARRAY)) { filter_flags |= FILTER_REQUIRE_SCALAR; } } else { - filter = lval; + filter = filter_args_long; } - } else if (filter_args) { - if ((option = zend_hash_str_find(Z_ARRVAL_P(filter_args), "filter", sizeof("filter") - 1)) != NULL) { + } else { + if ((option = zend_hash_str_find(filter_args_ht, "filter", sizeof("filter") - 1)) != NULL) { filter = zval_get_long(option); } - if ((option = zend_hash_str_find(Z_ARRVAL_P(filter_args), "flags", sizeof("flags") - 1)) != NULL) { + if ((option = zend_hash_str_find(filter_args_ht, "flags", sizeof("flags") - 1)) != NULL) { filter_flags = zval_get_long(option); if (!(filter_flags & FILTER_REQUIRE_ARRAY || filter_flags & FILTER_FORCE_ARRAY)) { @@ -556,7 +556,7 @@ static void php_filter_call(zval *filtered, zend_long filter, zval *filter_args, } } - if ((option = zend_hash_str_find_deref(Z_ARRVAL_P(filter_args), "options", sizeof("options") - 1)) != NULL) { + if ((option = zend_hash_str_find_deref(filter_args_ht, "options", sizeof("options") - 1)) != NULL) { if (filter != FILTER_CALLBACK) { if (Z_TYPE_P(option) == IS_ARRAY) { options = option; @@ -601,21 +601,19 @@ static void php_filter_call(zval *filtered, zend_long filter, zval *filter_args, } /* }}} */ -static void php_filter_array_handler(zval *input, zval *op, zval *return_value, zend_bool add_empty) /* {{{ */ -{ +static void php_filter_array_handler(zval *input, HashTable *op_ht, zend_long op_long, + zval *return_value, zend_bool add_empty +) /* {{{ */ { zend_string *arg_key; zval *tmp, *arg_elm; - if (!op) { + if (!op_ht) { ZVAL_DUP(return_value, input); - php_filter_call(return_value, FILTER_DEFAULT, NULL, 0, FILTER_REQUIRE_ARRAY); - } else if (Z_TYPE_P(op) == IS_LONG) { - ZVAL_DUP(return_value, input); - php_filter_call(return_value, Z_LVAL_P(op), NULL, 0, FILTER_REQUIRE_ARRAY); - } else if (Z_TYPE_P(op) == IS_ARRAY) { + php_filter_call(return_value, -1, NULL, op_long, 0, FILTER_REQUIRE_ARRAY); + } else { array_init(return_value); - ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(op), arg_key, arg_elm) { + ZEND_HASH_FOREACH_STR_KEY_VAL(op_ht, arg_key, arg_elm) { if (arg_key == NULL) { zend_argument_type_error(2, "must contain only string keys"); RETURN_THROWS(); @@ -632,12 +630,14 @@ static void php_filter_array_handler(zval *input, zval *op, zval *return_value, zval nval; ZVAL_DEREF(tmp); ZVAL_DUP(&nval, tmp); - php_filter_call(&nval, -1, arg_elm, 0, FILTER_REQUIRE_SCALAR); + php_filter_call(&nval, -1, + Z_TYPE_P(arg_elm) == IS_ARRAY ? Z_ARRVAL_P(arg_elm) : NULL, + Z_TYPE_P(arg_elm) == IS_ARRAY ? 0 : zval_get_long(arg_elm), + 0, FILTER_REQUIRE_SCALAR + ); zend_hash_update(Z_ARRVAL_P(return_value), arg_key, &nval); } } ZEND_HASH_FOREACH_END(); - } else { - RETURN_FALSE; } } /* }}} */ @@ -646,15 +646,21 @@ static void php_filter_array_handler(zval *input, zval *op, zval *return_value, PHP_FUNCTION(filter_input) { zend_long fetch_from, filter = FILTER_DEFAULT; - zval *filter_args = NULL, *tmp; - zval *input = NULL; + zval *input = NULL, *tmp; zend_string *var; + HashTable *filter_args_ht = NULL; + zend_long filter_args_long = 0; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "lS|lz", &fetch_from, &var, &filter, &filter_args) == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_START(2, 4) + Z_PARAM_LONG(fetch_from) + Z_PARAM_STR(var) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(filter) + Z_PARAM_ARRAY_HT_OR_LONG(filter_args_ht, filter_args_long) + ZEND_PARSE_PARAMETERS_END(); if (!PHP_FILTER_ID_EXISTS(filter)) { + php_error_docref(NULL, E_WARNING, "Unknown filter with ID " ZEND_LONG_FMT, filter); RETURN_FALSE; } @@ -666,16 +672,17 @@ PHP_FUNCTION(filter_input) if (!input || (tmp = zend_hash_find(Z_ARRVAL_P(input), var)) == NULL) { zend_long filter_flags = 0; zval *option, *opt, *def; - if (filter_args) { - if (Z_TYPE_P(filter_args) == IS_LONG) { - filter_flags = Z_LVAL_P(filter_args); - } else if (Z_TYPE_P(filter_args) == IS_ARRAY && (option = zend_hash_str_find(Z_ARRVAL_P(filter_args), "flags", sizeof("flags") - 1)) != NULL) { + if (!filter_args_ht) { + filter_flags = filter_args_long; + } else { + if ((option = zend_hash_str_find(filter_args_ht, "flags", sizeof("flags") - 1)) != NULL) { filter_flags = zval_get_long(option); } - if (Z_TYPE_P(filter_args) == IS_ARRAY && - (opt = zend_hash_str_find_deref(Z_ARRVAL_P(filter_args), "options", sizeof("options") - 1)) != NULL && + + if ((opt = zend_hash_str_find_deref(filter_args_ht, "options", sizeof("options") - 1)) != NULL && Z_TYPE_P(opt) == IS_ARRAY && - (def = zend_hash_str_find_deref(Z_ARRVAL_P(opt), "default", sizeof("default") - 1)) != NULL) { + (def = zend_hash_str_find_deref(Z_ARRVAL_P(opt), "default", sizeof("default") - 1)) != NULL + ) { ZVAL_COPY(return_value, def); return; } @@ -695,7 +702,7 @@ PHP_FUNCTION(filter_input) ZVAL_DUP(return_value, tmp); - php_filter_call(return_value, filter, filter_args, 1, FILTER_REQUIRE_SCALAR); + php_filter_call(return_value, filter, filter_args_ht, filter_args_long, 1, FILTER_REQUIRE_SCALAR); } /* }}} */ @@ -703,19 +710,25 @@ PHP_FUNCTION(filter_input) PHP_FUNCTION(filter_var) { zend_long filter = FILTER_DEFAULT; - zval *filter_args = NULL, *data; + zval *data; + HashTable *filter_args_ht = NULL; + zend_long filter_args_long = 0; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "z|lz", &data, &filter, &filter_args) == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_START(1, 3) + Z_PARAM_ZVAL(data) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(filter) + Z_PARAM_ARRAY_HT_OR_LONG(filter_args_ht, filter_args_long) + ZEND_PARSE_PARAMETERS_END(); if (!PHP_FILTER_ID_EXISTS(filter)) { + php_error_docref(NULL, E_WARNING, "Unknown filter with ID " ZEND_LONG_FMT, filter); RETURN_FALSE; } ZVAL_DUP(return_value, data); - php_filter_call(return_value, filter, filter_args, 1, FILTER_REQUIRE_SCALAR); + php_filter_call(return_value, filter, filter_args_ht, filter_args_long, 1, FILTER_REQUIRE_SCALAR); } /* }}} */ @@ -723,14 +736,20 @@ PHP_FUNCTION(filter_var) PHP_FUNCTION(filter_input_array) { zend_long fetch_from; - zval *array_input = NULL, *op = NULL; + zval *array_input = NULL; zend_bool add_empty = 1; - - if (zend_parse_parameters(ZEND_NUM_ARGS(), "l|zb", &fetch_from, &op, &add_empty) == FAILURE) { - RETURN_THROWS(); - } - - if (op && (Z_TYPE_P(op) != IS_ARRAY) && !(Z_TYPE_P(op) == IS_LONG && PHP_FILTER_ID_EXISTS(Z_LVAL_P(op)))) { + HashTable *op_ht = NULL; + zend_long op_long = FILTER_DEFAULT; + + ZEND_PARSE_PARAMETERS_START(1, 3) + Z_PARAM_LONG(fetch_from) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_HT_OR_LONG(op_ht, op_long) + Z_PARAM_BOOL(add_empty) + ZEND_PARSE_PARAMETERS_END(); + + if (!op_ht && !PHP_FILTER_ID_EXISTS(op_long)) { + php_error_docref(NULL, E_WARNING, "Unknown filter with ID " ZEND_LONG_FMT, op_long); RETURN_FALSE; } @@ -742,12 +761,10 @@ PHP_FUNCTION(filter_input_array) if (!array_input) { zend_long filter_flags = 0; zval *option; - if (op) { - if (Z_TYPE_P(op) == IS_LONG) { - filter_flags = Z_LVAL_P(op); - } else if (Z_TYPE_P(op) == IS_ARRAY && (option = zend_hash_str_find(Z_ARRVAL_P(op), "flags", sizeof("flags") - 1)) != NULL) { - filter_flags = zval_get_long(option); - } + if (op_long) { + filter_flags = op_long; + } else if (op_ht && (option = zend_hash_str_find(op_ht, "flags", sizeof("flags") - 1)) != NULL) { + filter_flags = zval_get_long(option); } /* The FILTER_NULL_ON_FAILURE flag inverts the usual return values of @@ -762,25 +779,31 @@ PHP_FUNCTION(filter_input_array) } } - php_filter_array_handler(array_input, op, return_value, add_empty); + php_filter_array_handler(array_input, op_ht, op_long, return_value, add_empty); } /* }}} */ /* {{{ Returns an array with all arguments defined in 'definition'. */ PHP_FUNCTION(filter_var_array) { - zval *array_input = NULL, *op = NULL; + zval *array_input = NULL; zend_bool add_empty = 1; - - if (zend_parse_parameters(ZEND_NUM_ARGS(), "a|zb", &array_input, &op, &add_empty) == FAILURE) { - RETURN_THROWS(); - } - - if (op && (Z_TYPE_P(op) != IS_ARRAY) && !(Z_TYPE_P(op) == IS_LONG && PHP_FILTER_ID_EXISTS(Z_LVAL_P(op)))) { + HashTable *op_ht = NULL; + zend_long op_long = FILTER_DEFAULT; + + ZEND_PARSE_PARAMETERS_START(1, 3) + Z_PARAM_ARRAY(array_input) + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_HT_OR_LONG(op_ht, op_long) + Z_PARAM_BOOL(add_empty) + ZEND_PARSE_PARAMETERS_END(); + + if (!op_ht && !PHP_FILTER_ID_EXISTS(op_long)) { + php_error_docref(NULL, E_WARNING, "Unknown filter with ID " ZEND_LONG_FMT, op_long); RETURN_FALSE; } - php_filter_array_handler(array_input, op, return_value, add_empty); + php_filter_array_handler(array_input, op_ht, op_long, return_value, add_empty); } /* }}} */ diff --git a/ext/filter/filter.stub.php b/ext/filter/filter.stub.php index e8e6b0fbdd097..56f926b913f3c 100644 --- a/ext/filter/filter.stub.php +++ b/ext/filter/filter.stub.php @@ -4,17 +4,13 @@ function filter_has_var(int $type, string $variable_name): bool {} -/** @param array|int $options */ -function filter_input(int $type, string $variable_name, int $filter = FILTER_DEFAULT, $options = null): mixed {} +function filter_input(int $type, string $variable_name, int $filter = FILTER_DEFAULT, array|int $options = 0): mixed {} -/** @param array|int $options */ -function filter_var(mixed $variable, int $filter = FILTER_DEFAULT, $options = null): mixed {} +function filter_var(mixed $variable, int $filter = FILTER_DEFAULT, array|int $options = 0): mixed {} -/** @param array|int $options */ -function filter_input_array(int $type, $options = FILTER_DEFAULT, bool $add_empty = true): array|false|null {} +function filter_input_array(int $type, array|int $options = FILTER_DEFAULT, bool $add_empty = true): array|false|null {} -/** @param array|int $options */ -function filter_var_array(array $data, $options = FILTER_DEFAULT, bool $add_empty = true): array|false|null {} +function filter_var_array(array $data, array|int $options = FILTER_DEFAULT, bool $add_empty = true): array|false|null {} function filter_list(): array {} diff --git a/ext/filter/filter_arginfo.h b/ext/filter/filter_arginfo.h index 00d18092500f6..bb3ab54666c5b 100644 --- a/ext/filter/filter_arginfo.h +++ b/ext/filter/filter_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 54d4bb809e05c73a1a16174bce578377f7cd8f31 */ + * Stub hash: dae0cf8beeb47a996123cffd3b429482047d42c1 */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_filter_has_var, 0, 2, _IS_BOOL, 0) ZEND_ARG_TYPE_INFO(0, type, IS_LONG, 0) @@ -10,24 +10,24 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_filter_input, 0, 2, IS_MIXED, 0) ZEND_ARG_TYPE_INFO(0, type, IS_LONG, 0) ZEND_ARG_TYPE_INFO(0, variable_name, IS_STRING, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, filter, IS_LONG, 0, "FILTER_DEFAULT") - ZEND_ARG_INFO_WITH_DEFAULT_VALUE(0, options, "null") + ZEND_ARG_TYPE_MASK(0, options, MAY_BE_ARRAY|MAY_BE_LONG, "0") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_filter_var, 0, 1, IS_MIXED, 0) ZEND_ARG_TYPE_INFO(0, variable, IS_MIXED, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, filter, IS_LONG, 0, "FILTER_DEFAULT") - ZEND_ARG_INFO_WITH_DEFAULT_VALUE(0, options, "null") + ZEND_ARG_TYPE_MASK(0, options, MAY_BE_ARRAY|MAY_BE_LONG, "0") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_filter_input_array, 0, 1, MAY_BE_ARRAY|MAY_BE_FALSE|MAY_BE_NULL) ZEND_ARG_TYPE_INFO(0, type, IS_LONG, 0) - ZEND_ARG_INFO_WITH_DEFAULT_VALUE(0, options, "FILTER_DEFAULT") + ZEND_ARG_TYPE_MASK(0, options, MAY_BE_ARRAY|MAY_BE_LONG, "FILTER_DEFAULT") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, add_empty, _IS_BOOL, 0, "true") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_filter_var_array, 0, 1, MAY_BE_ARRAY|MAY_BE_FALSE|MAY_BE_NULL) ZEND_ARG_TYPE_INFO(0, data, IS_ARRAY, 0) - ZEND_ARG_INFO_WITH_DEFAULT_VALUE(0, options, "FILTER_DEFAULT") + ZEND_ARG_TYPE_MASK(0, options, MAY_BE_ARRAY|MAY_BE_LONG, "FILTER_DEFAULT") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, add_empty, _IS_BOOL, 0, "true") ZEND_END_ARG_INFO() diff --git a/ext/filter/tests/010.phpt b/ext/filter/tests/010.phpt index 46b6044668897..802f817e98948 100644 --- a/ext/filter/tests/010.phpt +++ b/ext/filter/tests/010.phpt @@ -17,7 +17,7 @@ var_dump(filter_var(1, 0, array())); echo "Done\n"; ?> ---EXPECT-- +--EXPECTF-- array(7) { [0]=> int(1) @@ -55,6 +55,10 @@ array(7) { string(1) "1" string(1) "1" string(1) "1" + +Warning: filter_var(): Unknown filter with ID -1 in %s on line %d bool(false) + +Warning: filter_var(): Unknown filter with ID 0 in %s on line %d bool(false) Done diff --git a/ext/filter/tests/011.phpt b/ext/filter/tests/011.phpt index 1b2a2ec3574ca..5c00f895fdec6 100644 --- a/ext/filter/tests/011.phpt +++ b/ext/filter/tests/011.phpt @@ -14,7 +14,11 @@ ini_set('html_errors', false); var_dump(filter_input(INPUT_GET, "a", FILTER_SANITIZE_STRIPPED)); var_dump(filter_input(INPUT_GET, "b", FILTER_SANITIZE_URL)); var_dump(filter_input(INPUT_GET, "a", FILTER_SANITIZE_SPECIAL_CHARS, array(1,2,3,4,5))); -var_dump(filter_input(INPUT_GET, "b", FILTER_VALIDATE_FLOAT, new stdClass)); +try { + filter_input(INPUT_GET, "b", FILTER_VALIDATE_FLOAT, new stdClass); +} catch (TypeError $exception) { + echo $exception->getMessage() . "\n"; +} var_dump(filter_input(INPUT_POST, "c", FILTER_SANITIZE_STRIPPED, array(5,6,7,8))); var_dump(filter_input(INPUT_POST, "d", FILTER_VALIDATE_FLOAT)); var_dump(filter_input(INPUT_POST, "c", FILTER_SANITIZE_SPECIAL_CHARS)); @@ -22,13 +26,11 @@ var_dump(filter_input(INPUT_POST, "d", FILTER_VALIDATE_INT)); echo "Done\n"; ?> ---EXPECTF-- +--EXPECT-- string(4) "test" string(18) "http://example.com" string(27) "<b>test</b>" - -Notice: Object of class stdClass could not be converted to int in %s011.php on line %d -bool(false) +filter_input(): Argument #4 ($options) must be of type array|int, stdClass given string(6) "string" float(12345.7) string(29) "<p>string</p>" diff --git a/ext/filter/tests/039.phpt b/ext/filter/tests/039.phpt index f5a1cf2fe7c22..ec6f075bc3a16 100644 --- a/ext/filter/tests/039.phpt +++ b/ext/filter/tests/039.phpt @@ -10,20 +10,41 @@ var_dump(filter_var_array(array())); var_dump(filter_var_array(array(1,"blah"=>"hoho"))); var_dump(filter_var_array(array(), -1)); var_dump(filter_var_array(array(), 1000000)); -var_dump(filter_var_array(array(), "")); + +try { + filter_var_array(array(), ""); +} catch (TypeError $exception) { + echo $exception->getMessage() . "\n"; +} echo "-- (2)\n"; var_dump(filter_var_array(array(""=>""), -1)); var_dump(filter_var_array(array(""=>""), 1000000)); -var_dump(filter_var_array(array(""=>""), "")); + +try { + filter_var_array(array(""=>""), ""); +} catch (TypeError $exception) { + echo $exception->getMessage() . "\n"; +} echo "-- (3)\n"; var_dump(filter_var_array(array("aaa"=>"bbb"), -1)); var_dump(filter_var_array(array("aaa"=>"bbb"), 1000000)); -var_dump(filter_var_array(array("aaa"=>"bbb"), "")); + +try { + filter_var_array(array("aaa"=>"bbb"), ""); +} catch (TypeError $exception) { + echo $exception->getMessage() . "\n"; +} echo "-- (4)\n"; -var_dump(filter_var_array(array(), new stdclass)); + +try { + filter_var_array(array(), new stdclass); +} catch (TypeError $exception) { + echo $exception->getMessage() . "\n"; +} + var_dump(filter_var_array(array(), array())); var_dump(filter_var_array(array(), array("var_name"=>1))); var_dump(filter_var_array(array(), array("var_name"=>-1))); @@ -50,12 +71,16 @@ var_dump(filter_var_array($a, $b)); var_dump($a, $b); $a = array(""=>""); $b = ""; -var_dump(filter_var_array($a, $b)); +try { + filter_var_array($a, $b); +} catch (TypeError $exception) { + echo $exception->getMessage() . "\n"; +} var_dump($a, $b); echo "Done\n"; ?> ---EXPECT-- +--EXPECTF-- -- (1) array(0) { } @@ -65,19 +90,31 @@ array(2) { ["blah"]=> string(4) "hoho" } + +Warning: filter_var_array(): Unknown filter with ID -1 in %s on line %d bool(false) + +Warning: filter_var_array(): Unknown filter with ID 1000000 in %s on line %d bool(false) -bool(false) +filter_var_array(): Argument #2 ($options) must be of type array|int, string given -- (2) + +Warning: filter_var_array(): Unknown filter with ID -1 in %s on line %d bool(false) + +Warning: filter_var_array(): Unknown filter with ID 1000000 in %s on line %d bool(false) -bool(false) +filter_var_array(): Argument #2 ($options) must be of type array|int, string given -- (3) + +Warning: filter_var_array(): Unknown filter with ID -1 in %s on line %d bool(false) + +Warning: filter_var_array(): Unknown filter with ID 1000000 in %s on line %d bool(false) -bool(false) +filter_var_array(): Argument #2 ($options) must be of type array|int, string given -- (4) -bool(false) +filter_var_array(): Argument #2 ($options) must be of type array|int, stdClass given array(0) { } array(1) { @@ -95,19 +132,23 @@ array(1) { -- (5) filter_var_array(): Argument #2 ($options) cannot contain empty keys filter_var_array(): Argument #2 ($options) cannot contain empty keys + +Warning: filter_var_array(): Unknown filter with ID -1 in %s on line %d bool(false) array(1) { [""]=> string(0) "" } int(-1) + +Warning: filter_var_array(): Unknown filter with ID 100000 in %s on line %d bool(false) array(1) { [""]=> string(0) "" } int(100000) -bool(false) +filter_var_array(): Argument #2 ($options) must be of type array|int, string given array(1) { [""]=> string(0) "" diff --git a/ext/filter/tests/057.phpt b/ext/filter/tests/057.phpt index fc4c3a824cd1c..7c57a2670b9ff 100644 --- a/ext/filter/tests/057.phpt +++ b/ext/filter/tests/057.phpt @@ -5,20 +5,44 @@ filter_input_array() and filter_var_array() with invalid $definition arguments --FILE-- getMessage() . "\n"; + } + + try { + var_dump(filter_var_array(array(), $invalid)); + } catch (TypeError $exception) { + echo $exception->getMessage() . "\n"; + } } ?> ---EXPECT-- -bool(false) -bool(false) -bool(false) -bool(false) +--EXPECTF-- +Warning: filter_input_array(): Unknown filter with ID 0 in %s on line %d bool(false) + +Warning: filter_var_array(): Unknown filter with ID 0 in %s on line %d bool(false) + +Warning: filter_input_array(): Unknown filter with ID 1 in %s on line %d bool(false) + +Warning: filter_var_array(): Unknown filter with ID 1 in %s on line %d bool(false) + +Warning: filter_input_array(): Unknown filter with ID 0 in %s on line %d bool(false) + +Warning: filter_var_array(): Unknown filter with ID 0 in %s on line %d bool(false) + +Warning: filter_input_array(): Unknown filter with ID 1 in %s on line %d bool(false) + +Warning: filter_var_array(): Unknown filter with ID 1 in %s on line %d bool(false) +filter_input_array(): Argument #2 ($options) must be of type array|int, string given +filter_var_array(): Argument #2 ($options) must be of type array|int, string given +filter_input_array(): Argument #2 ($options) must be of type array|int, stdClass given +filter_var_array(): Argument #2 ($options) must be of type array|int, stdClass given diff --git a/ext/intl/calendar/calendar_class.cpp b/ext/intl/calendar/calendar_class.cpp index 06f64f5e111c2..a46ef62e68756 100644 --- a/ext/intl/calendar/calendar_class.cpp +++ b/ext/intl/calendar/calendar_class.cpp @@ -57,9 +57,9 @@ U_CFUNC void calendar_object_create(zval *object, calendar_object_construct(object, calendar); } -U_CFUNC Calendar *calendar_fetch_native_calendar(zval *object) +U_CFUNC Calendar *calendar_fetch_native_calendar(zend_object *object) { - Calendar_object *co = Z_INTL_CALENDAR_P(object); + Calendar_object *co = php_intl_calendar_fetch_object(object); return co->ucal; } diff --git a/ext/intl/calendar/calendar_class.h b/ext/intl/calendar/calendar_class.h index a4d5236307e52..c301cda481aa9 100644 --- a/ext/intl/calendar/calendar_class.h +++ b/ext/intl/calendar/calendar_class.h @@ -61,14 +61,13 @@ static inline Calendar_object *php_intl_calendar_fetch_object(zend_object *obj) void calendar_object_create(zval *object, Calendar *calendar); -Calendar *calendar_fetch_native_calendar(zval *object); +Calendar *calendar_fetch_native_calendar(zend_object *object); void calendar_object_construct(zval *object, Calendar *calendar); void calendar_register_IntlCalendar_class(void); -extern zend_class_entry *Calendar_ce_ptr, - *GregorianCalendar_ce_ptr; +extern zend_class_entry *Calendar_ce_ptr, *GregorianCalendar_ce_ptr; extern zend_object_handlers Calendar_handlers; diff --git a/ext/intl/dateformat/dateformat.stub.php b/ext/intl/dateformat/dateformat.stub.php index 5d77e075554a5..53cda18560f2d 100644 --- a/ext/intl/dateformat/dateformat.stub.php +++ b/ext/intl/dateformat/dateformat.stub.php @@ -12,11 +12,10 @@ public function __construct(?string $locale, int $datetype, int $timetype, $time /** * @param IntlTimeZone|DateTimeZone|string|null $timezone - * @param IntlCalendar|int|null $calendar * @return IntlDateFormatter|null * @alias datefmt_create */ - public static function create(?string $locale, int $datetype, int $timetype, $timezone = null, $calendar = null, string $pattern = "") {} + public static function create(?string $locale, int $datetype, int $timetype, $timezone = null, IntlCalendar|int|null $calendar = null, string $pattern = "") {} /** * @return int|false @@ -37,11 +36,10 @@ public function getTimeType() {} public function getCalendar() {} /** - * @param IntlCalendar|int|null $which * @return bool * @alias datefmt_set_calendar */ - public function setCalendar($which) {} + public function setCalendar(IntlCalendar|int|null $which) {} /** * @return string|false diff --git a/ext/intl/dateformat/dateformat_arginfo.h b/ext/intl/dateformat/dateformat_arginfo.h index d94c886003906..7a468d4fda6b9 100644 --- a/ext/intl/dateformat/dateformat_arginfo.h +++ b/ext/intl/dateformat/dateformat_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 1b018a6b473db965a89c4ce9ebce3133d8d304db */ + * Stub hash: 6e7935cd23cd9bba625cf65d08d8e3796f938d74 */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_IntlDateFormatter___construct, 0, 0, 3) ZEND_ARG_TYPE_INFO(0, locale, IS_STRING, 1) @@ -10,7 +10,14 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_IntlDateFormatter___construct, 0, 0, 3) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, pattern, IS_STRING, 0, "\"\"") ZEND_END_ARG_INFO() -#define arginfo_class_IntlDateFormatter_create arginfo_class_IntlDateFormatter___construct +ZEND_BEGIN_ARG_INFO_EX(arginfo_class_IntlDateFormatter_create, 0, 0, 3) + ZEND_ARG_TYPE_INFO(0, locale, IS_STRING, 1) + ZEND_ARG_TYPE_INFO(0, datetype, IS_LONG, 0) + ZEND_ARG_TYPE_INFO(0, timetype, IS_LONG, 0) + ZEND_ARG_INFO_WITH_DEFAULT_VALUE(0, timezone, "null") + ZEND_ARG_OBJ_TYPE_MASK(0, calendar, IntlCalendar, MAY_BE_LONG|MAY_BE_NULL, "null") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, pattern, IS_STRING, 0, "\"\"") +ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_class_IntlDateFormatter_getDateType, 0, 0, 0) ZEND_END_ARG_INFO() @@ -20,7 +27,7 @@ ZEND_END_ARG_INFO() #define arginfo_class_IntlDateFormatter_getCalendar arginfo_class_IntlDateFormatter_getDateType ZEND_BEGIN_ARG_INFO_EX(arginfo_class_IntlDateFormatter_setCalendar, 0, 0, 1) - ZEND_ARG_INFO(0, which) + ZEND_ARG_OBJ_TYPE_MASK(0, which, IntlCalendar, MAY_BE_LONG|MAY_BE_NULL, NULL) ZEND_END_ARG_INFO() #define arginfo_class_IntlDateFormatter_getTimeZoneId arginfo_class_IntlDateFormatter_getDateType diff --git a/ext/intl/dateformat/dateformat_attrcpp.cpp b/ext/intl/dateformat/dateformat_attrcpp.cpp index fdf61d8500032..343ef170d2579 100644 --- a/ext/intl/dateformat/dateformat_attrcpp.cpp +++ b/ext/intl/dateformat/dateformat_attrcpp.cpp @@ -156,12 +156,22 @@ U_CFUNC PHP_FUNCTION(datefmt_get_calendar_object) /* {{{ Set formatter's calendar. */ U_CFUNC PHP_FUNCTION(datefmt_set_calendar) { - zval *calendar_zv; + zend_object *calendar_obj; + zend_long calendar_long; + zend_bool calendar_is_null; DATE_FORMAT_METHOD_INIT_VARS; - if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Oz", - &object, IntlDateFormatter_ce_ptr, &calendar_zv) == FAILURE) { - RETURN_THROWS(); + object = getThis(); + + if (object) { + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_OBJ_OF_CLASS_OR_LONG_OR_NULL(calendar_obj, Calendar_ce_ptr, calendar_long, calendar_is_null) + ZEND_PARSE_PARAMETERS_END(); + } else { + ZEND_PARSE_PARAMETERS_START(2, 2) + Z_PARAM_OBJECT_OF_CLASS(object, IntlDateFormatter_ce_ptr) + Z_PARAM_OBJ_OF_CLASS_OR_LONG_OR_NULL(calendar_obj, Calendar_ce_ptr, calendar_long, calendar_is_null) + ZEND_PARSE_PARAMETERS_END(); } DATE_FORMAT_METHOD_FETCH_OBJECT; @@ -174,9 +184,9 @@ U_CFUNC PHP_FUNCTION(datefmt_set_calendar) // because we would have lost modifiers such as @calendar. We // must store the requested locale on object creation - if (datefmt_process_calendar_arg(calendar_zv, locale, - "datefmt_set_calendar", INTL_DATA_ERROR_P(dfo), cal, cal_type, - cal_owned) == FAILURE) { + if (datefmt_process_calendar_arg(calendar_obj, calendar_long, calendar_is_null, locale, + "datefmt_set_calendar", INTL_DATA_ERROR_P(dfo), cal, cal_type, cal_owned) == FAILURE + ) { RETURN_FALSE; } diff --git a/ext/intl/dateformat/dateformat_create.cpp b/ext/intl/dateformat/dateformat_create.cpp index a75719c0f44b0..43e113fab1cf8 100644 --- a/ext/intl/dateformat/dateformat_create.cpp +++ b/ext/intl/dateformat/dateformat_create.cpp @@ -26,6 +26,8 @@ extern "C" { #include "php_intl.h" #include "dateformat_create.h" #include "dateformat_class.h" +#define USE_CALENDAR_POINTER 1 +#include "../calendar/calendar_class.h" #define USE_TIMEZONE_POINTER 1 #include "../timezone/timezone_class.h" #include "../intl_convert.h" @@ -43,16 +45,18 @@ extern "C" { UDAT_PATTERN == (i)) /* {{{ */ -static int datefmt_ctor(INTERNAL_FUNCTION_PARAMETERS) +static zend_result datefmt_ctor(INTERNAL_FUNCTION_PARAMETERS) { zval *object; - const char *locale_str; + char *locale_str; size_t locale_len = 0; Locale locale; zend_long date_type = 0; zend_long time_type = 0; - zval *calendar_zv = NULL; - Calendar *calendar = NULL; + zend_object *calendar_obj = NULL; + zend_long calendar_long; + zend_bool calendar_is_null = 1; + Calendar *cal = NULL; zend_long calendar_type; bool calendar_owned; zval *timezone_zv = NULL; @@ -66,18 +70,21 @@ static int datefmt_ctor(INTERNAL_FUNCTION_PARAMETERS) intl_error_reset(NULL); object = return_value; - /* Parse parameters. */ - if (zend_parse_parameters(ZEND_NUM_ARGS(), "s!ll|zzs", - &locale_str, &locale_len, &date_type, &time_type, &timezone_zv, - &calendar_zv, &pattern_str, &pattern_str_len) == FAILURE) { - return FAILURE; - } + + ZEND_PARSE_PARAMETERS_START(3, 6) + Z_PARAM_STRING_OR_NULL(locale_str, locale_len) + Z_PARAM_LONG(date_type) + Z_PARAM_LONG(time_type) + Z_PARAM_OPTIONAL + Z_PARAM_ZVAL(timezone_zv) + Z_PARAM_OBJ_OF_CLASS_OR_LONG_OR_NULL(calendar_obj, Calendar_ce_ptr, calendar_long, calendar_is_null) + Z_PARAM_STRING_OR_NULL(pattern_str, pattern_str_len) + ZEND_PARSE_PARAMETERS_END_EX(return FAILURE); DATE_FORMAT_METHOD_FETCH_OBJECT_NO_CHECK; if (DATE_FORMAT_OBJECT(dfo) != NULL) { - intl_errors_set(INTL_DATA_ERROR_P(dfo), U_ILLEGAL_ARGUMENT_ERROR, - "datefmt_create: cannot call constructor twice", 0); + intl_errors_set(INTL_DATA_ERROR_P(dfo), U_ILLEGAL_ARGUMENT_ERROR, "datefmt_create: cannot call constructor twice", 0); return FAILURE; } @@ -87,20 +94,19 @@ static int datefmt_ctor(INTERNAL_FUNCTION_PARAMETERS) } if (!INTL_UDATE_FMT_OK(time_type)) { intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "datefmt_create: invalid time format style", 0); - return FAILURE; +return FAILURE; } INTL_CHECK_LOCALE_LEN_OR_FAILURE(locale_len); if (locale_len == 0) { - locale_str = intl_locale_get_default(); + locale_str = (char *) intl_locale_get_default(); } locale = Locale::createFromName(locale_str); /* process calendar */ - if (datefmt_process_calendar_arg(calendar_zv, locale, "datefmt_create", - INTL_DATA_ERROR_P(dfo), calendar, calendar_type, - calendar_owned) - == FAILURE) { + if (datefmt_process_calendar_arg(calendar_obj, calendar_long, calendar_is_null, locale, "datefmt_create", + INTL_DATA_ERROR_P(dfo), cal, calendar_type, calendar_owned) == FAILURE + ) { goto error; } @@ -143,10 +149,10 @@ static int datefmt_ctor(INTERNAL_FUNCTION_PARAMETERS) if (!U_FAILURE(INTL_DATA_ERROR_CODE(dfo))) { DateFormat *df = (DateFormat*)DATE_FORMAT_OBJECT(dfo); if (calendar_owned) { - df->adoptCalendar(calendar); + df->adoptCalendar(cal); calendar_owned = false; } else { - df->setCalendar(*calendar); + df->setCalendar(*cal); } if (timezone != NULL) { @@ -171,8 +177,8 @@ static int datefmt_ctor(INTERNAL_FUNCTION_PARAMETERS) if (timezone != NULL && DATE_FORMAT_OBJECT(dfo) == NULL) { delete timezone; } - if (calendar != NULL && calendar_owned) { - delete calendar; + if (cal != NULL && calendar_owned) { + delete cal; } return U_FAILURE(intl_error_get_code(NULL)) ? FAILURE : SUCCESS; @@ -183,7 +189,7 @@ static int datefmt_ctor(INTERNAL_FUNCTION_PARAMETERS) U_CFUNC PHP_FUNCTION( datefmt_create ) { object_init_ex( return_value, IntlDateFormatter_ce_ptr ); - if (datefmt_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU) == FAILURE) { + if (datefmt_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU) == FAILURE) { zval_ptr_dtor(return_value); RETURN_NULL(); } diff --git a/ext/intl/dateformat/dateformat_format_object.cpp b/ext/intl/dateformat/dateformat_format_object.cpp index 9723006b1582b..d569eb935d26b 100644 --- a/ext/intl/dateformat/dateformat_format_object.cpp +++ b/ext/intl/dateformat/dateformat_format_object.cpp @@ -158,7 +158,7 @@ U_CFUNC PHP_FUNCTION(datefmt_format_object) zend_class_entry *instance_ce = Z_OBJCE_P(object); if (instanceof_function(instance_ce, Calendar_ce_ptr)) { - Calendar *obj_cal = calendar_fetch_native_calendar(object); + Calendar *obj_cal = calendar_fetch_native_calendar(Z_OBJ_P(object)); if (obj_cal == NULL) { intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "datefmt_format_object: bad IntlCalendar instance: " diff --git a/ext/intl/dateformat/dateformat_helpers.cpp b/ext/intl/dateformat/dateformat_helpers.cpp index 69332e931c6f8..46c909bf95af4 100644 --- a/ext/intl/dateformat/dateformat_helpers.cpp +++ b/ext/intl/dateformat/dateformat_helpers.cpp @@ -28,28 +28,22 @@ extern "C" { using icu::GregorianCalendar; -int datefmt_process_calendar_arg(zval* calendar_zv, - Locale const& locale, - const char *func_name, - intl_error *err, - Calendar*& cal, - zend_long& cal_int_type, - bool& calendar_owned) -{ +int datefmt_process_calendar_arg( + zend_object *calendar_obj, zend_long calendar_long, zend_bool calendar_is_null, Locale const& locale, + const char *func_name, intl_error *err, Calendar*& cal, zend_long& cal_int_type, bool& calendar_owned +) { char *msg; UErrorCode status = UErrorCode(); - if (calendar_zv == NULL || Z_TYPE_P(calendar_zv) == IS_NULL) { - + if (calendar_is_null) { // default requested cal = new GregorianCalendar(locale, status); calendar_owned = true; cal_int_type = UCAL_GREGORIAN; - } else if (Z_TYPE_P(calendar_zv) == IS_LONG) { - - zend_long v = Z_LVAL_P(calendar_zv); + } else if (!calendar_obj) { + zend_long v = calendar_long; if (v != (zend_long)UCAL_TRADITIONAL && v != (zend_long)UCAL_GREGORIAN) { spprintf(&msg, 0, "%s: Invalid value for calendar type; it must be " "one of IntlDateFormatter::TRADITIONAL (locale's default " @@ -66,12 +60,10 @@ int datefmt_process_calendar_arg(zval* calendar_zv, } calendar_owned = true; - cal_int_type = Z_LVAL_P(calendar_zv); - - } else if (Z_TYPE_P(calendar_zv) == IS_OBJECT && - instanceof_function(Z_OBJCE_P(calendar_zv), Calendar_ce_ptr)) { + cal_int_type = calendar_long; - cal = calendar_fetch_native_calendar(calendar_zv); + } else if (calendar_obj) { + cal = calendar_fetch_native_calendar(calendar_obj); if (cal == NULL) { spprintf(&msg, 0, "%s: Found unconstructed IntlCalendar object", func_name); diff --git a/ext/intl/dateformat/dateformat_helpers.h b/ext/intl/dateformat/dateformat_helpers.h index 0c88977015fe9..1f2d7eb32e79c 100644 --- a/ext/intl/dateformat/dateformat_helpers.h +++ b/ext/intl/dateformat/dateformat_helpers.h @@ -30,12 +30,9 @@ using icu::Locale; using icu::Calendar; using icu::DateFormat; -int datefmt_process_calendar_arg(zval* calendar_zv, - Locale const& locale, - const char *func_name, - intl_error *err, - Calendar*& cal, - zend_long& cal_int_type, - bool& calendar_owned); +int datefmt_process_calendar_arg( + zend_object *calendar_obj, zend_long calendar_long, zend_bool calendar_is_null, Locale const& locale, + const char *func_name, intl_error *err, Calendar*& cal, zend_long& cal_int_type, bool& calendar_owned +); #endif /* DATEFORMAT_HELPERS_H */ diff --git a/ext/intl/php_intl.stub.php b/ext/intl/php_intl.stub.php index 7662004f304bd..f2a1af1c2e2e0 100644 --- a/ext/intl/php_intl.stub.php +++ b/ext/intl/php_intl.stub.php @@ -153,11 +153,8 @@ function intl_error_name(int $error_code): string {} /* dateformat */ -/** - * @param IntlTimeZone|DateTimeZone|string|null $timezone - * @param IntlCalendar|int|null $calendar - */ -function datefmt_create(?string $locale, int $datetype, int $timetype, $timezone = null, $calendar = null, string $pattern = ""): ?IntlDateFormatter {} +/** @param IntlTimeZone|DateTimeZone|string|null $timezone */ +function datefmt_create(?string $locale, int $datetype, int $timetype, $timezone = null, IntlCalendar|int|null $calendar = null, string $pattern = ""): ?IntlDateFormatter {} function datefmt_get_datetype(IntlDateFormatter $df): int|false {} @@ -165,8 +162,7 @@ function datefmt_get_timetype(IntlDateFormatter $df): int|false {} function datefmt_get_calendar(IntlDateFormatter $df): int|false {} -/** @param IntlCalendar|int|null $which */ -function datefmt_set_calendar(IntlDateFormatter $df, $which): bool {} +function datefmt_set_calendar(IntlDateFormatter $df, IntlCalendar|int|null $which): bool {} function datefmt_get_timezone_id(IntlDateFormatter $df): string|false {} diff --git a/ext/intl/php_intl_arginfo.h b/ext/intl/php_intl_arginfo.h index 3917187a5cc2d..32f098d0bb878 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: fdc7c500ddc5bc560ec54b7ce12d5961a4697a63 */ + * Stub hash: 324b7ae3eaab4777117c1c6963bc841088e6b998 */ 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") @@ -281,7 +281,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_datefmt_create, 0, 3, IntlDateFor ZEND_ARG_TYPE_INFO(0, datetype, IS_LONG, 0) ZEND_ARG_TYPE_INFO(0, timetype, IS_LONG, 0) ZEND_ARG_INFO_WITH_DEFAULT_VALUE(0, timezone, "null") - ZEND_ARG_INFO_WITH_DEFAULT_VALUE(0, calendar, "null") + ZEND_ARG_OBJ_TYPE_MASK(0, calendar, IntlCalendar, MAY_BE_LONG|MAY_BE_NULL, "null") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, pattern, IS_STRING, 0, "\"\"") ZEND_END_ARG_INFO() @@ -295,7 +295,7 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_datefmt_set_calendar, 0, 2, _IS_BOOL, 0) ZEND_ARG_OBJ_INFO(0, df, IntlDateFormatter, 0) - ZEND_ARG_INFO(0, which) + ZEND_ARG_OBJ_TYPE_MASK(0, which, IntlCalendar, MAY_BE_LONG|MAY_BE_NULL, NULL) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_datefmt_get_timezone_id, 0, 1, MAY_BE_STRING|MAY_BE_FALSE) diff --git a/ext/intl/tests/dateformat___construct_bad_tz_cal.phpt b/ext/intl/tests/dateformat___construct_bad_tz_cal.phpt index 086bc013402b5..928c30b9222b8 100644 --- a/ext/intl/tests/dateformat___construct_bad_tz_cal.phpt +++ b/ext/intl/tests/dateformat___construct_bad_tz_cal.phpt @@ -26,7 +26,7 @@ try { } try { var_dump(new IntlDateFormatter(NULL, 0, 0, NULL, new stdclass)); -} catch (IntlException $e) { +} catch (TypeError $e) { print_exception($e); } ?> @@ -35,4 +35,4 @@ Exception: IntlDateFormatter::__construct(): datefmt_create: No such time zone: Exception: IntlDateFormatter::__construct(): datefmt_create: Invalid value for calendar type; it must be one of IntlDateFormatter::TRADITIONAL (locale's default calendar) or IntlDateFormatter::GREGORIAN. Alternatively, it can be an IntlCalendar object in %s on line %d -Exception: IntlDateFormatter::__construct(): datefmt_create: Invalid calendar argument; should be an integer or an IntlCalendar instance in %s on line %d +Exception: IntlDateFormatter::__construct(): Argument #5 ($calendar) must be of type IntlCalendar|int|null, stdClass given in %s on line %d diff --git a/ext/json/json_encoder.c b/ext/json/json_encoder.c index d08a4666435d1..92e4a10933957 100644 --- a/ext/json/json_encoder.c +++ b/ext/json/json_encoder.c @@ -113,15 +113,15 @@ static inline void php_json_encode_double(smart_str *buf, double d, int options) #define PHP_JSON_HASH_PROTECT_RECURSION(_tmp_ht) \ do { \ - if (_tmp_ht && !(GC_FLAGS(_tmp_ht) & GC_IMMUTABLE)) { \ - GC_PROTECT_RECURSION(_tmp_ht); \ + if (_tmp_ht) { \ + GC_TRY_PROTECT_RECURSION(_tmp_ht); \ } \ } while (0) #define PHP_JSON_HASH_UNPROTECT_RECURSION(_tmp_ht) \ do { \ - if (_tmp_ht && !(GC_FLAGS(_tmp_ht) & GC_IMMUTABLE)) { \ - GC_UNPROTECT_RECURSION(_tmp_ht); \ + if (_tmp_ht) { \ + GC_TRY_UNPROTECT_RECURSION(_tmp_ht); \ } \ } while (0) diff --git a/ext/mbstring/libmbfl/filters/mbfilter_cp5022x.c b/ext/mbstring/libmbfl/filters/mbfilter_cp5022x.c index a68285bc7310d..3879f9eb5bba0 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_cp5022x.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_cp5022x.c @@ -586,8 +586,8 @@ mbfl_filt_conv_wchar_cp50220_ctor(mbfl_convert_filter *filt) ctx->last.data = filt->data; 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 = ctx->last.filter_flush; + filt->output_function = (output_function_t)ctx->last.filter_function; + filt->flush_function = (flush_function_t)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 755b06871c2c0..793dd8e078194 100644 --- a/ext/mbstring/libmbfl/mbfl/mbfilter.c +++ b/ext/mbstring/libmbfl/mbfl/mbfilter.c @@ -129,8 +129,8 @@ mbfl_buffer_converter_new( if (convd->filter2 != NULL) { convd->filter1 = mbfl_convert_filter_new(from, &mbfl_encoding_wchar, - (int (*)(int, void*))convd->filter2->filter_function, - convd->filter2->filter_flush, + (output_function_t)convd->filter2->filter_function, + (flush_function_t)convd->filter2->filter_flush, convd->filter2); if (convd->filter1 == NULL) { mbfl_convert_filter_delete(convd->filter2); @@ -1196,8 +1196,8 @@ mbfl_strcut( } /* switch the drain direction */ - encoder->output_function = (int(*)(int,void *))decoder->filter_function; - encoder->flush_function = decoder->filter_flush; + encoder->output_function = (output_function_t)decoder->filter_function; + encoder->flush_function = (flush_function_t)decoder->filter_flush; encoder->data = decoder; q = string->val + string->len; @@ -1605,7 +1605,7 @@ mbfl_ja_jp_hantozen( tl_filter = mbfl_convert_filter_new2( &vtbl_tl_jisx0201_jisx0208, (int(*)(int, void*))next_filter->filter_function, - next_filter->filter_flush, + (flush_function_t)next_filter->filter_flush, next_filter); if (tl_filter == NULL) { efree(param); @@ -1619,7 +1619,7 @@ mbfl_ja_jp_hantozen( string->encoding, &mbfl_encoding_wchar, (int(*)(int, void*))next_filter->filter_function, - next_filter->filter_flush, + (flush_function_t)next_filter->filter_flush, next_filter); if (encoder == NULL) { goto out; @@ -2637,7 +2637,7 @@ mbfl_html_numeric_entity( string->encoding, &mbfl_encoding_wchar, collector_decode_htmlnumericentity, - mbfl_filt_decode_htmlnumericentity_flush, &pc); + (flush_function_t)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 544fee7a33ca8..6a46c2b541a1f 100644 --- a/ext/mbstring/libmbfl/mbfl/mbfl_convert.c +++ b/ext/mbstring/libmbfl/mbfl/mbfl_convert.c @@ -116,7 +116,7 @@ static const struct mbfl_convert_vtbl *mbfl_special_filter_list[] = { }; 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) + const struct mbfl_convert_vtbl *vtbl, output_function_t output_function, flush_function_t flush_function, void* data) { /* encoding structure */ filter->from = from; @@ -143,8 +143,8 @@ static void mbfl_convert_filter_common_init(mbfl_convert_filter *filter, const m } -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* mbfl_convert_filter_new(const mbfl_encoding *from, const mbfl_encoding *to, output_function_t output_function, + flush_function_t flush_function, void* data) { const struct mbfl_convert_vtbl *vtbl = mbfl_convert_filter_get_vtbl(from, to); if (vtbl == NULL) { @@ -156,8 +156,8 @@ mbfl_convert_filter* mbfl_convert_filter_new(const mbfl_encoding *from, const mb return filter; } -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* mbfl_convert_filter_new2(const struct mbfl_convert_vtbl *vtbl, output_function_t output_function, + flush_function_t flush_function, void* data) { const mbfl_encoding *from_encoding = mbfl_no2encoding(vtbl->from); const mbfl_encoding *to_encoding = mbfl_no2encoding(vtbl->to); @@ -175,6 +175,12 @@ void mbfl_convert_filter_delete(mbfl_convert_filter *filter) efree(filter); } +/* Feed a char, return 0 if ok - used by mailparse ext */ +int mbfl_convert_filter_feed(int c, mbfl_convert_filter *filter) +{ + return (*filter->filter_function)(c, filter); +} + /* 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) { diff --git a/ext/mbstring/libmbfl/mbfl/mbfl_convert.h b/ext/mbstring/libmbfl/mbfl/mbfl_convert.h index 6fc6b3c6bccf6..771c38e3dfc18 100644 --- a/ext/mbstring/libmbfl/mbfl/mbfl_convert.h +++ b/ext/mbstring/libmbfl/mbfl/mbfl_convert.h @@ -37,17 +37,21 @@ typedef struct _mbfl_convert_filter mbfl_convert_filter; -typedef int (*filter_output_func)(int, void*); -typedef int (*filter_flush_func)(mbfl_convert_filter*); +/* internal */ +typedef int (*filter_flush_t)(mbfl_convert_filter*); + +/* defined by mbfl_convert_filter_{new,new2,init} */ +typedef int (*output_function_t)(int, void*); +typedef int (*flush_function_t)(void *); 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); - filter_flush_func filter_flush; - filter_output_func output_function; - filter_flush_func flush_function; + filter_flush_t filter_flush; + output_function_t output_function; + flush_function_t flush_function; void *data; int status; int cache; @@ -59,11 +63,12 @@ struct _mbfl_convert_filter { void *opaque; }; -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 mbfl_convert_filter *mbfl_convert_filter_new(const mbfl_encoding *from, const mbfl_encoding *to, output_function_t output_function, + flush_function_t flush_function, void *data); +MBFLAPI extern mbfl_convert_filter *mbfl_convert_filter_new2(const struct mbfl_convert_vtbl *vtbl, output_function_t output_function, + flush_function_t flush_function, void *data); MBFLAPI extern void mbfl_convert_filter_delete(mbfl_convert_filter *filter); +MBFLAPI extern int mbfl_convert_filter_feed(int c, mbfl_convert_filter *filter); 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); diff --git a/ext/mbstring/mbstring.c b/ext/mbstring/mbstring.c index 1189270bec61c..274feec35ef5b 100644 --- a/ext/mbstring/mbstring.c +++ b/ext/mbstring/mbstring.c @@ -2233,8 +2233,7 @@ PHP_FUNCTION(mb_strcut) } if (from > string.len) { - // TODO Out of bounds ValueError - RETURN_FALSE; + RETURN_EMPTY_STRING(); } ret = mbfl_strcut(&string, &result, from, len); @@ -3488,7 +3487,7 @@ PHP_FUNCTION(mb_send_mail) Z_PARAM_PATH(subject, subject_len) Z_PARAM_PATH(message, message_len) Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_HT_OR_STR_OR_NULL(headers_ht, str_headers) + Z_PARAM_ARRAY_HT_OR_STR(headers_ht, str_headers) Z_PARAM_PATH_STR_OR_NULL(extra_cmd) ZEND_PARSE_PARAMETERS_END(); @@ -3500,6 +3499,9 @@ PHP_FUNCTION(mb_send_mail) str_headers = php_trim(str_headers, NULL, 0, 2); } else if (headers_ht) { str_headers = php_mail_build_headers(headers_ht); + if (EG(exception)) { + RETURN_THROWS(); + } } zend_hash_init(&ht_headers, 0, NULL, ZVAL_PTR_DTOR, 0); diff --git a/ext/mbstring/mbstring.stub.php b/ext/mbstring/mbstring.stub.php index d089c24c194cb..74f86404cf4eb 100644 --- a/ext/mbstring/mbstring.stub.php +++ b/ext/mbstring/mbstring.stub.php @@ -45,7 +45,7 @@ function mb_substr_count(string $haystack, string $needle, ?string $encoding = n function mb_substr(string $str, int $start, ?int $length = null, ?string $encoding = null): string {} -function mb_strcut(string $str, int $start, ?int $length = null, ?string $encoding = null): string|false {} +function mb_strcut(string $str, int $start, ?int $length = null, ?string $encoding = null): string {} function mb_strwidth(string $str, ?string $encoding = null): int {} @@ -77,7 +77,7 @@ function mb_encode_numericentity(string $string, array $convmap, ?string $encodi function mb_decode_numericentity(string $string, array $convmap, ?string $encoding = null): string {} -function mb_send_mail(string $to, string $subject, string $message, array|string|null $additional_headers = null, ?string $additional_parameters = null): bool {} +function mb_send_mail(string $to, string $subject, string $message, array|string $additional_headers = [], ?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 873a0c86a45cc..27b692c26f617 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: 84096daa0fd395f57401f11e9e79f7c8420e8a93 */ + * Stub hash: e02a0588d1f46fa96452558e35ea904907b8bdf2 */ 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") @@ -87,12 +87,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_mb_substr, 0, 2, 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_mb_strcut, 0, 2, MAY_BE_STRING|MAY_BE_FALSE) - ZEND_ARG_TYPE_INFO(0, str, IS_STRING, 0) - ZEND_ARG_TYPE_INFO(0, start, IS_LONG, 0) - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, length, IS_LONG, 1, "null") - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, encoding, IS_STRING, 1, "null") -ZEND_END_ARG_INFO() +#define arginfo_mb_strcut arginfo_mb_substr #define arginfo_mb_strwidth arginfo_mb_strlen @@ -178,7 +173,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_TYPE_MASK(0, additional_headers, MAY_BE_ARRAY|MAY_BE_STRING|MAY_BE_NULL, "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, 1, "null") ZEND_END_ARG_INFO() diff --git a/ext/mbstring/tests/bug49354.phpt b/ext/mbstring/tests/bug49354.phpt index c25b405d82032..1326efca7dd5a 100644 --- a/ext/mbstring/tests/bug49354.phpt +++ b/ext/mbstring/tests/bug49354.phpt @@ -11,6 +11,7 @@ var_dump(mb_strcut($crap, 2, 100, 'UTF-8')); var_dump(mb_strcut($crap, 3, 100, 'UTF-8')); var_dump(mb_strcut($crap, 12, 100, 'UTF-8')); var_dump(mb_strcut($crap, 13, 100, 'UTF-8')); + ?> --EXPECT-- string(12) "AÃ¥BäCöDü" @@ -18,4 +19,4 @@ string(11) "Ã¥BäCöDü" string(11) "Ã¥BäCöDü" string(9) "BäCöDü" string(0) "" -bool(false) +string(0) "" diff --git a/ext/mbstring/tests/mb_strcut.phpt b/ext/mbstring/tests/mb_strcut.phpt index 40cc3ddb0dcef..5c191f7dcd983 100644 --- a/ext/mbstring/tests/mb_strcut.phpt +++ b/ext/mbstring/tests/mb_strcut.phpt @@ -29,7 +29,7 @@ print MBStringChars(mb_strcut($euc_jp, 5, 5,'EUC-JP'), 'EUC-JP') . "\n"; print MBStringChars(mb_strcut($euc_jp, 0, 100,'EUC-JP'), 'EUC-JP') . "\n"; $str = mb_strcut($euc_jp, 100, 10,'EUC-JP'); -($str === false) ? print "OK\n" : print "No good\n"; +($str === "") ? print "OK\n" : print "No good\n"; $str = mb_strcut($euc_jp, -100, 10,'EUC-JP'); ($str !== "") ? print "OK\n" : print "No good\n"; diff --git a/ext/mysqli/mysqli.c b/ext/mysqli/mysqli.c index b2f85bc147df0..e056ceba2dabd 100644 --- a/ext/mysqli/mysqli.c +++ b/ext/mysqli/mysqli.c @@ -384,8 +384,7 @@ static int mysqli_object_has_property(zend_object *object, zend_string *name, in } break; } - default: - php_error_docref(NULL, E_WARNING, "Invalid value for has_set_exists"); + EMPTY_SWITCH_DEFAULT_CASE(); } } else { ret = zend_std_has_property(object, name, has_set_exists, cache_slot); @@ -1035,7 +1034,8 @@ PHP_METHOD(mysqli_result, __construct) result = mysql_use_result(mysql->mysql); break; default: - php_error_docref(NULL, E_WARNING, "Invalid value for resultmode"); + zend_argument_value_error(2, "must be either MYSQLI_STORE_RESULT or MYSQLI_USE_RESULT"); + RETURN_THROWS(); } if (!result) { @@ -1052,7 +1052,7 @@ PHP_METHOD(mysqli_result, __construct) PHP_METHOD(mysqli_result, getIterator) { if (zend_parse_parameters_none() == FAILURE) { - return; + RETURN_THROWS(); } zend_create_internal_iterator_zval(return_value, ZEND_THIS); @@ -1130,6 +1130,7 @@ void php_mysqli_fetch_into_hash_aux(zval *return_value, MYSQL_RES * result, zend } /* }}} */ +/* TODO Split this up */ /* {{{ php_mysqli_fetch_into_hash */ void php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAMETERS, int override_flags, int into_object) { diff --git a/ext/mysqli/mysqli.stub.php b/ext/mysqli/mysqli.stub.php index 940f3c4fcc749..de74bba8e128f 100644 --- a/ext/mysqli/mysqli.stub.php +++ b/ext/mysqli/mysqli.stub.php @@ -164,7 +164,7 @@ public function prepare(string $query) {} * @return mysqli_result|bool * @alias mysqli_query */ - public function query(string $query, int $resultmode = MYSQLI_STORE_RESULT) {} + public function query(string $query, int $result_mode = MYSQLI_STORE_RESULT) {} /** * @return bool @@ -301,7 +301,7 @@ public function refresh(int $options) {} class mysqli_result implements IteratorAggregate { - public function __construct(object $mysqli_link, int $resmode = MYSQLI_STORE_RESULT) {} + public function __construct(object $mysqli_link, int $result_mode = MYSQLI_STORE_RESULT) {} /** * @return void @@ -421,7 +421,7 @@ public function bind_result(mixed &...$vars) {} public function close() {} /** - * @return bool|null + * @return void * @alias mysqli_stmt_data_seek */ public function data_seek(int $offset) {} @@ -641,7 +641,7 @@ function mysqli_prepare(mysqli $mysqli_link, string $query): mysqli_stmt|false { function mysqli_report(int $flags): bool {} -function mysqli_query(mysqli $mysqli_link, string $query, int $resultmode = MYSQLI_STORE_RESULT): mysqli_result|bool {} +function mysqli_query(mysqli $mysqli_link, string $query, int $result_mode = MYSQLI_STORE_RESULT): mysqli_result|bool {} function mysqli_real_connect( mysqli $mysqli_link, @@ -672,7 +672,7 @@ function mysqli_set_charset(mysqli $mysqli_link, string $charset): bool {} function mysqli_stmt_affected_rows(mysqli_stmt $mysql_stmt): int|string {} -function mysqli_stmt_attr_get(mysqli_stmt $mysql_stmt, int $attr): int|false {} +function mysqli_stmt_attr_get(mysqli_stmt $mysql_stmt, int $attr): int {} function mysqli_stmt_attr_set(mysqli_stmt $mysql_stmt, int $attr, int $mode_in): bool {} @@ -682,7 +682,7 @@ function mysqli_stmt_bind_result(mysqli_stmt $mysql_stmt, mixed &...$vars): bool function mysqli_stmt_close(mysqli_stmt $mysql_stmt): bool {} -function mysqli_stmt_data_seek(mysqli_stmt $mysql_stmt, int $offset): ?bool {} +function mysqli_stmt_data_seek(mysqli_stmt $mysql_stmt, int $offset): void {} function mysqli_stmt_errno(mysqli_stmt $mysql_stmt): int {} diff --git a/ext/mysqli/mysqli_api.c b/ext/mysqli/mysqli_api.c index 3f89e838fd894..88e6e91cd151a 100644 --- a/ext/mysqli/mysqli_api.c +++ b/ext/mysqli/mysqli_api.c @@ -31,6 +31,8 @@ #include "mysqli_priv.h" #include "ext/mysqlnd/mysql_float_to_double.h" +#define ERROR_ARG_POS(arg_num) (getThis() ? (arg_num-1) : (arg_num)) + #ifndef MYSQLI_USE_MYSQLND /* {{{ mysqli_tx_cor_options_to_string */ @@ -324,19 +326,19 @@ PHP_FUNCTION(mysqli_stmt_bind_param) MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID); if (!types_len) { - php_error_docref(NULL, E_WARNING, "Invalid type or no types specified"); - RETURN_FALSE; + zend_argument_value_error(ERROR_ARG_POS(2), "cannot be empty"); + RETURN_THROWS(); } if (types_len != (size_t) argc) { /* number of bind variables doesn't match number of elements in type definition string */ - php_error_docref(NULL, E_WARNING, "Number of elements in type definition string doesn't match number of bind variables"); - RETURN_FALSE; + zend_argument_count_error("The number of elements in the type definition string must match the number of bind variables"); + RETURN_THROWS(); } if (types_len != mysql_stmt_param_count(stmt->stmt)) { - php_error_docref(NULL, E_WARNING, "Number of variables doesn't match number of parameters in prepared statement"); - RETURN_FALSE; + zend_argument_count_error("The number of variables must match the number of parameters in the prepared statement"); + RETURN_THROWS(); } RETVAL_BOOL(!mysqli_stmt_bind_param_do_bind(stmt, argc, args, types, getThis() ? 1 : 2)); @@ -557,8 +559,8 @@ PHP_FUNCTION(mysqli_stmt_bind_result) MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID); if ((uint32_t)argc != mysql_stmt_field_count(stmt->stmt)) { - php_error_docref(NULL, E_WARNING, "Number of bind variables doesn't match number of fields in prepared statement"); - RETURN_FALSE; + zend_argument_count_error("Number of bind variables doesn't match number of fields in prepared statement"); + RETURN_THROWS(); } rc = mysqli_stmt_bind_result_do_bind(stmt, args, argc); @@ -729,14 +731,23 @@ PHP_FUNCTION(mysqli_data_seek) RETURN_THROWS(); } + if (offset < 0) { + zend_argument_value_error(ERROR_ARG_POS(2), "must be greater than or equal to 0"); + RETURN_THROWS(); + } + MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, mysql_result, "mysqli_result", MYSQLI_STATUS_VALID); if (mysqli_result_is_unbuffered(result)) { - php_error_docref(NULL, E_WARNING, "Function cannot be used with MYSQL_USE_RESULT"); - RETURN_FALSE; + if (getThis()) { + zend_throw_error(NULL, "mysqli_result::data_seek() cannot be used with MYSQLI_USE_RESULT"); + } else { + zend_throw_error(NULL, "mysqli_data_seek() cannot be used with MYSQLI_USE_RESULT"); + } + RETURN_THROWS(); } - if (offset < 0 || (uint64_t)offset >= mysql_num_rows(result)) { + if ((uint64_t)offset >= mysql_num_rows(result)) { RETURN_FALSE; } @@ -1181,11 +1192,16 @@ PHP_FUNCTION(mysqli_fetch_field_direct) RETURN_THROWS(); } + if (offset < 0) { + zend_argument_value_error(ERROR_ARG_POS(2), "must be greater than or equal to 0"); + RETURN_THROWS(); + } + MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, mysql_result, "mysqli_result", MYSQLI_STATUS_VALID); - if (offset < 0 || offset >= (zend_long) mysql_num_fields(result)) { - php_error_docref(NULL, E_WARNING, "Field offset is invalid for resultset"); - RETURN_FALSE; + if (offset >= (zend_long) mysql_num_fields(result)) { + zend_argument_value_error(ERROR_ARG_POS(2), "must be less than the number of fields for this result set"); + RETURN_THROWS(); } if (!(field = mysql_fetch_field_direct(result,offset))) { @@ -1215,6 +1231,7 @@ PHP_FUNCTION(mysqli_fetch_lengths) MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, mysql_result, "mysqli_result", MYSQLI_STATUS_VALID); + // TODO Warning? if (!(ret = mysql_fetch_lengths(result))) { RETURN_FALSE; } @@ -1260,9 +1277,16 @@ PHP_FUNCTION(mysqli_field_seek) if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Ol", &mysql_result, mysqli_result_class_entry, &fieldnr) == FAILURE) { RETURN_THROWS(); } + + if (fieldnr < 0) { + zend_argument_value_error(ERROR_ARG_POS(2), "must be greater than or equal to 0"); + RETURN_THROWS(); + } + MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, mysql_result, "mysqli_result", MYSQLI_STATUS_VALID); - if (fieldnr < 0 || (uint32_t)fieldnr >= mysql_num_fields(result)) { + if ((uint32_t)fieldnr >= mysql_num_fields(result)) { + // TODO ValueError? php_error_docref(NULL, E_WARNING, "Invalid field offset"); RETURN_FALSE; } @@ -1499,13 +1523,14 @@ PHP_FUNCTION(mysqli_kill) if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Ol", &mysql_link, mysqli_link_class_entry, &processid) == FAILURE) { RETURN_THROWS(); } - MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID); if (processid <= 0) { - php_error_docref(NULL, E_WARNING, "processid should have positive value"); - RETURN_FALSE; + zend_argument_value_error(ERROR_ARG_POS(2), "must be greater than 0"); + RETURN_THROWS(); } + MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID); + if (mysql_kill(mysql->mysql, processid)) { MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql); RETURN_FALSE; @@ -1601,8 +1626,8 @@ PHP_FUNCTION(mysqli_num_rows) MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, mysql_result, "mysqli_result", MYSQLI_STATUS_VALID); if (mysqli_result_is_unbuffered_and_not_everything_is_fetched(result)) { - php_error_docref(NULL, E_WARNING, "Function cannot be used with MYSQL_USE_RESULT"); - RETURN_LONG(0); + zend_throw_error(NULL, "mysqli_num_rows() cannot be used with MYSQLI_USE_RESULT"); + RETURN_THROWS(); } MYSQLI_RETURN_LONG_INT(mysql_num_rows(result)); @@ -1922,12 +1947,14 @@ PHP_FUNCTION(mysqli_stmt_send_long_data) if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Ols", &mysql_stmt, mysqli_stmt_class_entry, ¶m_nr, &data, &data_len) == FAILURE) { RETURN_THROWS(); } + MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID); if (param_nr < 0) { - php_error_docref(NULL, E_WARNING, "Invalid parameter number"); - RETURN_FALSE; + zend_argument_value_error(ERROR_ARG_POS(2), "must be greater than or equal to 0"); + RETURN_THROWS(); } + if (mysql_stmt_send_long_data(stmt->stmt, param_nr, data, data_len)) { RETURN_FALSE; } @@ -1984,9 +2011,10 @@ PHP_FUNCTION(mysqli_stmt_data_seek) if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Ol", &mysql_stmt, mysqli_stmt_class_entry, &offset) == FAILURE) { RETURN_THROWS(); } + if (offset < 0) { - php_error_docref(NULL, E_WARNING, "Offset must be positive"); - RETURN_FALSE; + zend_argument_value_error(ERROR_ARG_POS(2), "must be greater than or equal to 0"); + RETURN_THROWS(); } MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID); @@ -2216,7 +2244,7 @@ PHP_FUNCTION(mysqli_stmt_attr_set) zval *mysql_stmt; zend_long mode_in; #if MYSQL_VERSION_ID >= 50107 - my_bool mode_b; + my_bool mode_b; #endif unsigned long mode; zend_long attr; @@ -2225,25 +2253,54 @@ PHP_FUNCTION(mysqli_stmt_attr_set) if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Oll", &mysql_stmt, mysqli_stmt_class_entry, &attr, &mode_in) == FAILURE) { RETURN_THROWS(); } - MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID); - if (mode_in < 0) { - php_error_docref(NULL, E_WARNING, "Mode should be non-negative, " ZEND_LONG_FMT " passed", mode_in); - RETURN_FALSE; - } + MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID); switch (attr) { #if MYSQL_VERSION_ID >= 50107 case STMT_ATTR_UPDATE_MAX_LENGTH: + if (mode_in != 0 && mode_in != 1) { + zend_argument_value_error(ERROR_ARG_POS(3), "must be 0 or 1 for attribute MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH"); + RETURN_THROWS(); + } mode_b = (my_bool) mode_in; mode_p = &mode_b; break; #endif - default: + case STMT_ATTR_CURSOR_TYPE: + switch (mode_in) { + case CURSOR_TYPE_NO_CURSOR: + case CURSOR_TYPE_READ_ONLY: + case CURSOR_TYPE_FOR_UPDATE: + case CURSOR_TYPE_SCROLLABLE: + break; + default: + zend_argument_value_error(ERROR_ARG_POS(3), "must be one of MYSQLI_CURSOR_TYPE_NO_CURSOR, " + "MYSQLI_CURSOR_TYPE_READ_ONLY, MYSQLI_CURSOR_TYPE_FOR_UPDATE, or MYSQLI_CURSOR_TYPE_SCROLLABLE " + "for attribute MYSQLI_STMT_ATTR_CURSOR_TYPE"); + RETURN_THROWS(); + } mode = mode_in; mode_p = &mode; break; + case STMT_ATTR_PREFETCH_ROWS: + if (mode_in < 1) { + zend_argument_value_error(ERROR_ARG_POS(3), "must be greater than 0 for attribute MYSQLI_STMT_ATTR_PREFETCH_ROWS"); + RETURN_THROWS(); + } + mode = mode_in; + mode_p = &mode; + break; + default: + zend_argument_value_error(ERROR_ARG_POS(2), "must be one of " +#if MYSQL_VERSION_ID >= 50107 + "MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH, " +#endif + "MYSQLI_STMT_ATTR_PREFETCH_ROWS, or STMT_ATTR_CURSOR_TYPE"); + RETURN_THROWS(); } + +// TODO Can unify this? #ifndef MYSQLI_USE_MYSQLND if (mysql_stmt_attr_set(stmt->stmt, attr, mode_p)) { #else @@ -2267,11 +2324,20 @@ PHP_FUNCTION(mysqli_stmt_attr_get) if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Ol", &mysql_stmt, mysqli_stmt_class_entry, &attr) == FAILURE) { RETURN_THROWS(); } + MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_VALID); if ((rc = mysql_stmt_attr_get(stmt->stmt, attr, &value))) { - RETURN_FALSE; - } + /* Success corresponds to 0 return value and a non-zero value + * should only happen if the attr/option is unknown */ + zend_argument_value_error(ERROR_ARG_POS(2), "must be one of " +#if MYSQL_VERSION_ID >= 50107 + "MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH, " +#endif + "MYSQLI_STMT_ATTR_PREFETCH_ROWS, or STMT_ATTR_CURSOR_TYPE"); + RETURN_THROWS(); + } + #if MYSQL_VERSION_ID >= 50107 if (attr == STMT_ATTR_UPDATE_MAX_LENGTH) diff --git a/ext/mysqli/mysqli_arginfo.h b/ext/mysqli/mysqli_arginfo.h index 7d7c69e943919..15daa38426a18 100644 --- a/ext/mysqli/mysqli_arginfo.h +++ b/ext/mysqli/mysqli_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: a8626c7c42e4d117b08df7f42a7523f60f357b82 */ + * Stub hash: beb821b6e0b26f798d88f7b726a39084d856251f */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_mysqli_affected_rows, 0, 1, MAY_BE_LONG|MAY_BE_STRING) ZEND_ARG_OBJ_INFO(0, mysql_link, mysqli, 0) @@ -233,7 +233,7 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_mysqli_query, 0, 2, mysqli_result, MAY_BE_BOOL) ZEND_ARG_OBJ_INFO(0, mysqli_link, mysqli, 0) ZEND_ARG_TYPE_INFO(0, query, IS_STRING, 0) - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, resultmode, IS_LONG, 0, "MYSQLI_STORE_RESULT") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, result_mode, IS_LONG, 0, "MYSQLI_STORE_RESULT") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_mysqli_real_connect, 0, 1, _IS_BOOL, 0) @@ -285,7 +285,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_mysqli_stmt_affected_rows, 0, 1, ZEND_ARG_OBJ_INFO(0, mysql_stmt, mysqli_stmt, 0) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_mysqli_stmt_attr_get, 0, 2, MAY_BE_LONG|MAY_BE_FALSE) +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_mysqli_stmt_attr_get, 0, 2, IS_LONG, 0) ZEND_ARG_OBJ_INFO(0, mysql_stmt, mysqli_stmt, 0) ZEND_ARG_TYPE_INFO(0, attr, IS_LONG, 0) ZEND_END_ARG_INFO() @@ -309,7 +309,7 @@ ZEND_END_ARG_INFO() #define arginfo_mysqli_stmt_close arginfo_mysqli_stmt_execute -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_mysqli_stmt_data_seek, 0, 2, _IS_BOOL, 1) +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_mysqli_stmt_data_seek, 0, 2, IS_VOID, 0) ZEND_ARG_OBJ_INFO(0, mysql_stmt, mysqli_stmt, 0) ZEND_ARG_TYPE_INFO(0, offset, IS_LONG, 0) ZEND_END_ARG_INFO() @@ -502,7 +502,7 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_class_mysqli_query, 0, 0, 1) ZEND_ARG_TYPE_INFO(0, query, IS_STRING, 0) - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, resultmode, IS_LONG, 0, "MYSQLI_STORE_RESULT") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, result_mode, IS_LONG, 0, "MYSQLI_STORE_RESULT") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_class_mysqli_real_connect, 0, 0, 0) @@ -576,7 +576,7 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_class_mysqli_result___construct, 0, 0, 1) ZEND_ARG_TYPE_INFO(0, mysqli_link, IS_OBJECT, 0) - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, resmode, IS_LONG, 0, "MYSQLI_STORE_RESULT") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, result_mode, IS_LONG, 0, "MYSQLI_STORE_RESULT") ZEND_END_ARG_INFO() #define arginfo_class_mysqli_result_close arginfo_class_mysqli_character_set_name diff --git a/ext/mysqli/mysqli_nonapi.c b/ext/mysqli/mysqli_nonapi.c index 9b675bb526326..394afc7ccc993 100644 --- a/ext/mysqli/mysqli_nonapi.c +++ b/ext/mysqli/mysqli_nonapi.c @@ -28,6 +28,7 @@ #include "zend_smart_str.h" #include "php_mysqli_structs.h" #include "mysqli_priv.h" +#define ERROR_ARG_POS(arg_num) (getThis() ? (arg_num-1) : (arg_num)) #define SAFE_STR(a) ((a)?a:"") @@ -435,9 +436,9 @@ PHP_FUNCTION(mysqli_fetch_all) MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, mysql_result, "mysqli_result", MYSQLI_STATUS_VALID); if (!mode || (mode & ~MYSQLND_FETCH_BOTH)) { - php_error_docref(NULL, E_WARNING, "Mode can be only MYSQLI_FETCH_NUM, " - "MYSQLI_FETCH_ASSOC or MYSQLI_FETCH_BOTH"); - RETURN_FALSE; + zend_argument_value_error(ERROR_ARG_POS(2), "must be one of MYSQLI_FETCH_NUM, " + "MYSQLI_FETCH_ASSOC, or MYSQLI_FETCH_BOTH"); + RETURN_THROWS(); } mysqlnd_fetch_all(result, mode, return_value); @@ -631,16 +632,18 @@ PHP_FUNCTION(mysqli_query) } if (!query_len) { - php_error_docref(NULL, E_WARNING, "Empty query"); - RETURN_FALSE; + zend_argument_value_error(ERROR_ARG_POS(2), "cannot be empty"); + RETURN_THROWS(); } -#ifdef MYSQLI_USE_MYSQLND - if ((resultmode & ~MYSQLI_ASYNC) != MYSQLI_USE_RESULT && (resultmode & ~(MYSQLI_ASYNC | MYSQLI_STORE_RESULT_COPY_DATA)) != MYSQLI_STORE_RESULT) { -#else - if ((resultmode & ~MYSQLI_ASYNC) != MYSQLI_USE_RESULT && (resultmode & ~MYSQLI_ASYNC) != MYSQLI_STORE_RESULT) { -#endif - php_error_docref(NULL, E_WARNING, "Invalid value for resultmode"); - RETURN_FALSE; + if ((resultmode & ~MYSQLI_ASYNC) != MYSQLI_USE_RESULT && + MYSQLI_STORE_RESULT != (resultmode & ~(MYSQLI_ASYNC | MYSQLI_STORE_RESULT_COPY_DATA)) + ) { + zend_argument_value_error(ERROR_ARG_POS(3), "must be either MYSQLI_USE_RESULT, or MYSQLI_STORE_RESULT" + #ifdef MYSQLI_USE_MYSQLND + " with MYSQLI_ASYNC as an optional bitmask flag" + #endif + ); + RETURN_THROWS(); } MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID); @@ -722,7 +725,8 @@ static int mysqlnd_zval_array_to_mysqlnd_array(zval *in_array, MYSQLND ***out_ar i++; if (Z_TYPE_P(elem) != IS_OBJECT || !instanceof_function(Z_OBJCE_P(elem), mysqli_link_class_entry)) { - php_error_docref(NULL, E_WARNING, "Parameter %d not a mysqli object", i); + zend_argument_type_error(i, "must be an instance of mysqli, %s given", zend_zval_type_name(elem)); + return FAILURE; } else { MY_MYSQL *mysql; MYSQLI_RESOURCE *my_res; @@ -831,11 +835,16 @@ PHP_FUNCTION(mysqli_poll) if (zend_parse_parameters(ZEND_NUM_ARGS(), "a!a!al|l", &r_array, &e_array, &dont_poll_array, &sec, &usec) == FAILURE) { RETURN_THROWS(); } - if (sec < 0 || usec < 0) { - php_error_docref(NULL, E_WARNING, "Negative values passed for sec and/or usec"); - RETURN_FALSE; + if (sec < 0) { + zend_argument_value_error(4, "must be greater than or equal to 0"); + RETURN_THROWS(); + } + if (usec < 0) { + zend_argument_value_error(5, "must be greater than or equal to 0"); + RETURN_THROWS(); } + // TODO Error promotion if (!r_array && !e_array) { php_error_docref(NULL, E_WARNING, "No stream arrays were passed"); RETURN_FALSE; @@ -1152,22 +1161,18 @@ PHP_FUNCTION(mysqli_begin_transaction) zend_long flags = TRANS_START_NO_OPT; char * name = NULL; size_t name_len = -1; - zend_bool err = FALSE; if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O|ls!", &mysql_link, mysqli_link_class_entry, &flags, &name, &name_len) == FAILURE) { RETURN_THROWS(); } MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID); if (flags < 0) { - php_error_docref(NULL, E_WARNING, "Invalid value for parameter flags (" ZEND_LONG_FMT ")", flags); - err = TRUE; + zend_argument_value_error(ERROR_ARG_POS(2), "must be one of the MYSQLI_TRANS_* constants"); + RETURN_THROWS(); } if (!name_len) { - php_error_docref(NULL, E_WARNING, "Savepoint name cannot be empty"); - err = TRUE; - } - if (TRUE == err) { - RETURN_FALSE; + zend_argument_value_error(ERROR_ARG_POS(3), "cannot be empty"); + RETURN_THROWS(); } #ifndef MYSQLI_USE_MYSQLND @@ -1203,15 +1208,15 @@ PHP_FUNCTION(mysqli_savepoint) MY_MYSQL *mysql; zval *mysql_link; char * name = NULL; - size_t name_len = -1; + size_t name_len; if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Os", &mysql_link, mysqli_link_class_entry, &name, &name_len) == FAILURE) { RETURN_THROWS(); } MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID); - if (!name || !name_len) { - php_error_docref(NULL, E_WARNING, "Savepoint name cannot be empty"); - RETURN_FALSE; + if (name_len == 0) { + zend_argument_value_error(ERROR_ARG_POS(2), "cannot be empty"); + RETURN_THROWS(); } #ifndef MYSQLI_USE_MYSQLND @@ -1231,15 +1236,15 @@ PHP_FUNCTION(mysqli_release_savepoint) MY_MYSQL *mysql; zval *mysql_link; char * name = NULL; - size_t name_len = -1; + size_t name_len; if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Os", &mysql_link, mysqli_link_class_entry, &name, &name_len) == FAILURE) { RETURN_THROWS(); } MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID); - if (!name || !name_len) { - php_error_docref(NULL, E_WARNING, "Savepoint name cannot be empty"); - RETURN_FALSE; + if (name_len == 0) { + zend_argument_value_error(ERROR_ARG_POS(2), "cannot be empty"); + RETURN_THROWS(); } #ifndef MYSQLI_USE_MYSQLND if (mysqli_savepoint_libmysql(mysql->mysql, name, TRUE)) { diff --git a/ext/mysqli/mysqli_result_iterator.c b/ext/mysqli/mysqli_result_iterator.c index 1388937816173..7aec918bbd0d6 100644 --- a/ext/mysqli/mysqli_result_iterator.c +++ b/ext/mysqli/mysqli_result_iterator.c @@ -45,8 +45,10 @@ zend_object_iterator *php_mysqli_result_get_iterator(zend_class_entry *ce, zval php_mysqli_result_iterator *iterator; if (by_ref) { - zend_error(E_ERROR, "An iterator cannot be used with foreach by reference"); + zend_throw_error(NULL, "An iterator cannot be used with foreach by reference"); + return NULL; } + iterator = ecalloc(1, sizeof(php_mysqli_result_iterator)); zend_iterator_init(&iterator->intern); diff --git a/ext/mysqli/tests/bug55582.phpt b/ext/mysqli/tests/bug55582.phpt index 86626c0279f79..817f7eecfe557 100644 --- a/ext/mysqli/tests/bug55582.phpt +++ b/ext/mysqli/tests/bug55582.phpt @@ -15,27 +15,31 @@ require_once("connect.inc"); var_dump($link->real_query("SELECT 1")); $res = $link->use_result(); - var_dump(mysqli_num_rows($res)); + try { + var_dump(mysqli_num_rows($res)); + } catch (\Error $e) { + echo $e->getMessage() . \PHP_EOL; + } var_dump($res->fetch_assoc()); - var_dump(mysqli_num_rows($res)); + try { + var_dump(mysqli_num_rows($res)); + } catch (\Error $e) { + echo $e->getMessage() . \PHP_EOL; + } var_dump($res->fetch_assoc()); var_dump(mysqli_num_rows($res)); $link->close(); echo "done\n"; ?> ---EXPECTF-- +--EXPECT-- bool(true) - -Warning: mysqli_num_rows(): Function cannot be used with MYSQL_USE_RESULT in %s on line %d -int(0) +mysqli_num_rows() cannot be used with MYSQLI_USE_RESULT array(1) { [1]=> string(1) "1" } - -Warning: mysqli_num_rows(): Function cannot be used with MYSQL_USE_RESULT in %s on line %d -int(0) +mysqli_num_rows() cannot be used with MYSQLI_USE_RESULT NULL int(1) done diff --git a/ext/mysqli/tests/bug74595.phpt b/ext/mysqli/tests/bug74595.phpt deleted file mode 100644 index 9d017eaa82b51..0000000000000 --- a/ext/mysqli/tests/bug74595.phpt +++ /dev/null @@ -1,25 +0,0 @@ ---TEST-- -Bug #74595 (ReflectionMethod::getParameters returns incorrect number of parameters) ---SKIPIF-- - ---FILE-- -getMethod('query'); -var_dump($method->getParameters()); -?> ---EXPECTF-- -array(2) { - [0]=> - object(ReflectionParameter)#%d (1) { - ["name"]=> - string(5) "query" - } - [1]=> - object(ReflectionParameter)#%d (1) { - ["name"]=> - string(10) "resultmode" - } -} diff --git a/ext/mysqli/tests/connect.inc b/ext/mysqli/tests/connect.inc index 43bb3c4153f83..6bf393a2de665 100644 --- a/ext/mysqli/tests/connect.inc +++ b/ext/mysqli/tests/connect.inc @@ -8,7 +8,7 @@ $driver = new mysqli_driver; - $host = getenv("MYSQL_TEST_HOST") ?: "localhost"; + $host = getenv("MYSQL_TEST_HOST") ?: "127.0.0.1"; $port = getenv("MYSQL_TEST_PORT") ?: 3306; $user = getenv("MYSQL_TEST_USER") ?: "root"; $passwd = getenv("MYSQL_TEST_PASSWD") ?: ""; diff --git a/ext/mysqli/tests/mysqli_begin_transaction.phpt b/ext/mysqli/tests/mysqli_begin_transaction.phpt index bed9b1bf61321..7a9107b7e6917 100644 --- a/ext/mysqli/tests/mysqli_begin_transaction.phpt +++ b/ext/mysqli/tests/mysqli_begin_transaction.phpt @@ -76,8 +76,11 @@ if (!have_innodb($link)) } } - if (!mysqli_begin_transaction($link, -1)) { - printf("[019] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + try { + mysqli_begin_transaction($link, -1); + printf("[019] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; } if (mysqli_get_server_version($link) >= 50605) { @@ -96,9 +99,7 @@ if (!have_innodb($link)) ---EXPECTF-- +--EXPECT-- NULL - -Warning: mysqli_begin_transaction(): Invalid value for parameter flags (-1) in %s on line %d -[019] [%d]%A +mysqli_begin_transaction(): Argument #2 ($flags) must be one of the MYSQLI_TRANS_* constants done! diff --git a/ext/mysqli/tests/mysqli_data_seek.phpt b/ext/mysqli/tests/mysqli_data_seek.phpt index 53c8b8354d5b2..2b477af3fd4b1 100644 --- a/ext/mysqli/tests/mysqli_data_seek.phpt +++ b/ext/mysqli/tests/mysqli_data_seek.phpt @@ -31,16 +31,22 @@ require_once('skipifconnectfailure.inc'); if (false !== ($tmp = mysqli_data_seek($res, 4))) printf("[009] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); - if (false !== ($tmp = mysqli_data_seek($res, -1))) - printf("[010] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + try { + mysqli_data_seek($res, -1); + } catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; + } mysqli_free_result($res); if (!$res = mysqli_query($link, 'SELECT * FROM test ORDER BY id', MYSQLI_USE_RESULT)) printf("[011] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); - if (false !== ($tmp = mysqli_data_seek($res, 3))) - printf("[012] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + try { + var_dump(mysqli_data_seek($res, 3)); + } catch (\Error $e) { + echo $e->getMessage() . \PHP_EOL; + } mysqli_free_result($res); @@ -58,7 +64,8 @@ require_once('skipifconnectfailure.inc'); ---EXPECTF-- -Warning: mysqli_data_seek(): Function cannot be used with MYSQL_USE_RESULT in %s on line %d +--EXPECT-- +mysqli_data_seek(): Argument #2 ($offset) must be greater than or equal to 0 +mysqli_data_seek() cannot be used with MYSQLI_USE_RESULT mysqli_result object is already closed done! diff --git a/ext/mysqli/tests/mysqli_data_seek_oo.phpt b/ext/mysqli/tests/mysqli_data_seek_oo.phpt index 0d1ee8b79f6e5..ccbf86542ac59 100644 --- a/ext/mysqli/tests/mysqli_data_seek_oo.phpt +++ b/ext/mysqli/tests/mysqli_data_seek_oo.phpt @@ -43,16 +43,22 @@ require_once('skipifconnectfailure.inc'); if (false !== ($tmp = $res->data_seek(4))) printf("[011] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); - if (false !== ($tmp = $res->data_seek(-1))) - printf("[012] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + try { + $res->data_seek(-1); + } catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; + } $res->free_result(); if (!$res = $mysqli->query('SELECT * FROM test ORDER BY id', MYSQLI_USE_RESULT)) printf("[013] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); - if (false !== ($tmp = $res->data_seek(3))) - printf("[014] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + try { + var_dump($res->data_seek(3)); + } catch (\Error $e) { + echo $e->getMessage() . \PHP_EOL; + } $res->free_result(); @@ -69,9 +75,9 @@ require_once('skipifconnectfailure.inc'); ---EXPECTF-- +--EXPECT-- mysqli_result object is already closed - -Warning: mysqli_result::data_seek(): Function cannot be used with MYSQL_USE_RESULT in %s on line %d +mysqli_result::data_seek(): Argument #1 ($offset) must be greater than or equal to 0 +mysqli_result::data_seek() cannot be used with MYSQLI_USE_RESULT mysqli_result object is already closed done! diff --git a/ext/mysqli/tests/mysqli_fetch_all.phpt b/ext/mysqli/tests/mysqli_fetch_all.phpt index 76c6b971f41a9..ab48821498e0d 100644 --- a/ext/mysqli/tests/mysqli_fetch_all.phpt +++ b/ext/mysqli/tests/mysqli_fetch_all.phpt @@ -71,12 +71,12 @@ if (!function_exists('mysqli_fetch_all')) exit(1); } - do { - $illegal_mode = mt_rand(-10000, 10000); - } while (in_array($illegal_mode, array(MYSQLI_ASSOC, MYSQLI_NUM, MYSQLI_BOTH))); - // NOTE: for BC reasons with ext/mysql, ext/mysqli accepts invalid result modes. - - mysqli_fetch_all($res, $illegal_mode); + // Illegal mode + try { + mysqli_fetch_all($res, -10); + } catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; + } mysqli_free_result($res); function func_mysqli_fetch_all($link, $engine, $sql_type, $sql_value, $php_value, $offset, $regexp_comparison = NULL) { @@ -315,7 +315,7 @@ if (!function_exists('mysqli_fetch_all')) ---EXPECTF-- +--EXPECT-- [005] array(2) { [0]=> @@ -443,7 +443,6 @@ array(1) { string(1) "1" } } - -Warning: mysqli_fetch_all(): Mode can be only MYSQLI_FETCH_NUM, MYSQLI_FETCH_ASSOC or MYSQLI_FETCH_BOTH in %s on line %d +mysqli_fetch_all(): Argument #2 ($mode) must be one of MYSQLI_FETCH_NUM, MYSQLI_FETCH_ASSOC, or MYSQLI_FETCH_BOTH mysqli_result object is already closed done! diff --git a/ext/mysqli/tests/mysqli_fetch_all_oo.phpt b/ext/mysqli/tests/mysqli_fetch_all_oo.phpt index 992a61a348bc8..2b34670756583 100644 --- a/ext/mysqli/tests/mysqli_fetch_all_oo.phpt +++ b/ext/mysqli/tests/mysqli_fetch_all_oo.phpt @@ -81,14 +81,14 @@ if (!function_exists('mysqli_fetch_all')) exit(1); } - do { - $illegal_mode = mt_rand(-10000, 10000); - } while (in_array($illegal_mode, array(MYSQLI_ASSOC, MYSQLI_NUM, MYSQLI_BOTH))); - // NOTE: for BC reasons with ext/mysql, ext/mysqli accepts invalid result modes. - $tmp = $res->fetch_all($illegal_mode); - if (false !== $tmp) - printf("[019] Expecting boolean/false although, got %s/%s. [%d] %s\n", - gettype($tmp), $tmp, $mysqli->errno, $mysqli->error); + try { + $tmp = $res->fetch_all(-10); + if (false !== $tmp) + printf("[019] Expecting boolean/false although, got %s/%s. [%d] %s\n", + gettype($tmp), $tmp, $mysqli->errno, $mysqli->error); + } catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; + } $res->free_result(); @@ -436,7 +436,6 @@ array(1) { string(1) "1" } } - -Warning: mysqli_result::fetch_all(): Mode can be only MYSQLI_FETCH_NUM, MYSQLI_FETCH_ASSOC or MYSQLI_FETCH_BOTH in %s on line %d +mysqli_result::fetch_all(): Argument #1 ($result_type) must be one of MYSQLI_FETCH_NUM, MYSQLI_FETCH_ASSOC, or MYSQLI_FETCH_BOTH mysqli_result object is already closed done! diff --git a/ext/mysqli/tests/mysqli_fetch_field_direct.phpt b/ext/mysqli/tests/mysqli_fetch_field_direct.phpt index 0afe6e4626af7..8b57cca094c81 100644 --- a/ext/mysqli/tests/mysqli_fetch_field_direct.phpt +++ b/ext/mysqli/tests/mysqli_fetch_field_direct.phpt @@ -16,9 +16,18 @@ require_once('skipifconnectfailure.inc'); printf("[004] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); } - var_dump(mysqli_fetch_field_direct($res, -1)); + try { + var_dump(mysqli_fetch_field_direct($res, -1)); + } catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; + } var_dump(mysqli_fetch_field_direct($res, 0)); - var_dump(mysqli_fetch_field_direct($res, 2)); + + try { + var_dump(mysqli_fetch_field_direct($res, 2)); + } catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; + } mysqli_free_result($res); @@ -36,8 +45,7 @@ require_once('skipifconnectfailure.inc'); require_once("clean_table.inc"); ?> --EXPECTF-- -Warning: mysqli_fetch_field_direct(): Field offset is invalid for resultset in %s on line %d -bool(false) +mysqli_fetch_field_direct(): Argument #2 ($offset) must be greater than or equal to 0 object(stdClass)#%d (13) { ["name"]=> string(2) "ID" @@ -66,8 +74,6 @@ object(stdClass)#%d (13) { ["decimals"]=> int(%d) } - -Warning: mysqli_fetch_field_direct(): Field offset is invalid for resultset in %s on line %d -bool(false) +mysqli_fetch_field_direct(): Argument #2 ($offset) must be less than the number of fields for this result set mysqli_result object is already closed done! diff --git a/ext/mysqli/tests/mysqli_fetch_field_direct_oo.phpt b/ext/mysqli/tests/mysqli_fetch_field_direct_oo.phpt index 33806f1c553f0..5dedefcdab1b9 100644 --- a/ext/mysqli/tests/mysqli_fetch_field_direct_oo.phpt +++ b/ext/mysqli/tests/mysqli_fetch_field_direct_oo.phpt @@ -27,9 +27,19 @@ require_once('skipifconnectfailure.inc'); printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); } - var_dump($res->fetch_field_direct(-1)); + try { + var_dump($res->fetch_field_direct(-1)); + } catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; + } + var_dump($res->fetch_field_direct(0)); - var_dump($res->fetch_field_direct(2)); + + try { + var_dump($res->fetch_field_direct(2)); + } catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; + } $res->free_result(); @@ -48,9 +58,7 @@ require_once('skipifconnectfailure.inc'); ?> --EXPECTF-- mysqli object is not fully initialized - -Warning: mysqli_result::fetch_field_direct(): Field offset is invalid for resultset in %s on line %d -bool(false) +mysqli_result::fetch_field_direct(): Argument #1 ($field_nr) must be greater than or equal to 0 object(stdClass)#%d (13) { ["name"]=> string(2) "ID" @@ -79,8 +87,6 @@ object(stdClass)#%d (13) { ["decimals"]=> int(%d) } - -Warning: mysqli_result::fetch_field_direct(): Field offset is invalid for resultset in %s on line %d -bool(false) +mysqli_result::fetch_field_direct(): Argument #1 ($field_nr) must be less than the number of fields for this result set mysqli_result object is already closed done! diff --git a/ext/mysqli/tests/mysqli_field_seek.phpt b/ext/mysqli/tests/mysqli_field_seek.phpt index 9eb9f0315b071..bcc1e29526c54 100644 --- a/ext/mysqli/tests/mysqli_field_seek.phpt +++ b/ext/mysqli/tests/mysqli_field_seek.phpt @@ -69,7 +69,11 @@ require_once('skipifconnectfailure.inc'); printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); } - var_dump(mysqli_field_seek($res, -1)); + try { + var_dump(mysqli_field_seek($res, -1)); + } catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; + } var_dump(mysqli_fetch_field($res)); var_dump(mysqli_field_seek($res, 0)); var_dump(mysqli_fetch_field($res)); @@ -115,8 +119,7 @@ require_once('skipifconnectfailure.inc'); require_once("clean_table.inc"); ?> --EXPECTF-- -Warning: mysqli_field_seek(): Invalid field offset in %s on line %d -bool(false) +mysqli_field_seek(): Argument #2 ($field_nr) must be greater than or equal to 0 object(stdClass)#%d (13) { ["name"]=> string(2) "id" diff --git a/ext/mysqli/tests/mysqli_field_tell.phpt b/ext/mysqli/tests/mysqli_field_tell.phpt index bf169003aa7e0..e8c344ec956ff 100644 --- a/ext/mysqli/tests/mysqli_field_tell.phpt +++ b/ext/mysqli/tests/mysqli_field_tell.phpt @@ -24,7 +24,11 @@ require_once('skipifconnectfailure.inc'); var_dump(mysqli_field_seek($res, 2)); var_dump(mysqli_field_tell($res)); - var_dump(mysqli_field_seek($res, -1)); + try { + var_dump(mysqli_field_seek($res, -1)); + } catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; + } var_dump(mysqli_field_tell($res)); var_dump(mysqli_field_seek($res, 0)); @@ -85,9 +89,7 @@ int(1) Warning: mysqli_field_seek(): Invalid field offset in %s on line %d bool(false) int(1) - -Warning: mysqli_field_seek(): Invalid field offset in %s on line %d -bool(false) +mysqli_field_seek(): Argument #2 ($field_nr) must be greater than or equal to 0 int(1) bool(true) int(0) diff --git a/ext/mysqli/tests/mysqli_kill.phpt b/ext/mysqli/tests/mysqli_kill.phpt index 943e213a81a36..e4be618fc7fa6 100644 --- a/ext/mysqli/tests/mysqli_kill.phpt +++ b/ext/mysqli/tests/mysqli_kill.phpt @@ -13,8 +13,11 @@ require_once('skipifconnectfailure.inc'); require('table.inc'); // Zend will cast the NULL to 0 - if (!is_bool($tmp = mysqli_kill($link, null))) - printf("[003] Expecting boolean/any, got %s/%s\n", gettype($tmp), $tmp); + try { + mysqli_kill($link, null); + } catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; + } if (!$thread_id = mysqli_thread_id($link)) printf("[004] Cannot determine thread id, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); @@ -46,7 +49,11 @@ require_once('skipifconnectfailure.inc'); if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) printf("[010] Cannot connect, [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); - mysqli_kill($link, -1); + try { + mysqli_kill($link, -1); + } catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; + } if ((!$res = mysqli_query($link, "SELECT id FROM test LIMIT 1")) || (!$tmp = mysqli_fetch_assoc($res))) { printf("[011] Connection should not be gone, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); @@ -58,7 +65,12 @@ require_once('skipifconnectfailure.inc'); if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) printf("[012] Cannot connect, [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); - mysqli_change_user($link, "This might work if you accept anonymous users in your setup", "password", $db); mysqli_kill($link, -1); + mysqli_change_user($link, "This might work if you accept anonymous users in your setup", "password", $db); + try { + mysqli_kill($link, -1); + } catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; + } mysqli_close($link); @@ -69,7 +81,7 @@ require_once('skipifconnectfailure.inc'); require_once("clean_table.inc"); ?> --EXPECTF-- -Warning: mysqli_kill(): processid should have positive value in %s on line %d +mysqli_kill(): Argument #2 ($connection_id) must be greater than 0 string(%d) "%s" bool(false) object(mysqli)#%d (%d) { @@ -120,12 +132,10 @@ object(mysqli)#%d (%d) { ["warning_count"]=> int(0) } - -Warning: mysqli_kill(): processid should have positive value in %s on line %d +mysqli_kill(): Argument #2 ($connection_id) must be greater than 0 array(1) { ["id"]=> string(1) "1" } - -Warning: mysqli_kill(): processid should have positive value in %s on line %d +mysqli_kill(): Argument #2 ($connection_id) must be greater than 0 done! diff --git a/ext/mysqli/tests/mysqli_num_rows.phpt b/ext/mysqli/tests/mysqli_num_rows.phpt index 3266f37dce172..4d09c256823a7 100644 --- a/ext/mysqli/tests/mysqli_num_rows.phpt +++ b/ext/mysqli/tests/mysqli_num_rows.phpt @@ -56,8 +56,11 @@ require_once('skipifconnectfailure.inc'); if ($res = mysqli_query($link, 'SELECT id FROM test', MYSQLI_USE_RESULT)) { $row = mysqli_fetch_row($res); - if (0 !== ($tmp = mysqli_num_rows($res))) - printf("[031] Expecting int/0, got %s/%d\n", gettype($tmp), $tmp); + try { + var_dump(mysqli_num_rows($res)); + } catch (\Error $e) { + echo $e->getMessage() . \PHP_EOL; + } mysqli_free_result($res); } else { @@ -71,12 +74,11 @@ require_once('skipifconnectfailure.inc'); ---EXPECTF-- +--EXPECT-- mysqli_result object is already closed mysqli_result object is already closed mysqli_result object is already closed mysqli_result object is already closed run_tests.php don't fool me with your 'ungreedy' expression '.+?'! - -Warning: mysqli_num_rows(): Function cannot be used with MYSQL_USE_RESULT in %s on line %d +mysqli_num_rows() cannot be used with MYSQLI_USE_RESULT done! diff --git a/ext/mysqli/tests/mysqli_poll.phpt b/ext/mysqli/tests/mysqli_poll.phpt index 97b1a7e61ad77..cc3cc36b2f8fb 100644 --- a/ext/mysqli/tests/mysqli_poll.phpt +++ b/ext/mysqli/tests/mysqli_poll.phpt @@ -30,12 +30,16 @@ if (!$IS_MYSQLND) printf("[009] Expecting int/0 got %s/%s\n", gettype($tmp), var_export($tmp, true)); $read = $error = $reject = array($link); - if (false !== ($tmp = (mysqli_poll($read, $error, $reject, -1, 1)))) - printf("[010] Expecting false got %s/%s\n", gettype($tmp), var_export($tmp, true)); - - $read = $error = $reject = array($link); - if (false !== ($tmp = (mysqli_poll($read, $error, $reject, 0, -1)))) - printf("[011] Expecting false got %s/%s\n", gettype($tmp), var_export($tmp, true)); + try { + mysqli_poll($read, $error, $reject, -1, 1); + } catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; + } + try { + mysqli_poll($read, $error, $reject, 0, -1); + } catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; + } function poll_async($offset, $link, $links, $errors, $reject, $exp_ready, $use_oo_syntax) { @@ -111,9 +115,8 @@ if (!$IS_MYSQLND) print "done!"; ?> --EXPECTF-- -Warning: mysqli_poll(): Negative values passed for sec and/or usec in %s on line %d - -Warning: mysqli_poll(): Negative values passed for sec and/or usec in %s on line %d +mysqli_poll(): Argument #4 ($sec) must be greater than or equal to 0 +mysqli_poll(): Argument #5 ($usec) must be greater than or equal to 0 [012 + 6] Rejecting thread %d: 0/ [013 + 6] Rejecting thread %d: 0/ [014 + 6] Rejecting thread %d: 0/ diff --git a/ext/mysqli/tests/mysqli_query.phpt b/ext/mysqli/tests/mysqli_query.phpt index ba159cf9852ed..daac374cf7976 100644 --- a/ext/mysqli/tests/mysqli_query.phpt +++ b/ext/mysqli/tests/mysqli_query.phpt @@ -12,8 +12,11 @@ require_once('skipifconnectfailure.inc'); require('table.inc'); - if (false !== ($tmp = @mysqli_query($link, ''))) - printf("[002a] Expecting boolean/false got %s/%s\n", gettype($tmp), $tmp); + try { + mysqli_query($link, ''); + } catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; + } if (false !== ($tmp = mysqli_query($link, 'THIS IS NOT SQL'))) printf("[004] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); @@ -82,11 +85,11 @@ require_once('skipifconnectfailure.inc'); printf("[012] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); mysqli_free_result($res); - if (false !== ($res = @mysqli_query($link, "SELECT id FROM test ORDER BY id", 1234))) - printf("[013] Invalid mode should return false got %s/%s, [%d] %s\n", - gettype($res), (is_object($res)) ? 'object' : $res, - mysqli_errno($link), mysqli_error($link)); - + try { + mysqli_query($link, "SELECT id FROM test ORDER BY id", 1234); + } catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; + } mysqli_close($link); @@ -113,6 +116,7 @@ if (!mysqli_query($link, "DROP TABLE IF EXISTS test")) mysqli_close($link); ?> --EXPECT-- +mysqli_query(): Argument #2 ($query) cannot be empty array(1) { ["valid"]=> string(30) "this is sql but with semicolon" @@ -122,5 +126,6 @@ array(1) { string(1) "a" } string(1) "a" +mysqli_query(): Argument #3 ($result_mode) must be either MYSQLI_USE_RESULT, or MYSQLI_STORE_RESULT with MYSQLI_ASYNC as an optional bitmask flag mysqli object is already closed done! diff --git a/ext/mysqli/tests/mysqli_release_savepoint.phpt b/ext/mysqli/tests/mysqli_release_savepoint.phpt index 92f85c8b7576c..fa46366e7cac8 100644 --- a/ext/mysqli/tests/mysqli_release_savepoint.phpt +++ b/ext/mysqli/tests/mysqli_release_savepoint.phpt @@ -23,8 +23,11 @@ if (!have_innodb($link)) printf("[003] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", $host, $user, $db, $port, $socket); - if (false !== ($tmp = mysqli_release_savepoint($link, ''))) - printf("[006] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + try { + mysqli_release_savepoint($link, ''); + } catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; + } if (!mysqli_query($link, 'DROP TABLE IF EXISTS test')) printf("[007] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); @@ -61,8 +64,8 @@ if (!have_innodb($link)) ---EXPECTF-- -Warning: mysqli_release_savepoint(): Savepoint name cannot be empty in %s on line %d +--EXPECT-- +mysqli_release_savepoint(): Argument #2 ($name) cannot be empty array(1) { ["id"]=> string(1) "1" diff --git a/ext/mysqli/tests/mysqli_report.phpt b/ext/mysqli/tests/mysqli_report.phpt index 17baea0f66f95..6f5733513ca3b 100644 --- a/ext/mysqli/tests/mysqli_report.phpt +++ b/ext/mysqli/tests/mysqli_report.phpt @@ -37,7 +37,11 @@ require_once('skipifconnectfailure.inc'); mysqli_multi_query($link, "BAR; FOO;"); mysqli_query($link, "FOO"); - mysqli_kill($link, -1); + try { + mysqli_kill($link, -1); + } catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; + } // mysqli_ping() cannot be tested, because one would need to cause an error inside the C function to test it mysqli_prepare($link, "FOO"); @@ -53,7 +57,11 @@ require_once('skipifconnectfailure.inc'); mysqli_multi_query($link, "BAR; FOO;"); mysqli_query($link, "FOO"); - mysqli_kill($link, -1); + try { + mysqli_kill($link, -1); + } catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; + } mysqli_prepare($link, "FOO"); mysqli_real_query($link, "FOO"); mysqli_select_db($link, "Oh lord, let this be an unknown database name"); @@ -280,14 +288,12 @@ require_once('skipifconnectfailure.inc'); Warning: mysqli_multi_query(): (%d/%d): You have an error in your SQL syntax; check the manual that corresponds to your %s server version for the right syntax to use near 'BAR; FOO' at line 1 in %s on line %d Warning: mysqli_query(): (%d/%d): You have an error in your SQL syntax; check the manual that corresponds to your %s server version for the right syntax to use near 'FOO' at line 1 in %s on line %d - -Warning: mysqli_kill(): processid should have positive value in %s on line %d +mysqli_kill(): Argument #2 ($connection_id) must be greater than 0 Warning: mysqli_prepare(): (%d/%d): You have an error in your SQL syntax; check the manual that corresponds to your %s server version for the right syntax to use near 'FOO' at line 1 in %s on line %d Warning: mysqli_real_query(): (%d/%d): You have an error in your SQL syntax; check the manual that corresponds to your %s server version for the right syntax to use near 'FOO' at line 1 in %s on line %d - -Warning: mysqli_kill(): processid should have positive value in %s on line %d +mysqli_kill(): Argument #2 ($connection_id) must be greater than 0 Warning: mysqli_stmt_prepare(): (%d/%d): You have an error in your SQL syntax; check the manual that corresponds to your %s server version for the right syntax to use near 'FOO' at line 1 in %s on line %d [013] Access denied for user '%s'@'%s' (using password: YES) diff --git a/ext/mysqli/tests/mysqli_result_invalid_mode.phpt b/ext/mysqli/tests/mysqli_result_invalid_mode.phpt index 9f902920dbf44..374fccfa61e81 100644 --- a/ext/mysqli/tests/mysqli_result_invalid_mode.phpt +++ b/ext/mysqli/tests/mysqli_result_invalid_mode.phpt @@ -12,19 +12,19 @@ require_once('skipifconnectfailure.inc'); require('table.inc'); $valid = array(MYSQLI_STORE_RESULT, MYSQLI_USE_RESULT); - do { - $mode = mt_rand(-1000, 1000); - } while (in_array($mode, $valid)); - - if (!is_object($res = new mysqli_result($link, $mode))) - printf("[001] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); - - print "done!"; + $invalidModes = [-1, 152]; + foreach ($invalidModes as $mode) { + try { + new mysqli_result($link, $mode); + } catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; + } + } ?> --CLEAN-- ---EXPECTF-- -Warning: mysqli_result::__construct(): Invalid value for resultmode in %s on line %d -done! +--EXPECT-- +mysqli_result::__construct(): Argument #2 ($result_mode) must be either MYSQLI_STORE_RESULT or MYSQLI_USE_RESULT +mysqli_result::__construct(): Argument #2 ($result_mode) must be either MYSQLI_STORE_RESULT or MYSQLI_USE_RESULT diff --git a/ext/mysqli/tests/mysqli_savepoint.phpt b/ext/mysqli/tests/mysqli_savepoint.phpt index 524d21e5c3eb4..10016256671d3 100644 --- a/ext/mysqli/tests/mysqli_savepoint.phpt +++ b/ext/mysqli/tests/mysqli_savepoint.phpt @@ -21,8 +21,11 @@ if (!have_innodb($link)) printf("[003] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", $host, $user, $db, $port, $socket); - if (false !== ($tmp = mysqli_savepoint($link, ''))) - printf("[006] Expecting false, got %s/%s\n", gettype($tmp), $tmp); + try { + mysqli_savepoint($link, ''); + } catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; + } if (!mysqli_query($link, 'DROP TABLE IF EXISTS test')) printf("[007] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); @@ -50,6 +53,6 @@ if (!have_innodb($link)) ---EXPECTF-- -Warning: mysqli_savepoint(): Savepoint name cannot be empty in %s on line %d +--EXPECT-- +mysqli_savepoint(): Argument #2 ($name) cannot be empty done! diff --git a/ext/mysqli/tests/mysqli_stmt_attr_get.phpt b/ext/mysqli/tests/mysqli_stmt_attr_get.phpt index 0844a6c8acc7c..6179155e777b1 100644 --- a/ext/mysqli/tests/mysqli_stmt_attr_get.phpt +++ b/ext/mysqli/tests/mysqli_stmt_attr_get.phpt @@ -19,20 +19,17 @@ require_once('skipifconnectfailure.inc'); if ($IS_MYSQLND && mysqli_get_client_version() > 50007) $valid_attr["prefetch_rows"] = MYSQLI_STMT_ATTR_PREFETCH_ROWS; - do { - $invalid_attr = mt_rand(0, 10000); - } while (in_array($invalid_attr, $valid_attr)); - $stmt = mysqli_stmt_init($link); mysqli_stmt_prepare($stmt, 'SELECT * FROM test'); try { - mysqli_stmt_attr_get($stmt, $invalid_attr); - } catch (Error $exception) { - echo $exception->getMessage() . "\n"; + mysqli_stmt_attr_get($stmt, -100); + } catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; } foreach ($valid_attr as $k => $attr) { + /* This can't happen anymore as it only returns int */ if (false === ($tmp = mysqli_stmt_attr_get($stmt, $attr))) { printf("[006] Expecting any type, but not boolean/false, got %s/%s for attribute %s/%s\n", gettype($tmp), $tmp, $k, $attr); @@ -44,7 +41,7 @@ require_once('skipifconnectfailure.inc'); foreach ($valid_attr as $k => $attr) { try { mysqli_stmt_attr_get($stmt, $attr); - } catch (Error $exception) { + } catch (Throwable $exception) { echo $exception->getMessage() . "\n"; } } @@ -57,6 +54,7 @@ require_once('skipifconnectfailure.inc'); require_once("clean_table.inc"); ?> --EXPECT-- +mysqli_stmt_attr_get(): Argument #2 ($attr) must be one of MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH, MYSQLI_STMT_ATTR_PREFETCH_ROWS, or STMT_ATTR_CURSOR_TYPE mysqli_stmt object is already closed mysqli_stmt object is already closed mysqli_stmt object is already closed diff --git a/ext/mysqli/tests/mysqli_stmt_attr_set.phpt b/ext/mysqli/tests/mysqli_stmt_attr_set.phpt index 4fad53cba2fbe..870960e602f9a 100644 --- a/ext/mysqli/tests/mysqli_stmt_attr_set.phpt +++ b/ext/mysqli/tests/mysqli_stmt_attr_set.phpt @@ -28,38 +28,28 @@ require_once("connect.inc"); $stmt = mysqli_stmt_init($link); try { mysqli_stmt_attr_set($stmt, 0, 0); - } catch (Error $exception) { - echo $exception->getMessage() . "\n"; + } catch (\Throwable $e) { + echo get_class($e) . ': ' . $e->getMessage() . PHP_EOL; } $stmt->prepare("SELECT * FROM test"); - - mt_srand(microtime(true)); - - for ($i = -100; $i < 1000; $i++) { - if (in_array($i, $valid_attr)) - continue; - $invalid_attr = $i; - if (false !== ($tmp = @mysqli_stmt_attr_set($stmt, $invalid_attr, 0))) { - printf("[006a] Expecting boolean/false for attribute %d, got %s/%s\n", $invalid_attr, gettype($tmp), $tmp); - } + // Invalid Attribute (2nd argument) + try { + mysqli_stmt_attr_set($stmt, -1, 0); + } catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; } - - for ($i = 0; $i < 2; $i++) { - do { - $invalid_attr = mt_rand(-1 * (min(4294967296, PHP_INT_MAX) + 1), min(4294967296, PHP_INT_MAX)); - } while (in_array($invalid_attr, $valid_attr)); - if (false !== ($tmp = @mysqli_stmt_attr_set($stmt, $invalid_attr, 0))) { - printf("[006b] Expecting boolean/false for attribute %d, got %s/%s\n", $invalid_attr, gettype($tmp), $tmp); - } + // Invalid mode for MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH + try { + $stmt->attr_set(MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH, -1); + } catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; } $stmt->close(); // // MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH // - - // expecting max_length not to be set and be 0 in all cases $stmt = mysqli_stmt_init($link); $stmt->prepare("SELECT label FROM test"); @@ -79,7 +69,7 @@ require_once("connect.inc"); // expecting max_length to _be_ set $stmt = mysqli_stmt_init($link); $stmt->prepare("SELECT label FROM test"); - $stmt->attr_set(MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH, 1); + var_dump($stmt->attr_set(MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH, 1)); $res = $stmt->attr_get(MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH); if ($res !== 1) printf("[007.1] max_length should be 1, got %s\n", $res); @@ -122,21 +112,15 @@ require_once("connect.inc"); if (mysqli_get_client_version() > 50003) { - $cursor_types = array( - MYSQLI_CURSOR_TYPE_NO_CURSOR, - MYSQLI_CURSOR_TYPE_READ_ONLY, - MYSQLI_CURSOR_TYPE_FOR_UPDATE, - MYSQLI_CURSOR_TYPE_SCROLLABLE - ); - do { - $invalid_cursor_type = mt_rand(-1000, 1000); - } while (in_array($invalid_cursor_type, $cursor_types)); - $stmt = mysqli_stmt_init($link); $stmt->prepare("SELECT id, label FROM test"); - if (false !== ($tmp = @$stmt->attr_set(MYSQLI_STMT_ATTR_CURSOR_TYPE, $invalid_cursor_type))) - printf("[010] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + // Invalid cursor type + try { + $stmt->attr_set(MYSQLI_STMT_ATTR_CURSOR_TYPE, -1); + } catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; + } if (false !== ($tmp = $stmt->attr_set(MYSQLI_STMT_ATTR_CURSOR_TYPE, MYSQLI_CURSOR_TYPE_FOR_UPDATE))) printf("[011] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); @@ -209,6 +193,13 @@ require_once("connect.inc"); $stmt = mysqli_stmt_init($link); $stmt->prepare("SELECT id, label FROM test"); + // Invalid prefetch value + try { + $stmt->attr_set(MYSQLI_STMT_ATTR_PREFETCH_ROWS, 0); + } catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; + } + if (true !== ($tmp = $stmt->attr_set(MYSQLI_STMT_ATTR_PREFETCH_ROWS, 1))) printf("[020] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); $stmt->execute(); @@ -262,5 +253,10 @@ require_once("connect.inc"); require_once("clean_table.inc"); ?> --EXPECT-- -mysqli_stmt object is not fully initialized +Error: mysqli_stmt object is not fully initialized +mysqli_stmt_attr_set(): Argument #2 ($attr) must be one of MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH, MYSQLI_STMT_ATTR_PREFETCH_ROWS, or STMT_ATTR_CURSOR_TYPE +mysqli_stmt::attr_set(): Argument #2 ($mode_in) must be 0 or 1 for attribute MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH +bool(true) +mysqli_stmt::attr_set(): Argument #2 ($mode_in) must be one of MYSQLI_CURSOR_TYPE_NO_CURSOR, MYSQLI_CURSOR_TYPE_READ_ONLY, MYSQLI_CURSOR_TYPE_FOR_UPDATE, or MYSQLI_CURSOR_TYPE_SCROLLABLE for attribute MYSQLI_STMT_ATTR_CURSOR_TYPE +mysqli_stmt::attr_set(): Argument #2 ($mode_in) must be greater than 0 for attribute MYSQLI_STMT_ATTR_PREFETCH_ROWS done! diff --git a/ext/mysqli/tests/mysqli_stmt_bind_param.phpt b/ext/mysqli/tests/mysqli_stmt_bind_param.phpt index aba40decf4525..a12e01dc4203a 100644 --- a/ext/mysqli/tests/mysqli_stmt_bind_param.phpt +++ b/ext/mysqli/tests/mysqli_stmt_bind_param.phpt @@ -32,35 +32,77 @@ require_once('skipifconnectfailure.inc'); libmysql gives a less descriptive error message but mysqlnd, we did not unify the error messages but ignore this slight difference silently */ - if (!false === ($tmp = @mysqli_stmt_bind_param($stmt, " ", $tmp))) - printf("[003d] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + try { + if (!false === ($tmp = mysqli_stmt_bind_param($stmt, " ", $tmp))) + printf("[003d] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + } catch (\ArgumentCountError $e) { + echo $e->getMessage() . \PHP_EOL; + } - if (!false === ($tmp = @mysqli_stmt_bind_param($stmt, "", $id, $label))) - printf("[003a] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + try { + if (!false === ($tmp = mysqli_stmt_bind_param($stmt, "", $id, $label))) + printf("[003a] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + } catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; + } /* TODO: somehwhat undocumented syntax! */ $param = array($id); - if (!false === ($tmp = mysqli_stmt_bind_param($stmt, "is", $param))) - printf("[003b] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + try { + if (!false === ($tmp = mysqli_stmt_bind_param($stmt, "is", $param))) + printf("[003b] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + } catch (\ArgumentCountError $e) { + echo $e->getMessage() . \PHP_EOL; + } $param = array($id, $label, $id); - if (!false === ($tmp = mysqli_stmt_bind_param($stmt, "is", $param))) - printf("[003c] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + try { + if (!false === ($tmp = mysqli_stmt_bind_param($stmt, " ", $tmp))) + printf("[003d] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + } catch (\ArgumentCountError $e) { + echo $e->getMessage() . \PHP_EOL; + } + try { + if (!false === ($tmp = mysqli_stmt_bind_param($stmt, "is", $param))) + printf("[003c] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + } catch (\ArgumentCountError $e) { + echo $e->getMessage() . \PHP_EOL; + } - if (!false === ($tmp = mysqli_stmt_bind_param($stmt, "a", $id))) - printf("[004] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + try { + if (!false === ($tmp = mysqli_stmt_bind_param($stmt, "a", $id))) + printf("[004] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + } catch (\ArgumentCountError $e) { + echo $e->getMessage() . \PHP_EOL; + } - if (!false === ($tmp = mysqli_stmt_bind_param($stmt, "a", $id, $label))) - printf("[005] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + try { + if (!false === ($tmp = mysqli_stmt_bind_param($stmt, "a", $id, $label))) + printf("[005] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + } catch (\ArgumentCountError $e) { + echo $e->getMessage() . \PHP_EOL; + } - if (!false === ($tmp = mysqli_stmt_bind_param($stmt, "aa", $id, $label))) - printf("[006] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + try { + if (!false === ($tmp = mysqli_stmt_bind_param($stmt, "aa", $id, $label))) + printf("[006] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + } catch (\ArgumentCountError $e) { + echo $e->getMessage() . \PHP_EOL; + } - if (!false === ($tmp = mysqli_stmt_bind_param($stmt, "ia", $id, $label))) - printf("[007] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + try { + if (!false === ($tmp = mysqli_stmt_bind_param($stmt, "ia", $id, $label))) + printf("[007] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + } catch (\ArgumentCountError $e) { + echo $e->getMessage() . \PHP_EOL; + } - if (!true === ($tmp = mysqli_stmt_bind_param($stmt, "is", $id, $label))) - printf("[008] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + try { + if (!true === ($tmp = mysqli_stmt_bind_param($stmt, "is", $id, $label))) + printf("[008] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + } catch (\ArgumentCountError $e) { + echo $e->getMessage() . \PHP_EOL; + } if (function_exists("memory_get_usage")) { $mem = memory_get_usage(); @@ -374,13 +416,13 @@ require_once('skipifconnectfailure.inc'); require_once("clean_table.inc"); ?> --EXPECTF-- -Warning: mysqli_stmt_bind_param(): Number of elements in type definition string doesn't match number of bind variables in %s on line %d - -Warning: mysqli_stmt_bind_param(): Number of elements in type definition string doesn't match number of bind variables in %s on line %d - -Warning: mysqli_stmt_bind_param(): Number of variables doesn't match number of parameters in prepared statement in %s on line %d - -Warning: mysqli_stmt_bind_param(): Number of elements in type definition string doesn't match number of bind variables in %s on line %d +The number of variables must match the number of parameters in the prepared statement +mysqli_stmt_bind_param(): Argument #2 ($types) cannot be empty +The number of elements in the type definition string must match the number of bind variables +The number of variables must match the number of parameters in the prepared statement +The number of elements in the type definition string must match the number of bind variables +The number of variables must match the number of parameters in the prepared statement +The number of elements in the type definition string must match the number of bind variables Warning: mysqli_stmt_bind_param(): Undefined fieldtype a (parameter 3) in %s on line %d diff --git a/ext/mysqli/tests/mysqli_stmt_bind_result.phpt b/ext/mysqli/tests/mysqli_stmt_bind_result.phpt index c1dddca4f294b..f9556ad0f6380 100644 --- a/ext/mysqli/tests/mysqli_stmt_bind_result.phpt +++ b/ext/mysqli/tests/mysqli_stmt_bind_result.phpt @@ -31,14 +31,20 @@ require_once('skipifconnectfailure.inc'); if (!mysqli_stmt_prepare($stmt, "SELECT id, label FROM test ORDER BY id LIMIT 1")) printf("[004] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); - if (false !== ($tmp = mysqli_stmt_bind_result($stmt, $id))) - printf("[005] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + try { + mysqli_stmt_bind_result($stmt, $id); + } catch (\ArgumentCountError $e) { + echo $e->getMessage() . PHP_EOL; + } if (true !== ($tmp = mysqli_stmt_bind_result($stmt, $id, $label))) printf("[006] Expecting boolean/true, got %s/%s\n", gettype($tmp), $tmp); - if (false !== ($tmp = mysqli_stmt_bind_result($stmt, $id, $label, $foo))) - printf("[007] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + try { + mysqli_stmt_bind_result($stmt, $id, $label, $foo); + } catch (\ArgumentCountError $e) { + echo $e->getMessage() . PHP_EOL; + } if (!mysqli_stmt_execute($stmt)) printf("[008] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); @@ -290,8 +296,11 @@ require_once('skipifconnectfailure.inc'); printf("[3001] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); $id = null; - if (false !== @mysqli_stmt_bind_result($stmt, $id)) - printf("[3002] Bind result should not be allowed"); + try { + mysqli_stmt_bind_result($stmt, $id); + } catch (\ArgumentCountError $e) { + $e->getMessage() . \PHP_EOL; + } mysqli_stmt_close($stmt); @@ -304,10 +313,8 @@ require_once('skipifconnectfailure.inc'); ?> --EXPECTF-- mysqli_stmt object is not fully initialized - -Warning: mysqli_stmt_bind_result(): Number of bind variables doesn't match number of fields in prepared statement in %s on line %d - -Warning: mysqli_stmt_bind_result(): Number of bind variables doesn't match number of fields in prepared statement in %s on line %d +Number of bind variables doesn't match number of fields in prepared statement +Number of bind variables doesn't match number of fields in prepared statement int(1) %s(1) "a" done! diff --git a/ext/mysqli/tests/mysqli_stmt_data_seek.phpt b/ext/mysqli/tests/mysqli_stmt_data_seek.phpt index 72d807512f730..5594600747792 100644 --- a/ext/mysqli/tests/mysqli_stmt_data_seek.phpt +++ b/ext/mysqli/tests/mysqli_stmt_data_seek.phpt @@ -59,8 +59,11 @@ require_once('skipifconnectfailure.inc'); var_dump($id); - if (false !== ($tmp = mysqli_stmt_data_seek($stmt, -1))) - printf("[015] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); + try { + mysqli_stmt_data_seek($stmt, -1); + } catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; + } if (mysqli_stmt_fetch($stmt)) printf("[016] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); @@ -87,8 +90,7 @@ mysqli_stmt object is not fully initialized int(3) int(1) int(1) - -Warning: mysqli_stmt_data_seek(): Offset must be positive in %s on line %d +mysqli_stmt_data_seek(): Argument #2 ($offset) must be greater than or equal to 0 int(1) mysqli_stmt object is already closed done! diff --git a/ext/mysqli/tests/mysqli_stmt_execute_stored_proc_out.phpt b/ext/mysqli/tests/mysqli_stmt_execute_stored_proc_out.phpt index c65330ebc951e..7cbbc74988e9b 100644 --- a/ext/mysqli/tests/mysqli_stmt_execute_stored_proc_out.phpt +++ b/ext/mysqli/tests/mysqli_stmt_execute_stored_proc_out.phpt @@ -44,8 +44,12 @@ if ($IS_MYSQLND) { printf("[008] More results: %s\n", (mysqli_more_results($link) ? "yes" : "no")); printf("[009] Next results: %s\n", (mysqli_next_result($link) ? "yes" : "no")); - if (!mysqli_stmt_bind_result($stmt, $ver_out) || !mysqli_stmt_fetch($stmt)) - printf("[010] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + try { + if (!mysqli_stmt_bind_result($stmt, $ver_out) || !mysqli_stmt_fetch($stmt)) + printf("[010] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + } catch (\ArgumentCountError $e) { + echo $e->getMessage() . \PHP_EOL; + } if ("myversion" !== $ver_out) printf("[011] Results seem wrong got '%s'\n", $ver_out); diff --git a/ext/mysqli/tests/mysqli_stmt_field_count.phpt b/ext/mysqli/tests/mysqli_stmt_field_count.phpt index 51afb04e1b6f9..5c725cd063109 100644 --- a/ext/mysqli/tests/mysqli_stmt_field_count.phpt +++ b/ext/mysqli/tests/mysqli_stmt_field_count.phpt @@ -51,8 +51,12 @@ require_once('skipifconnectfailure.inc'); printf("[013] Expecting int/1, got %s/%s\n", gettype($tmp), $tmp); $label = null; - if (mysqli_stmt_bind_param($stmt, "s", $label)) - printf("[014] expected error - got ok\n"); + try { + if (mysqli_stmt_bind_param($stmt, "s", $label)) + printf("[014] expected error - got ok\n"); + } catch (\ArgumentCountError $e) { + echo $e->getMessage() . \PHP_EOL; + } while (mysqli_stmt_fetch($stmt)) if (1 !== ($tmp = mysqli_stmt_field_count($stmt))) printf("[015] Expecting int/1, got %s/%s\n", gettype($tmp), $tmp); @@ -91,11 +95,10 @@ require_once('skipifconnectfailure.inc'); ---EXPECTF-- +--EXPECT-- mysqli_stmt object is not fully initialized mysqli_stmt object is not fully initialized - -Warning: mysqli_stmt_bind_param(): Number of variables doesn't match number of parameters in prepared statement in %s on line %d +The number of variables must match the number of parameters in the prepared statement mysqli_stmt object is already closed mysqli_stmt object is already closed done! diff --git a/ext/mysqli/tests/mysqli_stmt_get_result_metadata.phpt b/ext/mysqli/tests/mysqli_stmt_get_result_metadata.phpt index cb95ed896afbe..9e6ddec044b4f 100644 --- a/ext/mysqli/tests/mysqli_stmt_get_result_metadata.phpt +++ b/ext/mysqli/tests/mysqli_stmt_get_result_metadata.phpt @@ -182,11 +182,19 @@ if (!function_exists('mysqli_stmt_get_result')) printf("[032] Expecting %s/%s got %s/%s\n", gettype($pos), $pos, gettype($tmp), $tmp); } else { - - if (false !== @mysqli_field_seek($res, $pos)) - printf("[033] field_seek(%d) did not fail\n", $pos); - if (false !== @mysqli_field_seek($res_meta, $pos)) - printf("[034] field_seek(%d) did not fail\n", $pos); + try { + $tmp = @mysqli_field_seek($res, $pos); + if ($pos >= $num && $tmp !== false) { + printf("[033] field_seek(%d) did not fail\n", $pos); + } + } catch (ValueError $e) { /* Suppress output because pos is RANDOM */} + + try { + $tmp = @mysqli_field_seek($res_meta, $pos); + if ($pos >= $num && $tmp !== false) { + printf("[034] field_seek(%d) did not fail\n", $pos); + } + } catch (ValueError $e) { /* Suppress output because pos is RANDOM */} } } diff --git a/ext/mysqli/tests/mysqli_stmt_get_result_seek.phpt b/ext/mysqli/tests/mysqli_stmt_get_result_seek.phpt index 68dad8b281731..cf9e634cc9e31 100644 --- a/ext/mysqli/tests/mysqli_stmt_get_result_seek.phpt +++ b/ext/mysqli/tests/mysqli_stmt_get_result_seek.phpt @@ -61,8 +61,11 @@ if (!function_exists('mysqli_stmt_get_result')) } } - if (false !== ($tmp = $res->data_seek(-1))) - printf("[011] Expecting boolean/false got %s/%s\n", gettype($tmp), $tmp); + try { + $res->data_seek(-1); + } catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; + } if (false !== ($tmp = $res->data_seek($res->num_rows + 1))) printf("[012] Expecting boolean/false got %s/%s\n", gettype($tmp), $tmp); @@ -70,18 +73,20 @@ if (!function_exists('mysqli_stmt_get_result')) for ($i = 0; $i < 100; $i++) { /* intentionally out of range! */ $pos = mt_rand(-1, 4); - $tmp = mysqli_data_seek($res, $pos); - if (($pos >= 0 && $pos < 3)) { - if (true !== $tmp) - printf("[015] Expecting boolan/true got %s/%s\n", gettype($tmp), $tmp); - $row = $res->fetch_array(MYSQLI_NUM); - if ($row[0] !== $pos + 1) - printf("[016] Expecting id = %d for pos %d got %s/%s\n", - $pos + 1, $pos, gettype($row[0]), $row[0]); - } else { - if (false !== $tmp) - printf("[014] Expecting boolan/false got %s/%s\n", gettype($tmp), $tmp); - } + try { + $tmp = @mysqli_data_seek($res, $pos); + if (($pos >= 0 && $pos < 3)) { + if (true !== $tmp) + printf("[015] Expecting boolan/true got %s/%s\n", gettype($tmp), $tmp); + $row = $res->fetch_array(MYSQLI_NUM); + if ($row[0] !== $pos + 1) + printf("[016] Expecting id = %d for pos %d got %s/%s\n", + $pos + 1, $pos, gettype($row[0]), $row[0]); + } else { + if (false !== $tmp) + printf("[014] Expecting boolan/false got %s/%s\n", gettype($tmp), $tmp); + } + } catch (\ValueError $e) { /* Suppress because RANDOM */} } mysqli_stmt_close($stmt); @@ -127,6 +132,7 @@ if (!function_exists('mysqli_stmt_get_result')) require_once("clean_table.inc"); ?> --EXPECT-- +mysqli_result::data_seek(): Argument #1 ($offset) must be greater than or equal to 0 mysqli_result object is already closed mysqli_result object is already closed mysqli_result object is already closed diff --git a/ext/mysqli/tests/mysqli_stmt_send_long_data.phpt b/ext/mysqli/tests/mysqli_stmt_send_long_data.phpt index 00afa5513df79..705f19e8c2178 100644 --- a/ext/mysqli/tests/mysqli_stmt_send_long_data.phpt +++ b/ext/mysqli/tests/mysqli_stmt_send_long_data.phpt @@ -64,9 +64,11 @@ require_once('skipifconnectfailure.inc'); */ assert(strlen($blob) <= $max_allowed_packet); - if (false !== ($tmp = mysqli_stmt_send_long_data($stmt, -1, $blob))) - printf("[012] Expecting boolean/false, got %s/%s. [%d] %s\n", - gettype($tmp), $tmp, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + try { + $tmp = mysqli_stmt_send_long_data($stmt, -1, $blob); + } catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; + } if (false !== ($tmp = mysqli_stmt_send_long_data($stmt, 999, $blob))) printf("[014] Expecting boolean/false, got %s/%s. [%d] %s\n", @@ -106,6 +108,6 @@ require_once('skipifconnectfailure.inc'); ---EXPECTF-- -Warning: mysqli_stmt_send_long_data(): Invalid parameter number in %s on line %d +--EXPECT-- +mysqli_stmt_send_long_data(): Argument #2 ($param_nr) must be greater than or equal to 0 done! diff --git a/ext/mysqli/tests/mysqli_store_result_copy.phpt b/ext/mysqli/tests/mysqli_store_result_copy.phpt index 136e2c5d4d9a5..c431a05a60c26 100644 --- a/ext/mysqli/tests/mysqli_store_result_copy.phpt +++ b/ext/mysqli/tests/mysqli_store_result_copy.phpt @@ -63,12 +63,16 @@ mysqlnd.fetch_data_copy=0 $no_result = 0; for ($i = 0; $i < 1000; $i++) { $idx = mt_rand(-100, 100); - if (true === @mysqli_data_seek($res, $idx)) { - $row = $res->fetch_assoc(); - if (!isset($row['id']) || !isset($row['label'])) { - printf("[010] Brute force seek %d returned %d\n", $idx, var_export($row, true)); + try { + if (true === @mysqli_data_seek($res, $idx)) { + $row = $res->fetch_assoc(); + if (!isset($row['id']) || !isset($row['label'])) { + printf("[010] Brute force seek %d returned %d\n", $idx, var_export($row, true)); + } + } else { + $no_result++; } - } else { + } catch (\ValueError $e) { $no_result++; } } diff --git a/ext/mysqli/tests/mysqli_use_result.phpt b/ext/mysqli/tests/mysqli_use_result.phpt index 1b679d142d3a4..c309d3e3910b5 100644 --- a/ext/mysqli/tests/mysqli_use_result.phpt +++ b/ext/mysqli/tests/mysqli_use_result.phpt @@ -19,9 +19,11 @@ require_once('skipifconnectfailure.inc'); printf("[004] Expecting object, got %s/%s. [%d] %s\n", gettype($res), $res, mysqli_errno($link), mysqli_error($link)); - if (false !== ($tmp = mysqli_data_seek($res, 2))) - printf("[005] Expecting boolean/true, got %s/%s. [%d] %s\n", - gettype($tmp), $tmp, mysqli_errno($link), mysqli_error($link)); + try { + var_dump(mysqli_data_seek($res, 2)); + } catch (\Error $e) { + echo $e->getMessage() . \PHP_EOL; + } mysqli_free_result($res); @@ -53,7 +55,7 @@ require_once('skipifconnectfailure.inc'); ---EXPECTF-- -Warning: mysqli_data_seek(): Function cannot be used with MYSQL_USE_RESULT in %s on line %d +--EXPECT-- +mysqli_data_seek() cannot be used with MYSQLI_USE_RESULT mysqli object is already closed done! diff --git a/ext/mysqlnd/mysqlnd_reverse_api.c b/ext/mysqlnd/mysqlnd_reverse_api.c index 580dc12ce8aed..1f6d920799d10 100644 --- a/ext/mysqlnd/mysqlnd_reverse_api.c +++ b/ext/mysqlnd/mysqlnd_reverse_api.c @@ -66,25 +66,10 @@ mysqlnd_reverse_api_register_api(const MYSQLND_REVERSE_API * apiext) PHPAPI MYSQLND * zval_to_mysqlnd(zval * zv, const unsigned int client_api_capabilities, unsigned int * save_client_api_capabilities) { - MYSQLND * retval; -#ifdef OLD_CODE - MYSQLND_REVERSE_API * elem; - ZEND_HASH_FOREACH_PTR(&mysqlnd_api_ext_ht, elem) { - if (elem->conversion_cb) { - retval = elem->conversion_cb(zv); - if (retval) { - if (retval->data) { - *save_client_api_capabilities = retval->data->m->negotiate_client_api_capabilities(retval->data, client_api_capabilities); - } - return retval; - } - } - } ZEND_HASH_FOREACH_END(); -#else - MYSQLND_REVERSE_API * api; + MYSQLND_REVERSE_API *api; ZEND_HASH_FOREACH_PTR(&mysqlnd_api_ext_ht, api) { - if (api && api->conversion_cb) { - retval = api->conversion_cb(zv); + if (api->conversion_cb) { + MYSQLND *retval = api->conversion_cb(zv); if (retval) { if (retval->data) { *save_client_api_capabilities = retval->data->m->negotiate_client_api_capabilities(retval->data, client_api_capabilities); @@ -93,7 +78,6 @@ zval_to_mysqlnd(zval * zv, const unsigned int client_api_capabilities, unsigned } } } ZEND_HASH_FOREACH_END(); -#endif return NULL; } /* }}} */ diff --git a/ext/oci8/oci8.stub.php b/ext/oci8/oci8.stub.php index 8e8537274a58a..917225f562655 100644 --- a/ext/oci8/oci8.stub.php +++ b/ext/oci8/oci8.stub.php @@ -87,13 +87,13 @@ function oci_lob_copy(OCILob $lob_descriptor_to, OCILob $lob_descriptor_from, ?i function oci_lob_is_equal(OCILob $lob_descriptor_first, OCILob $lob_descriptor_second): bool {} -function oci_lob_export(OCILob $lob_descriptor, string $path, ?int $start = null, ?int $length = null): bool {} +function oci_lob_export(OCILob $lob_descriptor, string $filename, ?int $start = null, ?int $length = null): bool {} /** * @alias oci_lob_export * @deprecated */ -function ociwritelobtofile(OCILob $lob_descriptor, string $path, ?int $start = null, ?int $length = null): bool {} +function ociwritelobtofile(OCILob $lob_descriptor, string $filename, ?int $start = null, ?int $length = null): bool {} /** * @param resource $connection_resource @@ -412,14 +412,14 @@ function oci_get_implicit_resultset($statement_resource) {} /** * @param resource $statement_resource */ -function oci_set_prefetch($statement_resource, int $number_of_rows): ?bool {} +function oci_set_prefetch($statement_resource, int $number_of_rows): bool {} /** * @param resource $statement_resource * @alias oci_set_prefetch * @deprecated */ -function ocisetprefetch($statement_resource, int $number_of_rows): ?bool {} +function ocisetprefetch($statement_resource, int $number_of_rows): bool {} /** * @param resource $connection_resource @@ -718,13 +718,13 @@ public function getbuffering() {} * @alias oci_lob_export * @return bool */ - public function writetofile(string $path, ?int $start = null, ?int $length = null) {} + public function writetofile(string $filename, ?int $start = null, ?int $length = null) {} /** * @alias oci_lob_export * @return bool */ - public function export(string $path, ?int $start = null, ?int $length = null) {} + public function export(string $filename, ?int $start = null, ?int $length = null) {} /** * @alias oci_lob_write_temporary diff --git a/ext/oci8/oci8_arginfo.h b/ext/oci8/oci8_arginfo.h index 32852789996dc..0bcc18f06a1fc 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: 2d553815c21edd58bc29b1ca8d294d5750fd7312 */ + * Stub hash: 6cdc7c967ce80c39eaef1c860ba8f8aa2cb3c979 */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_oci_define_by_name, 0, 3, _IS_BOOL, 0) ZEND_ARG_INFO(0, statement_resource) @@ -124,7 +124,7 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_oci_lob_export, 0, 2, _IS_BOOL, 0) ZEND_ARG_OBJ_INFO(0, lob_descriptor, OCILob, 0) - ZEND_ARG_TYPE_INFO(0, path, IS_STRING, 0) + ZEND_ARG_TYPE_INFO(0, filename, IS_STRING, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, start, IS_LONG, 1, "null") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, length, IS_LONG, 1, "null") ZEND_END_ARG_INFO() @@ -292,7 +292,7 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_oci_get_implicit_resultset, 0, 0, 1) ZEND_ARG_INFO(0, statement_resource) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_oci_set_prefetch, 0, 2, _IS_BOOL, 1) +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_oci_set_prefetch, 0, 2, _IS_BOOL, 0) ZEND_ARG_INFO(0, statement_resource) ZEND_ARG_TYPE_INFO(0, number_of_rows, IS_LONG, 0) ZEND_END_ARG_INFO() @@ -498,7 +498,7 @@ ZEND_END_ARG_INFO() #define arginfo_class_OCILob_getbuffering arginfo_class_OCILob_load ZEND_BEGIN_ARG_INFO_EX(arginfo_class_OCILob_writetofile, 0, 0, 1) - ZEND_ARG_TYPE_INFO(0, path, IS_STRING, 0) + ZEND_ARG_TYPE_INFO(0, filename, IS_STRING, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, start, IS_LONG, 1, "null") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, length, IS_LONG, 1, "null") ZEND_END_ARG_INFO() diff --git a/ext/oci8/oci8_interface.c b/ext/oci8/oci8_interface.c index 26f8dfdc401bf..91db3f4815fc3 100644 --- a/ext/oci8/oci8_interface.c +++ b/ext/oci8/oci8_interface.c @@ -40,6 +40,8 @@ #define OCI_STMT_CALL 10 #endif +#define ERROR_ARG_POS(arg_num) (getThis() ? (arg_num-1) : (arg_num)) + /* {{{ Register a callback function for Oracle Transparent Application Failover (TAF) */ PHP_FUNCTION(oci_register_taf_callback) { @@ -109,8 +111,8 @@ PHP_FUNCTION(oci_define_by_name) ZEND_PARSE_PARAMETERS_END(); if (!name_len) { - php_error_docref(NULL, E_WARNING, "Column name cannot be empty"); - RETURN_FALSE; + zend_argument_value_error(2, "cannot be empty"); + RETURN_THROWS(); } PHP_OCI_ZVAL_TO_STATEMENT(stmt, statement); @@ -210,8 +212,8 @@ PHP_FUNCTION(oci_bind_array_by_name) } if (max_array_len <= 0) { - php_error_docref(NULL, E_WARNING, "Maximum array length must be greater than zero"); - RETURN_FALSE; + zend_argument_value_error(4, "must be greater than 0"); + RETURN_THROWS(); } if (php_oci_bind_array_by_name(statement, name, (sb4) name_len, bind_var, max_array_len, max_item_len, type)) { @@ -257,6 +259,11 @@ PHP_FUNCTION(oci_lob_save) RETURN_THROWS(); } + if (offset < 0) { + zend_argument_value_error(ERROR_ARG_POS(3), "must be greater than or equal to 0"); + RETURN_THROWS(); + } + if ((tmp = zend_hash_str_find(Z_OBJPROP_P(z_descriptor), "descriptor", sizeof("descriptor")-1)) == NULL) { php_error_docref(NULL, E_WARNING, "Unable to find descriptor property"); RETURN_FALSE; @@ -264,11 +271,6 @@ PHP_FUNCTION(oci_lob_save) PHP_OCI_ZVAL_TO_DESCRIPTOR(tmp, descriptor); - if (offset < 0) { - php_error_docref(NULL, E_WARNING, "Offset parameter must be greater than or equal to 0"); - RETURN_FALSE; - } - if (php_oci_lob_write(descriptor, (ub4) offset, data, (ub4) data_len, &bytes_written)) { RETURN_FALSE; } @@ -284,7 +286,7 @@ PHP_FUNCTION(oci_lob_import) char *filename; size_t filename_len; - if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Os", &z_descriptor, oci_lob_class_entry_ptr, &filename, &filename_len) == FAILURE) { + if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Op", &z_descriptor, oci_lob_class_entry_ptr, &filename, &filename_len) == FAILURE) { RETURN_THROWS(); } @@ -293,11 +295,6 @@ PHP_FUNCTION(oci_lob_import) RETURN_FALSE; } - if (CHECK_NULL_PATH(filename, filename_len)) { - php_error_docref(NULL, E_WARNING, "filename must not contain null bytes"); - RETURN_FALSE; - } - PHP_OCI_ZVAL_TO_DESCRIPTOR(tmp, descriptor); if (php_oci_lob_import(descriptor, filename)) { @@ -354,6 +351,11 @@ PHP_FUNCTION(oci_lob_read) RETURN_THROWS(); } + if (length <= 0) { + zend_argument_value_error(ERROR_ARG_POS(2), "must be greater than 0"); + RETURN_THROWS(); + } + if ((tmp = zend_hash_str_find(Z_OBJPROP_P(z_descriptor), "descriptor", sizeof("descriptor")-1)) == NULL) { php_error_docref(NULL, E_WARNING, "Unable to find descriptor property"); RETURN_FALSE; @@ -361,11 +363,6 @@ PHP_FUNCTION(oci_lob_read) PHP_OCI_ZVAL_TO_DESCRIPTOR(tmp, descriptor); - if (length <= 0) { - php_error_docref(NULL, E_WARNING, "Length parameter must be greater than 0"); - RETURN_FALSE; - } - if (php_oci_lob_read(descriptor, length, descriptor->lob_current_position, &buffer, &buffer_len)) { RETURN_FALSE; } @@ -604,13 +601,13 @@ PHP_FUNCTION(oci_lob_truncate) RETURN_THROWS(); } - if ((tmp = zend_hash_str_find(Z_OBJPROP_P(z_descriptor), "descriptor", sizeof("descriptor")-1)) == NULL) { - php_error_docref(NULL, E_WARNING, "Unable to find descriptor property"); - RETURN_FALSE; + if (trim_length < 0) { + zend_argument_value_error(ERROR_ARG_POS(2), "must be greater than or equal to 0"); + RETURN_THROWS(); } - if (trim_length < 0) { - php_error_docref(NULL, E_WARNING, "Length must be greater than or equal to zero"); + if ((tmp = zend_hash_str_find(Z_OBJPROP_P(z_descriptor), "descriptor", sizeof("descriptor")-1)) == NULL) { + php_error_docref(NULL, E_WARNING, "Unable to find descriptor property"); RETURN_FALSE; } @@ -640,15 +637,15 @@ PHP_FUNCTION(oci_lob_erase) if (offset_is_null) { offset = -1; } else if (offset < 0) { - php_error_docref(NULL, E_WARNING, "Offset must be greater than or equal to 0"); - RETURN_FALSE; + zend_argument_value_error(ERROR_ARG_POS(2), "must be greater than or equal to 0"); + RETURN_THROWS(); } if (length_is_null) { length = -1; } else if (length < 0) { - php_error_docref(NULL, E_WARNING, "Length must be greater than or equal to 0"); - RETURN_FALSE; + zend_argument_value_error(ERROR_ARG_POS(3), "must be greater than or equal to 0"); + RETURN_THROWS(); } if ((tmp = zend_hash_str_find(Z_OBJPROP_P(z_descriptor), "descriptor", sizeof("descriptor")-1)) == NULL) { @@ -756,6 +753,13 @@ PHP_FUNCTION(oci_lob_copy) RETURN_THROWS(); } + if (length_is_null) { + length = -1; + } else if (length < 0) { + zend_argument_value_error(3, "must be greater than or equal to 0"); + RETURN_THROWS(); + } + if ((tmp_dest = zend_hash_str_find(Z_OBJPROP_P(z_descriptor_dest), "descriptor", sizeof("descriptor")-1)) == NULL) { php_error_docref(NULL, E_WARNING, "Unable to find descriptor property. The first argument should be valid descriptor object"); RETURN_FALSE; @@ -769,13 +773,6 @@ PHP_FUNCTION(oci_lob_copy) PHP_OCI_ZVAL_TO_DESCRIPTOR(tmp_dest, descriptor_dest); PHP_OCI_ZVAL_TO_DESCRIPTOR(tmp_from, descriptor_from); - if (length_is_null) { - length = -1; - } else if (length < 0) { - php_error_docref(NULL, E_WARNING, "Length parameter must be greater than 0"); - RETURN_FALSE; - } - if (php_oci_lob_copy(descriptor_dest, descriptor_from, length)) { RETURN_FALSE; } @@ -831,22 +828,22 @@ PHP_FUNCTION(oci_lob_export) php_stream *stream; ub4 lob_length; - if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Os|l!l!", &z_descriptor, oci_lob_class_entry_ptr, &filename, &filename_len, &start, &start_is_null, &length, &length_is_null) == FAILURE) { + if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Op|l!l!", &z_descriptor, oci_lob_class_entry_ptr, &filename, &filename_len, &start, &start_is_null, &length, &length_is_null) == FAILURE) { RETURN_THROWS(); } if (start_is_null) { start = -1; } else if (start < 0) { - php_error_docref(NULL, E_WARNING, "Start parameter must be greater than or equal to 0"); - RETURN_FALSE; + zend_argument_value_error(ERROR_ARG_POS(3), "must be greater than or equal to 0"); + RETURN_THROWS(); } if (length_is_null) { length = -1; } else if (length < 0) { - php_error_docref(NULL, E_WARNING, "length parameter must be greater than or equal to 0"); - RETURN_FALSE; + zend_argument_value_error(ERROR_ARG_POS(4), "must be greater than or equal to 0"); + RETURN_THROWS(); } if ((tmp = zend_hash_str_find(Z_OBJPROP_P(z_descriptor), "descriptor", sizeof("descriptor")-1)) == NULL) { @@ -854,11 +851,6 @@ PHP_FUNCTION(oci_lob_export) RETURN_FALSE; } - if (CHECK_NULL_PATH(filename, filename_len)) { - php_error_docref(NULL, E_WARNING, "filename must not contain null bytes"); - RETURN_FALSE; - } - PHP_OCI_ZVAL_TO_DESCRIPTOR(tmp, descriptor); if (php_oci_lob_get_length(descriptor, &lob_length)) { @@ -1630,8 +1622,8 @@ PHP_FUNCTION(oci_set_prefetch) PHP_OCI_ZVAL_TO_STATEMENT(z_statement, statement); if (size < 0) { - php_error_docref(NULL, E_WARNING, "Number of rows to be prefetched has to be greater than or equal to 0"); - return; + zend_argument_value_error(2, "must be greater than or equal to 0"); + RETURN_THROWS(); } if (php_oci_statement_set_prefetch(statement, (ub4)size)) { @@ -1899,16 +1891,16 @@ PHP_FUNCTION(oci_password_change) PHP_OCI_ZVAL_TO_CONNECTION(z_connection, connection); if (!user_len) { - php_error_docref(NULL, E_WARNING, "Username cannot be empty"); - RETURN_FALSE; + zend_argument_value_error(2, "cannot be empty"); + RETURN_THROWS(); } if (!pass_old_len) { - php_error_docref(NULL, E_WARNING, "Old password cannot be empty"); - RETURN_FALSE; + zend_argument_value_error(3, "cannot be empty"); + RETURN_THROWS(); } if (!pass_new_len) { - php_error_docref(NULL, E_WARNING, "New password cannot be empty"); - RETURN_FALSE; + zend_argument_value_error(4, "cannot be empty"); + RETURN_THROWS(); } if (php_oci_password_change(connection, user, (int) user_len, pass_old, (int) pass_old_len, pass_new, (int) pass_new_len)) { @@ -1918,16 +1910,16 @@ PHP_FUNCTION(oci_password_change) } else if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "ssss", &dbname, &dbname_len, &user, &user_len, &pass_old, &pass_old_len, &pass_new, &pass_new_len) == SUCCESS) { if (!user_len) { - php_error_docref(NULL, E_WARNING, "Username cannot be empty"); - RETURN_FALSE; + zend_argument_value_error(2, "cannot be empty"); + RETURN_THROWS(); } if (!pass_old_len) { - php_error_docref(NULL, E_WARNING, "Old password cannot be empty"); - RETURN_FALSE; + zend_argument_value_error(3, "cannot be empty"); + RETURN_THROWS(); } if (!pass_new_len) { - php_error_docref(NULL, E_WARNING, "New password cannot be empty"); - RETURN_FALSE; + zend_argument_value_error(4, "cannot be empty"); + RETURN_THROWS(); } connection = php_oci_do_connect_ex(user, (int) user_len, pass_old, (int) pass_old_len, pass_new, (int) pass_new_len, dbname, (int) dbname_len, NULL, OCI_DEFAULT, 0, 0); diff --git a/ext/oci8/tests/array_bind_002.phpt b/ext/oci8/tests/array_bind_002.phpt index 14635356ba6a3..863f543c0f5a4 100644 --- a/ext/oci8/tests/array_bind_002.phpt +++ b/ext/oci8/tests/array_bind_002.phpt @@ -50,7 +50,11 @@ $statement = oci_parse($c, "BEGIN array_bind_002_pkg.iobind(:c1); END;"); $array = Array("06-DEC-05","10-DEC-80","21-AUG-91","26-OCT-17","05-NOV-05"); -oci_bind_array_by_name($statement, ":c1", $array, 0, 0, SQLT_ODT); +try { + oci_bind_array_by_name($statement, ":c1", $array, 0, 0, SQLT_ODT); +} catch (ValueError $e) { + echo $e->getMessage(), "\n"; +} oci_execute($statement); @@ -59,7 +63,7 @@ var_dump($array); echo "Done\n"; ?> --EXPECTF-- -Warning: oci_bind_array_by_name(): Maximum array length must be greater than zero in %s on line %d +oci_bind_array_by_name(): Argument #4 ($maximum_array_length) must be greater than 0 Warning: oci_execute(): ORA-%r(01008|57000)%r: %s in %s on line %d array(5) { diff --git a/ext/oci8/tests/define1.phpt b/ext/oci8/tests/define1.phpt index 73178ae622748..e79fd76e1b9bd 100644 --- a/ext/oci8/tests/define1.phpt +++ b/ext/oci8/tests/define1.phpt @@ -26,7 +26,11 @@ $stmt = oci_parse($c, "select string from define1_tab"); $string = ''; var_dump(oci_define_by_name($stmt, "STRING", $string, 20)); var_dump(oci_define_by_name($stmt, "STRING", $string, 20)); -var_dump(oci_define_by_name($stmt, "", $string, 20)); +try { + var_dump(oci_define_by_name($stmt, "", $string, 20)); +} catch (ValueError $e) { + echo $e->getMessage(), "\n"; +} oci_execute($stmt); @@ -48,8 +52,6 @@ echo "Done\n"; --EXPECTF-- bool(true) bool(false) - -Warning: oci_define_by_name(): Column name cannot be empty in %s on line %d -bool(false) +oci_define_by_name(): Argument #2 ($column_name) cannot be empty string(4) "some" Done diff --git a/ext/oci8/tests/lob_003.phpt b/ext/oci8/tests/lob_003.phpt index 80bead5964bd2..e06d15109c15d 100644 Binary files a/ext/oci8/tests/lob_003.phpt and b/ext/oci8/tests/lob_003.phpt differ diff --git a/ext/oci8/tests/lob_020.phpt b/ext/oci8/tests/lob_020.phpt index affdef912634d..241b2c7c30f28 100644 Binary files a/ext/oci8/tests/lob_020.phpt and b/ext/oci8/tests/lob_020.phpt differ diff --git a/ext/oci8/tests/lob_022.phpt b/ext/oci8/tests/lob_022.phpt index dba5adcbe36cd..3f57122818492 100644 --- a/ext/oci8/tests/lob_022.phpt +++ b/ext/oci8/tests/lob_022.phpt @@ -34,11 +34,15 @@ $clob = oci_new_descriptor($c, OCI_D_LOB); oci_bind_by_name($statement, ":mylob", $clob, -1, OCI_B_CLOB); oci_execute($statement, OCI_DEFAULT); $clob->save("long data"); -$clob->save("long data", -1); $clob->save("long data", 0); -oci_commit($c); +try { + $clob->save("long data", -1); +} catch (ValueError $e) { + echo $e->getMessage(), "\n"; +} +oci_commit($c); $query = 'SELECT * FROM lob_test ORDER BY mykey ASC'; $statement = oci_parse ($c, $query); @@ -67,7 +71,7 @@ echo "Done\n"; ?> --EXPECTF-- -Warning: OCILob::save(): Offset parameter must be greater than or equal to 0 in %s on line %d +OCILob::save(): Argument #2 ($offset) must be greater than or equal to 0 string(4) "data" string(9) "long data" string(9) "long data" diff --git a/ext/oci8/tests/lob_027.phpt b/ext/oci8/tests/lob_027.phpt index 05390d1403df0..8f5992a555a3a 100644 --- a/ext/oci8/tests/lob_027.phpt +++ b/ext/oci8/tests/lob_027.phpt @@ -45,7 +45,11 @@ for ($i = 5; $i >= 0; $i--) { $row = oci_fetch_array($s); var_dump($row['BLOB']->load()); - var_dump($row['BLOB']->truncate(($i-1)*10)); + try { + var_dump($row['BLOB']->truncate(($i-1)*10)); + } catch (ValueError $e) { + echo $e->getMessage(), "\n"; + } oci_commit($c); } @@ -56,9 +60,14 @@ oci_execute($s, OCI_DEFAULT); $row = oci_fetch_array($s); var_dump($row['BLOB']->load()); -var_dump($row['BLOB']->truncate(-1)); var_dump($row['BLOB']->truncate(0)); +try { + var_dump($row['BLOB']->truncate(-1)); +} catch (ValueError $e) { + echo $e->getMessage(), "\n"; +} + oci_commit($c); require __DIR__.'/drop_table.inc'; @@ -95,12 +104,8 @@ bool(true) string(10) "this is a " bool(true) string(0) "" - -Warning: OCILob::truncate(): Length must be greater than or equal to zero in %s on line %d -bool(false) +OCILob::truncate(): Argument #1 ($length) must be greater than or equal to 0 string(0) "" - -Warning: OCILob::truncate(): Length must be greater than or equal to zero in %s on line %d -bool(false) bool(true) +OCILob::truncate(): Argument #1 ($length) must be greater than or equal to 0 Done diff --git a/ext/oci8/tests/lob_035.phpt b/ext/oci8/tests/lob_035.phpt index c2240849c249b..53146e1286575 100644 --- a/ext/oci8/tests/lob_035.phpt +++ b/ext/oci8/tests/lob_035.phpt @@ -23,6 +23,7 @@ $blob = oci_new_descriptor($c,OCI_D_LOB); oci_bind_by_name($statement,":v_blob", $blob,-1,OCI_B_BLOB); oci_execute($statement, OCI_DEFAULT); +echo "Writing blob\n"; var_dump($blob->write("some string here. string, I said")); oci_commit($c); @@ -54,21 +55,34 @@ $row2 = oci_fetch_array($s); $dummy = oci_new_descriptor($c, OCI_D_LOB); +//-------------------------------------------------- + +echo "\noci_lob_copy invalid args\n"; + var_dump(oci_lob_copy($dummy, $row1[0])); var_dump(oci_lob_copy($row2[0], $dummy)); - var_dump(oci_lob_copy($row2[0], $row1[0], 0)); -var_dump(oci_lob_copy($row2[0], $row1[0], -1)); var_dump(oci_lob_copy($row2[0], $row1[0], 100000)); +try { + var_dump(oci_lob_copy($row2[0], $row1[0], -1)); +} catch (ValueError $e) { + echo $e->getMessage(), "\n"; +} + +//-------------------------------------------------- + +echo "\noci_lob_size tests\n"; + var_dump(oci_lob_size($row2[0])); unset($dummy->descriptor); var_dump(oci_lob_size($dummy)); oci_rollback($c); -oci_rollback($c); -oci_commit($c); -oci_commit($c); + +//-------------------------------------------------- + +echo "\nQuery test\n"; $select_sql = "SELECT blob FROM ".$schema.$table_name." WHERE id = 2 FOR UPDATE"; $s = oci_parse($c, $select_sql); @@ -82,22 +96,27 @@ echo "Done\n"; ?> --EXPECTF-- +Writing blob int(32) +oci_lob_copy invalid args + Warning: oci_lob_copy(): OCI_INVALID_HANDLE in %s on line %d bool(false) Warning: oci_lob_copy(): OCI_INVALID_HANDLE in %s on line %d bool(false) bool(false) - -Warning: oci_lob_copy(): Length parameter must be greater than 0 in %s on line %d -bool(false) bool(true) +oci_lob_copy(): Argument #3 ($length) must be greater than or equal to 0 + +oci_lob_size tests int(0) Warning: oci_lob_size(): Unable to find descriptor property in %s on line %d bool(false) + +Query test array(2) { [0]=> string(0) "" diff --git a/ext/oci8/tests/lob_042.phpt b/ext/oci8/tests/lob_042.phpt index eb447f22afd80..f9e072e0fe68e 100644 --- a/ext/oci8/tests/lob_042.phpt +++ b/ext/oci8/tests/lob_042.phpt @@ -32,12 +32,17 @@ var_dump($blob->write($str)); var_dump($blob->truncate(1)); var_dump($blob->truncate(1)); var_dump($blob->truncate(2)); -var_dump($blob->truncate(-1)); var_dump($blob->read(2)); var_dump($blob->import("does_not_exist")); var_dump($blob->saveFile("does_not_exist")); +try { + var_dump($blob->truncate(-1)); +} catch (ValueError $e) { + echo $e->getMessage(), "\n"; +} + require(__DIR__.'/drop_table.inc'); echo "Done\n"; @@ -58,9 +63,6 @@ bool(true) Warning: OCILob::truncate(): Size must be less than or equal to the current LOB size in %s on line %d bool(false) -Warning: OCILob::truncate(): Length must be greater than or equal to zero in %s on line %d -bool(false) - Warning: OCILob::read(): Offset must be less than size of the LOB in %s on line %d bool(false) @@ -69,4 +71,5 @@ bool(false) Warning: OCILob::savefile(): Can't open file %s in %s on line %d bool(false) +OCILob::truncate(): Argument #1 ($length) must be greater than or equal to 0 Done diff --git a/ext/oci8/tests/null_byte_1.phpt b/ext/oci8/tests/null_byte_1.phpt index f922c62852d8c..d751335b1e868 100644 --- a/ext/oci8/tests/null_byte_1.phpt +++ b/ext/oci8/tests/null_byte_1.phpt @@ -9,7 +9,6 @@ if (PHP_MAJOR_VERSION < 5 || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION < 4)) ?> --INI-- display_errors = On -error_reporting = E_WARNING --FILE-- savefile("/tmp/abc\0def"); -var_dump($r); +try { + $lob->savefile("/tmp/abc\0def"); +} catch (ValueError $e) { + echo $e->getMessage(), "\n"; +} echo "Test 2: Export\n"; -$r = $lob->export("/tmp/abc\0def"); -var_dump($r); +try { + $lob->export("/tmp/abc\0def"); +} catch (ValueError $e) { + echo $e->getMessage(), "\n"; +} ?> --EXPECTF-- Test 1: Import - -Warning: OCILob::savefile(): filename must not contain null bytes in %s on line %d -bool(false) +OCILob::savefile(): Argument #1 ($filename) must not contain any null bytes Test 2: Export - -Warning: OCILob::export(): filename must not contain null bytes in %s on line %d -bool(false) +OCILob::export(): Argument #1 ($filename) must not contain any null bytes diff --git a/ext/oci8/tests/refcur_prefetch_1.phpt b/ext/oci8/tests/refcur_prefetch_1.phpt index 911a4810633ff..0297401f995dc 100644 --- a/ext/oci8/tests/refcur_prefetch_1.phpt +++ b/ext/oci8/tests/refcur_prefetch_1.phpt @@ -61,7 +61,7 @@ for ($i = 0; $i<=500; $i++) { } // Various values for prefetch -$pref = array(0,1,501,499,250,12345,-12345,-1); +$pref = array(0,1,501,499,250,12345); foreach($pref as $value) { echo"-----------------------------------------------\n"; echo "Test with Prefetch value set to $value \n"; @@ -71,6 +71,21 @@ foreach($pref as $value) { fetch_frm_plsql($c,$cur1); } +// Various invalid values for prefetch +$pref = array(-12345,-1); +foreach($pref as $value) { + try { + echo "-----------------------------------------------\n"; + echo "Test with Prefetch (invalid) value set to $value \n"; + echo "-----------------------------------------------\n"; + $cur1 = oci_new_cursor($c); + fetch_frm_php($c,$cur1,$value); + fetch_frm_plsql($c,$cur1); + } catch(ValueError $e) { + echo $e->getMessage(), "\n"; + } +} + // This function sets the prefetch count to the given $value and fetches one row . @@ -206,33 +221,11 @@ Fetch Row from PL/SQL int(0) NULL ----------------------------------------------- -Test with Prefetch value set to -12345 +Test with Prefetch (invalid) value set to -12345 ----------------------------------------------- - -Warning: oci_set_prefetch(): Number of rows to be prefetched has to be greater than or equal to 0 in %s on line %d -Fetch Row from PHP -array(2) { - [0]=> - string(%d) "0" - [1]=> - string(%d) "test0" -} -Fetch Row from PL/SQL -int(101) -string(%d) "test101" +oci_set_prefetch(): Argument #2 ($number_of_rows) must be greater than or equal to 0 ----------------------------------------------- -Test with Prefetch value set to -1 +Test with Prefetch (invalid) value set to -1 ----------------------------------------------- - -Warning: oci_set_prefetch(): Number of rows to be prefetched has to be greater than or equal to 0 in %s on line %d -Fetch Row from PHP -array(2) { - [0]=> - string(%d) "0" - [1]=> - string(%d) "test0" -} -Fetch Row from PL/SQL -int(101) -string(%d) "test101" +oci_set_prefetch(): Argument #2 ($number_of_rows) must be greater than or equal to 0 Done diff --git a/ext/odbc/php_odbc.c b/ext/odbc/php_odbc.c index af62ecb29dada..98b079c60310a 100644 --- a/ext/odbc/php_odbc.c +++ b/ext/odbc/php_odbc.c @@ -787,6 +787,11 @@ void odbc_column_lengths(INTERNAL_FUNCTION_PARAMETERS, int type) RETURN_THROWS(); } + if (pv_num < 1) { + zend_argument_value_error(2, "must be greater than 0"); + RETURN_THROWS(); + } + if (result->numcols == 0) { php_error_docref(NULL, E_WARNING, "No tuples available at this result index"); RETURN_FALSE; @@ -797,11 +802,6 @@ void odbc_column_lengths(INTERNAL_FUNCTION_PARAMETERS, int type) RETURN_FALSE; } - if (pv_num < 1) { - php_error_docref(NULL, E_WARNING, "Field numbering starts at 1"); - RETURN_FALSE; - } - PHP_ODBC_SQLCOLATTRIBUTE(result->stmt, (SQLUSMALLINT)pv_num, (SQLUSMALLINT) (type?SQL_COLUMN_SCALE:SQL_COLUMN_PRECISION), NULL, 0, NULL, &len); RETURN_LONG(len); @@ -963,7 +963,8 @@ PHP_FUNCTION(odbc_prepare) /* {{{ Execute a prepared statement */ PHP_FUNCTION(odbc_execute) { - zval *pv_res, *pv_param_arr, *tmp; + zval *pv_res, *tmp; + HashTable *pv_param_ht; typedef struct params_t { SQLLEN vallen; int fp; @@ -976,7 +977,7 @@ PHP_FUNCTION(odbc_execute) int numArgs = ZEND_NUM_ARGS(), i, ne; RETCODE rc; - if (zend_parse_parameters(numArgs, "r|a", &pv_res, &pv_param_arr) == FAILURE) { + if (zend_parse_parameters(numArgs, "r|h", &pv_res, &pv_param_ht) == FAILURE) { RETURN_THROWS(); } @@ -991,19 +992,19 @@ PHP_FUNCTION(odbc_execute) } if (result->numparams > 0) { - if ((ne = zend_hash_num_elements(Z_ARRVAL_P(pv_param_arr))) < result->numparams) { + if ((ne = zend_hash_num_elements(pv_param_ht)) < result->numparams) { php_error_docref(NULL, E_WARNING,"Not enough parameters (%d should be %d) given", ne, result->numparams); RETURN_FALSE; } - zend_hash_internal_pointer_reset(Z_ARRVAL_P(pv_param_arr)); + zend_hash_internal_pointer_reset(pv_param_ht); params = (params_t *)safe_emalloc(sizeof(params_t), result->numparams, 0); for(i = 0; i < result->numparams; i++) { params[i].fp = -1; } for(i = 1; i <= result->numparams; i++) { - if ((tmp = zend_hash_get_current_data(Z_ARRVAL_P(pv_param_arr))) == NULL) { + if ((tmp = zend_hash_get_current_data(pv_param_ht)) == NULL) { php_error_docref(NULL, E_WARNING,"Error getting parameter"); SQLFreeStmt(result->stmt,SQL_RESET_PARAMS); for (i = 0; i < result->numparams; i++) { @@ -1104,7 +1105,7 @@ PHP_FUNCTION(odbc_execute) efree(params); RETURN_FALSE; } - zend_hash_move_forward(Z_ARRVAL_P(pv_param_arr)); + zend_hash_move_forward(pv_param_ht); } } /* Close cursor, needed for doing multiple selects */ @@ -1246,8 +1247,8 @@ PHP_FUNCTION(odbc_data_source) fetch_type = (SQLSMALLINT) zv_fetch_type; if (!(fetch_type == SQL_FETCH_FIRST || fetch_type == SQL_FETCH_NEXT)) { - php_error_docref(NULL, E_WARNING, "Invalid fetch type (%d)", fetch_type); - RETURN_FALSE; + zend_argument_value_error(2, "must be either SQL_FETCH_FIRST or SQL_FETCH_NEXT"); + RETURN_THROWS(); } if (!(conn = (odbc_connection *)zend_fetch_resource2(Z_RES_P(zv_conn), "ODBC-Link", le_conn, le_pconn))) { @@ -2209,8 +2210,9 @@ void odbc_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) cur_opt == SQL_CUR_USE_ODBC || cur_opt == SQL_CUR_USE_DRIVER || cur_opt == SQL_CUR_DEFAULT) ) { - php_error_docref(NULL, E_WARNING, "Invalid Cursor type (%d)", cur_opt); - RETURN_FALSE; + zend_argument_value_error(4, "must be one of SQL_CUR_USE_IF_NEEDED, " + "SQL_CUR_USE_ODBC, or SQL_CUR_USE_DRIVER"); + RETURN_THROWS(); } } @@ -2483,6 +2485,11 @@ PHP_FUNCTION(odbc_field_name) RETURN_THROWS(); } + if (pv_num < 1) { + zend_argument_value_error(2, "must be greater than 0"); + RETURN_THROWS(); + } + if (result->numcols == 0) { php_error_docref(NULL, E_WARNING, "No tuples available at this result index"); RETURN_FALSE; @@ -2493,11 +2500,6 @@ PHP_FUNCTION(odbc_field_name) RETURN_FALSE; } - if (pv_num < 1) { - php_error_docref(NULL, E_WARNING, "Field numbering starts at 1"); - RETURN_FALSE; - } - RETURN_STRING(result->values[pv_num - 1].name); } /* }}} */ @@ -2519,6 +2521,11 @@ PHP_FUNCTION(odbc_field_type) RETURN_THROWS(); } + if (pv_num < 1) { + zend_argument_value_error(2, "must be greater than 0"); + RETURN_THROWS(); + } + if (result->numcols == 0) { php_error_docref(NULL, E_WARNING, "No tuples available at this result index"); RETURN_FALSE; @@ -2529,11 +2536,6 @@ PHP_FUNCTION(odbc_field_type) RETURN_FALSE; } - if (pv_num < 1) { - php_error_docref(NULL, E_WARNING, "Field numbering starts at 1"); - RETURN_FALSE; - } - PHP_ODBC_SQLCOLATTRIBUTE(result->stmt, (SQLUSMALLINT)pv_num, SQL_COLUMN_TYPE_NAME, tmp, 31, &tmplen, NULL); RETURN_STRING(tmp); } @@ -2733,9 +2735,8 @@ PHP_FUNCTION(odbc_setoption) } break; default: - php_error_docref(NULL, E_WARNING, "Unknown option type"); - RETURN_FALSE; - break; + zend_argument_value_error(2, "must be 1 for SQLSetConnectOption(), or 2 for SQLSetStmtOption()"); + RETURN_THROWS(); } RETURN_TRUE; diff --git a/ext/odbc/tests/odbc_data_source_001.phpt b/ext/odbc/tests/odbc_data_source_001.phpt index fedbbc1b02b79..0d7de96f12a60 100644 --- a/ext/odbc/tests/odbc_data_source_001.phpt +++ b/ext/odbc/tests/odbc_data_source_001.phpt @@ -14,12 +14,16 @@ include 'config.inc'; $conn = odbc_connect($dsn, $user, $pass); -var_dump(odbc_data_source($conn, NULL)); +try { + var_dump(odbc_data_source($conn, NULL)); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} var_dump(odbc_data_source($conn, SQL_FETCH_FIRST)); ?> --EXPECTF-- -Warning: odbc_data_source(): Invalid fetch type (0) in %s on line %d +odbc_data_source(): Argument #2 ($fetch_type) must be either SQL_FETCH_FIRST or SQL_FETCH_NEXT bool(false) array(%d) { %a diff --git a/ext/opcache/Optimizer/zend_func_info.c b/ext/opcache/Optimizer/zend_func_info.c index 5ee5d394981cb..edbc068dda2ec 100644 --- a/ext/opcache/Optimizer/zend_func_info.c +++ b/ext/opcache/Optimizer/zend_func_info.c @@ -434,7 +434,7 @@ static const func_info_t func_infos[] = { F1("timezone_name_from_abbr", MAY_BE_FALSE | MAY_BE_STRING), F1("timezone_transitions_get", MAY_BE_FALSE | MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_ANY), F1("timezone_location_get", MAY_BE_FALSE | MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_STRING | MAY_BE_ARRAY_OF_DOUBLE | MAY_BE_ARRAY_OF_STRING), - F1("timezone_identifiers_list", MAY_BE_FALSE | MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_LONG | MAY_BE_ARRAY_OF_STRING), + F1("timezone_identifiers_list", MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_LONG | MAY_BE_ARRAY_OF_STRING), F1("timezone_abbreviations_list", MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_STRING | MAY_BE_ARRAY_OF_ARRAY), F1("timezone_version_get", MAY_BE_STRING), F1("date_interval_create_from_date_string", MAY_BE_FALSE | MAY_BE_OBJECT), @@ -488,7 +488,6 @@ static const func_info_t func_infos[] = { F1("mysqli_prepare", MAY_BE_FALSE | MAY_BE_OBJECT), F1("mysqli_real_escape_string", MAY_BE_STRING), F1("mysqli_stmt_affected_rows", MAY_BE_LONG | MAY_BE_STRING), - F0("mysqli_stmt_data_seek", MAY_BE_NULL | MAY_BE_FALSE), F1("mysqli_stmt_insert_id", MAY_BE_LONG | MAY_BE_STRING), F1("mysqli_stmt_num_rows", MAY_BE_LONG | MAY_BE_STRING), F1("mysqli_sqlstate", MAY_BE_NULL | MAY_BE_STRING), @@ -533,7 +532,7 @@ static const func_info_t func_infos[] = { F1("mb_stristr", MAY_BE_FALSE | MAY_BE_STRING), F1("mb_strrichr", MAY_BE_FALSE | MAY_BE_STRING), F1("mb_substr", MAY_BE_STRING), - F1("mb_strcut", MAY_BE_FALSE | MAY_BE_STRING), + F1("mb_strcut", MAY_BE_STRING), F1("mb_strimwidth", MAY_BE_STRING), F1("mb_convert_encoding", MAY_BE_FALSE | MAY_BE_STRING | MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_ANY), F1("mb_detect_encoding", MAY_BE_FALSE | MAY_BE_STRING), @@ -727,7 +726,7 @@ static const func_info_t func_infos[] = { F1("pg_result_error", MAY_BE_FALSE | MAY_BE_STRING), F1("pg_result_error_field", MAY_BE_NULL | MAY_BE_FALSE | MAY_BE_STRING), F1("pg_get_result", MAY_BE_FALSE | MAY_BE_RESOURCE), - F1("pg_result_status", MAY_BE_FALSE | MAY_BE_LONG | MAY_BE_STRING), + F1("pg_result_status", MAY_BE_LONG | MAY_BE_STRING), F1("pg_get_notify", MAY_BE_FALSE | MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_ANY), F1("pg_socket", MAY_BE_FALSE | MAY_BE_RESOURCE), F1("pg_meta_data", MAY_BE_FALSE | MAY_BE_ARRAY | MAY_BE_ARRAY_KEY_STRING | MAY_BE_ARRAY_OF_ARRAY), diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c index 72dc2992198e7..46363acb7b2e1 100644 --- a/ext/opcache/ZendAccelerator.c +++ b/ext/opcache/ZendAccelerator.c @@ -2734,12 +2734,16 @@ static void accel_gen_system_id(void) */ ZEND_HASH_FOREACH_PTR(&module_registry, module) { PHP_MD5Update(&context, module->name, strlen(module->name)); - PHP_MD5Update(&context, module->version, strlen(module->version)); + if (module->version != NULL) { + PHP_MD5Update(&context, module->version, strlen(module->version)); + } } ZEND_HASH_FOREACH_END(); extension = (zend_extension *) zend_llist_get_first_ex(&zend_extensions, &pos); while (extension) { PHP_MD5Update(&context, extension->name, strlen(extension->name)); - PHP_MD5Update(&context, extension->version, strlen(extension->version)); + if (extension->version != NULL) { + PHP_MD5Update(&context, extension->version, strlen(extension->version)); + } extension = (zend_extension *) zend_llist_get_next_ex(&zend_extensions, &pos); } PHP_MD5Final(digest, &context); diff --git a/ext/opcache/jit/zend_jit.c b/ext/opcache/jit/zend_jit.c index 2ed83d0efe008..0ad3d3883eea7 100644 --- a/ext/opcache/jit/zend_jit.c +++ b/ext/opcache/jit/zend_jit.c @@ -22,6 +22,7 @@ #include "Zend/zend_vm.h" #include "Zend/zend_exceptions.h" #include "Zend/zend_constants.h" +#include "Zend/zend_closures.h" #include "Zend/zend_ini.h" #include "zend_smart_str.h" #include "jit/zend_jit.h" @@ -2457,10 +2458,98 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op goto jit_failure; } goto done; - case ZEND_ASSIGN_OBJ: - if (opline->op1_type == IS_VAR) { + case ZEND_PRE_INC_OBJ: + case ZEND_PRE_DEC_OBJ: + case ZEND_POST_INC_OBJ: + case ZEND_POST_DEC_OBJ: + if (opline->op2_type != IS_CONST + || Z_TYPE_P(RT_CONSTANT(opline, opline->op2)) != IS_STRING + || Z_STRVAL_P(RT_CONSTANT(opline, opline->op2))[0] == '\0') { break; } + if (PROFITABILITY_CHECKS && (!ssa->ops || !ssa->var_info)) { + break; + } + ce = NULL; + ce_is_instanceof = 0; + if (opline->op1_type == IS_UNUSED) { + op1_info = MAY_BE_OBJECT|MAY_BE_RC1|MAY_BE_RCN; + ce = op_array->scope; + ce_is_instanceof = (ce->ce_flags & ZEND_ACC_FINAL) != 0; + op1_addr = 0; + } else { + op1_info = OP1_INFO(); + if (!(op1_info & MAY_BE_OBJECT)) { + break; + } + op1_addr = OP1_REG_ADDR(); + if (ssa->var_info && ssa->ops) { + zend_ssa_op *ssa_op = &ssa->ops[opline - op_array->opcodes]; + if (ssa_op->op1_use >= 0) { + zend_ssa_var_info *op1_ssa = ssa->var_info + ssa_op->op1_use; + if (op1_ssa->ce && !op1_ssa->ce->create_object) { + ce = op1_ssa->ce; + ce_is_instanceof = op1_ssa->is_instanceof; + } + } + } + } + if (!zend_jit_incdec_obj(&dasm_state, opline, op_array, ssa, ssa_op, + op1_info, op1_addr, + 0, ce, ce_is_instanceof, 0, NULL, + zend_may_throw(opline, ssa_op, op_array, ssa))) { + goto jit_failure; + } + goto done; + case ZEND_ASSIGN_OBJ_OP: + if (opline->extended_value == ZEND_POW + || opline->extended_value == ZEND_DIV) { + // TODO: check for division by zero ??? + break; + } + if (opline->result_type != IS_UNUSED) { + break; + } + if (opline->op2_type != IS_CONST + || Z_TYPE_P(RT_CONSTANT(opline, opline->op2)) != IS_STRING + || Z_STRVAL_P(RT_CONSTANT(opline, opline->op2))[0] == '\0') { + break; + } + if (PROFITABILITY_CHECKS && (!ssa->ops || !ssa->var_info)) { + break; + } + ce = NULL; + ce_is_instanceof = 0; + if (opline->op1_type == IS_UNUSED) { + op1_info = MAY_BE_OBJECT|MAY_BE_RC1|MAY_BE_RCN; + ce = op_array->scope; + ce_is_instanceof = (ce->ce_flags & ZEND_ACC_FINAL) != 0; + op1_addr = 0; + } else { + op1_info = OP1_INFO(); + if (!(op1_info & MAY_BE_OBJECT)) { + break; + } + op1_addr = OP1_REG_ADDR(); + if (ssa->var_info && ssa->ops) { + zend_ssa_op *ssa_op = &ssa->ops[opline - op_array->opcodes]; + if (ssa_op->op1_use >= 0) { + zend_ssa_var_info *op1_ssa = ssa->var_info + ssa_op->op1_use; + if (op1_ssa->ce && !op1_ssa->ce->create_object) { + ce = op1_ssa->ce; + ce_is_instanceof = op1_ssa->is_instanceof; + } + } + } + } + if (!zend_jit_assign_obj_op(&dasm_state, opline, op_array, ssa, ssa_op, + op1_info, op1_addr, OP1_DATA_INFO(), OP1_DATA_RANGE(), + 0, ce, ce_is_instanceof, 0, NULL, + zend_may_throw(opline, ssa_op, op_array, ssa))) { + goto jit_failure; + } + goto done; + case ZEND_ASSIGN_OBJ: if (opline->op2_type != IS_CONST || Z_TYPE_P(RT_CONSTANT(opline, opline->op2)) != IS_STRING || Z_STRVAL_P(RT_CONSTANT(opline, opline->op2))[0] == '\0') { @@ -3026,7 +3115,7 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op if ((op1_info & (MAY_BE_UNDEF|MAY_BE_ANY|MAY_BE_REF)) != MAY_BE_STRING) { break; } - if (!zend_jit_strlen(&dasm_state, opline, op1_info)) { + if (!zend_jit_strlen(&dasm_state, opline, op1_info, OP1_REG_ADDR())) { goto jit_failure; } goto done; @@ -3087,6 +3176,41 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op goto jit_failure; } goto done; + case ZEND_INIT_METHOD_CALL: + if (opline->op2_type != IS_CONST + || Z_TYPE_P(RT_CONSTANT(opline, opline->op2)) != IS_STRING) { + break; + } + ce = NULL; + ce_is_instanceof = 0; + if (opline->op1_type == IS_UNUSED) { + op1_info = MAY_BE_OBJECT|MAY_BE_RC1|MAY_BE_RCN; + op1_addr = 0; + ce = op_array->scope; + ce_is_instanceof = (ce->ce_flags & ZEND_ACC_FINAL) != 0; + } else { + op1_info = OP1_INFO(); + if (!(op1_info & MAY_BE_OBJECT)) { + break; + } + op1_addr = OP1_REG_ADDR(); + if (ssa->var_info && ssa->ops) { + zend_ssa_op *ssa_op = &ssa->ops[opline - op_array->opcodes]; + if (ssa_op->op1_use >= 0) { + zend_ssa_var_info *op1_ssa = ssa->var_info + ssa_op->op1_use; + if (op1_ssa->ce && !op1_ssa->ce->create_object) { + ce = op1_ssa->ce; + ce_is_instanceof = op1_ssa->is_instanceof; + } + } + } + } + if (!zend_jit_init_method_call(&dasm_state, opline, b, op_array, ssa, ssa_op, call_level, + op1_info, op1_addr, ce, ce_is_instanceof, 0, NULL, + NULL)) { + goto jit_failure; + } + goto done; default: break; } @@ -3518,24 +3642,6 @@ static int zend_jit_setup_hot_counters(zend_op_array *op_array) return SUCCESS; } -static int zend_needs_manual_jit(const zend_op_array *op_array) -{ - if (op_array->doc_comment) { - const char *s = ZSTR_VAL(op_array->doc_comment); - const char *p = strstr(s, "@jit"); - - if (p) { - size_t l = ZSTR_LEN(op_array->doc_comment); - - if ((p == s + 3 || *(p-1) <= ' ') && - (p + 6 == s + l || *(p+4) <= ' ')) { - return 1; - } - } - } - return 0; -} - #include "jit/zend_jit_trace.c" ZEND_EXT_API int zend_jit_op_array(zend_op_array *op_array, zend_script *script) @@ -3589,12 +3695,6 @@ ZEND_EXT_API int zend_jit_op_array(zend_op_array *op_array, zend_script *script) return zend_jit_setup_hot_trace_counters(op_array); } else if (JIT_G(trigger) == ZEND_JIT_ON_SCRIPT_LOAD) { return zend_real_jit_func(op_array, script, NULL); - } else if (JIT_G(trigger) == ZEND_JIT_ON_DOC_COMMENT) { - if (zend_needs_manual_jit(op_array)) { - return zend_real_jit_func(op_array, script, NULL); - } else { - return SUCCESS; - } } else { ZEND_UNREACHABLE(); } @@ -3629,21 +3729,7 @@ ZEND_EXT_API int zend_jit_script(zend_script *script) goto jit_failure; } } - } else if (JIT_G(trigger) == ZEND_JIT_ON_SCRIPT_LOAD || - JIT_G(trigger) == ZEND_JIT_ON_DOC_COMMENT) { - - if (JIT_G(trigger) == ZEND_JIT_ON_DOC_COMMENT) { - int do_jit = 0; - for (i = 0; i < call_graph.op_arrays_count; i++) { - if (zend_needs_manual_jit(call_graph.op_arrays[i])) { - do_jit = 1; - break; - } - } - if (!do_jit) { - goto jit_failure; - } - } + } else if (JIT_G(trigger) == ZEND_JIT_ON_SCRIPT_LOAD) { for (i = 0; i < call_graph.op_arrays_count; i++) { info = ZEND_FUNC_INFO(call_graph.op_arrays[i]); if (info) { @@ -3665,10 +3751,6 @@ ZEND_EXT_API int zend_jit_script(zend_script *script) } for (i = 0; i < call_graph.op_arrays_count; i++) { - if (JIT_G(trigger) == ZEND_JIT_ON_DOC_COMMENT && - !zend_needs_manual_jit(call_graph.op_arrays[i])) { - continue; - } info = ZEND_FUNC_INFO(call_graph.op_arrays[i]); if (info) { if (zend_jit_op_array_analyze2(call_graph.op_arrays[i], script, &info->ssa, ZCG(accel_directives).optimization_level) != SUCCESS) { @@ -3680,10 +3762,6 @@ ZEND_EXT_API int zend_jit_script(zend_script *script) if (JIT_G(debug) & ZEND_JIT_DEBUG_SSA) { for (i = 0; i < call_graph.op_arrays_count; i++) { - if (JIT_G(trigger) == ZEND_JIT_ON_DOC_COMMENT && - !zend_needs_manual_jit(call_graph.op_arrays[i])) { - continue; - } info = ZEND_FUNC_INFO(call_graph.op_arrays[i]); if (info) { zend_dump_op_array(call_graph.op_arrays[i], ZEND_DUMP_HIDE_UNREACHABLE|ZEND_DUMP_RC_INFERENCE|ZEND_DUMP_SSA, "JIT", &info->ssa); @@ -3692,10 +3770,6 @@ ZEND_EXT_API int zend_jit_script(zend_script *script) } for (i = 0; i < call_graph.op_arrays_count; i++) { - if (JIT_G(trigger) == ZEND_JIT_ON_DOC_COMMENT && - !zend_needs_manual_jit(call_graph.op_arrays[i])) { - continue; - } info = ZEND_FUNC_INFO(call_graph.op_arrays[i]); if (info) { if (zend_jit(call_graph.op_arrays[i], &info->ssa, NULL) != SUCCESS) { @@ -3736,8 +3810,7 @@ ZEND_EXT_API int zend_jit_script(zend_script *script) return SUCCESS; jit_failure: - if (JIT_G(trigger) == ZEND_JIT_ON_SCRIPT_LOAD || - JIT_G(trigger) == ZEND_JIT_ON_DOC_COMMENT) { + if (JIT_G(trigger) == ZEND_JIT_ON_SCRIPT_LOAD) { for (i = 0; i < call_graph.op_arrays_count; i++) { ZEND_SET_FUNC_INFO(call_graph.op_arrays[i], NULL); } diff --git a/ext/opcache/jit/zend_jit_disasm_x86.c b/ext/opcache/jit/zend_jit_disasm_x86.c index ffe290dc4b537..07884ad03a52c 100644 --- a/ext/opcache/jit/zend_jit_disasm_x86.c +++ b/ext/opcache/jit/zend_jit_disasm_x86.c @@ -398,6 +398,11 @@ static int zend_jit_disasm_init(void) REGISTER_HELPER(zend_jit_init_func_run_time_cache_helper); REGISTER_HELPER(zend_jit_find_func_helper); REGISTER_HELPER(zend_jit_find_ns_func_helper); + REGISTER_HELPER(zend_jit_find_method_helper); + REGISTER_HELPER(zend_jit_push_static_metod_call_frame); + REGISTER_HELPER(zend_jit_push_static_metod_call_frame_tmp); + REGISTER_HELPER(zend_jit_invalid_method_call); + REGISTER_HELPER(zend_jit_unref_helper); REGISTER_HELPER(zend_jit_extend_stack_helper); REGISTER_HELPER(zend_jit_int_extend_stack_helper); REGISTER_HELPER(zend_jit_leave_nested_func_helper); @@ -456,7 +461,9 @@ static int zend_jit_disasm_init(void) REGISTER_HELPER(zend_jit_invalid_array_access); REGISTER_HELPER(zend_jit_invalid_property_read); REGISTER_HELPER(zend_jit_invalid_property_write); + REGISTER_HELPER(zend_jit_invalid_property_incdec); REGISTER_HELPER(zend_jit_invalid_property_assign); + REGISTER_HELPER(zend_jit_invalid_property_assign_op); REGISTER_HELPER(zend_jit_prepare_assign_dim_ref); REGISTER_HELPER(zend_jit_pre_inc); REGISTER_HELPER(zend_jit_pre_dec); @@ -468,7 +475,19 @@ static int zend_jit_disasm_init(void) REGISTER_HELPER(zend_jit_zval_array_dup); REGISTER_HELPER(zend_jit_add_arrays_helper); REGISTER_HELPER(zend_jit_assign_obj_helper); + REGISTER_HELPER(zend_jit_assign_obj_op_helper); REGISTER_HELPER(zend_jit_assign_to_typed_prop); + REGISTER_HELPER(zend_jit_assign_op_to_typed_prop); + REGISTER_HELPER(zend_jit_inc_typed_prop); + REGISTER_HELPER(zend_jit_dec_typed_prop); + REGISTER_HELPER(zend_jit_pre_inc_typed_prop); + REGISTER_HELPER(zend_jit_pre_dec_typed_prop); + REGISTER_HELPER(zend_jit_post_inc_typed_prop); + REGISTER_HELPER(zend_jit_post_dec_typed_prop); + REGISTER_HELPER(zend_jit_pre_inc_obj_helper); + REGISTER_HELPER(zend_jit_pre_dec_obj_helper); + REGISTER_HELPER(zend_jit_post_inc_obj_helper); + REGISTER_HELPER(zend_jit_post_dec_obj_helper); #undef REGISTER_HELPER #ifndef _WIN32 diff --git a/ext/opcache/jit/zend_jit_helpers.c b/ext/opcache/jit/zend_jit_helpers.c index 995b69c57e929..03e4041f0aab1 100644 --- a/ext/opcache/jit/zend_jit_helpers.c +++ b/ext/opcache/jit/zend_jit_helpers.c @@ -90,6 +90,109 @@ static zend_function* ZEND_FASTCALL zend_jit_find_ns_func_helper(zval *func_name return fbc; } +static ZEND_COLD void ZEND_FASTCALL zend_jit_invalid_method_call(zval *object) +{ + zend_execute_data *execute_data = EG(current_execute_data); + const zend_op *opline = EX(opline); + zval *function_name = function_name = RT_CONSTANT(opline, opline->op2);; + + if (Z_TYPE_P(object) == IS_UNDEF && opline->op1_type == IS_CV) { + zend_string *cv = EX(func)->op_array.vars[EX_VAR_TO_NUM(opline->op1.var)]; + + zend_error(E_WARNING, "Undefined variable $%s", ZSTR_VAL(cv)); + if (UNEXPECTED(EG(exception) != NULL)) { + return; + } + object = &EG(uninitialized_zval); + } + zend_throw_error(NULL, "Call to a member function %s() on %s", + Z_STRVAL_P(function_name), zend_zval_type_name(object)); + if (opline->op1_type & (IS_VAR|IS_TMP_VAR)) { + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + } +} + +static zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_undefined_method(const zend_class_entry *ce, const zend_string *method) +{ + zend_throw_error(NULL, "Call to undefined method %s::%s()", ZSTR_VAL(ce->name), ZSTR_VAL(method)); +} + +static void ZEND_FASTCALL zend_jit_unref_helper(zval *zv) +{ + zend_reference *ref; + + ZEND_ASSERT(Z_ISREF_P(zv)); + ref = Z_REF_P(zv); + ZVAL_COPY_VALUE(zv, &ref->val); + if (GC_DELREF(ref) == 0) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_TRY_ADDREF_P(zv); + } +} + +static zend_function* ZEND_FASTCALL zend_jit_find_method_helper(zend_object *obj, zval *function_name, zend_object **obj_ptr) +{ + zend_execute_data *execute_data = EG(current_execute_data); + const zend_op *opline = EX(opline); + zend_class_entry *called_scope = obj->ce; + zend_object *orig_obj = obj; + zend_function *fbc; + + fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), function_name + 1); + if (UNEXPECTED(fbc == NULL)) { + if (EXPECTED(!EG(exception))) { + zend_undefined_method(called_scope, Z_STR_P(function_name)); + } + if ((opline->op1_type & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(orig_obj) == 0) { + zend_objects_store_del(orig_obj); + } + return NULL; + } + + if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { + zend_init_func_run_time_cache(&fbc->op_array); + } + + if (UNEXPECTED(obj != orig_obj)) { + if (opline->op1_type & (IS_VAR|IS_TMP_VAR)) { + GC_ADDREF(obj); + if (GC_DELREF(orig_obj) == 0) { + zend_objects_store_del(orig_obj); + } + } + *obj_ptr = obj; + return fbc; + } + + if (EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE)))) { + CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); + } + + return fbc; +} + +static zend_execute_data* ZEND_FASTCALL zend_jit_push_static_metod_call_frame(zend_object *obj, zend_function *fbc, uint32_t num_args) +{ + zend_class_entry *scope = obj->ce; + + return zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION, fbc, num_args, scope); +} + +static zend_execute_data* ZEND_FASTCALL zend_jit_push_static_metod_call_frame_tmp(zend_object *obj, zend_function *fbc, uint32_t num_args) +{ + zend_class_entry *scope = obj->ce; + + if (GC_DELREF(obj) == 0) { + zend_objects_store_del(obj); + if (UNEXPECTED(EG(exception))) { + return NULL; + } + } + + return zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION, fbc, num_args, scope); +} + static zend_execute_data* ZEND_FASTCALL zend_jit_extend_stack_helper(uint32_t used_stack, zend_function *fbc) { zend_execute_data *call = (zend_execute_data*)zend_vm_stack_extend(used_stack); @@ -1748,8 +1851,9 @@ static ZEND_COLD void zend_jit_throw_incdec_ref_error(zend_reference *ref, zend_ inc ? "max" : "min"); } -static void ZEND_FASTCALL zend_jit_pre_inc_typed_ref(zval *var_ptr, zend_reference *ref, zval *ret) +static void ZEND_FASTCALL zend_jit_pre_inc_typed_ref(zend_reference *ref, zval *ret) { + zval *var_ptr = &ref->val; zval tmp; ZVAL_COPY(&tmp, var_ptr); @@ -1770,8 +1874,9 @@ static void ZEND_FASTCALL zend_jit_pre_inc_typed_ref(zval *var_ptr, zend_referen } } -static void ZEND_FASTCALL zend_jit_pre_dec_typed_ref(zval *var_ptr, zend_reference *ref, zval *ret) +static void ZEND_FASTCALL zend_jit_pre_dec_typed_ref(zend_reference *ref, zval *ret) { + zval *var_ptr = &ref->val; zval tmp; ZVAL_COPY(&tmp, var_ptr); @@ -1792,8 +1897,9 @@ static void ZEND_FASTCALL zend_jit_pre_dec_typed_ref(zval *var_ptr, zend_referen } } -static void ZEND_FASTCALL zend_jit_post_inc_typed_ref(zval *var_ptr, zend_reference *ref, zval *ret) +static void ZEND_FASTCALL zend_jit_post_inc_typed_ref(zend_reference *ref, zval *ret) { + zval *var_ptr = &ref->val; ZVAL_COPY(ret, var_ptr); increment_function(var_ptr); @@ -1807,8 +1913,9 @@ static void ZEND_FASTCALL zend_jit_post_inc_typed_ref(zval *var_ptr, zend_refere } } -static void ZEND_FASTCALL zend_jit_post_dec_typed_ref(zval *var_ptr, zend_reference *ref, zval *ret) +static void ZEND_FASTCALL zend_jit_post_dec_typed_ref(zend_reference *ref, zval *ret) { + zval *var_ptr = &ref->val; ZVAL_COPY(ret, var_ptr); decrement_function(var_ptr); @@ -1858,6 +1965,13 @@ static void ZEND_FASTCALL zend_jit_invalid_property_write(zval *container, const property_name, zend_zval_type_name(container)); } +static void ZEND_FASTCALL zend_jit_invalid_property_incdec(zval *container, const char *property_name) +{ + zend_throw_error(NULL, + "Attempt to increment/decrement property \"%s\" on %s", + property_name, zend_zval_type_name(container)); +} + static void ZEND_FASTCALL zend_jit_invalid_property_assign(zval *container, const char *property_name) { zend_throw_error(NULL, @@ -1865,6 +1979,16 @@ static void ZEND_FASTCALL zend_jit_invalid_property_assign(zval *container, cons property_name, zend_zval_type_name(container)); } +static void ZEND_FASTCALL zend_jit_invalid_property_assign_op(zval *container, const char *property_name) +{ + if (Z_TYPE_P(container) == IS_UNDEF) { + const zend_execute_data *execute_data = EG(current_execute_data); + + zend_jit_undefined_op_helper(EX(opline)->op1.var); + } + zend_jit_invalid_property_assign(container, property_name); +} + static zval * ZEND_FASTCALL zend_jit_prepare_assign_dim_ref(zval *ref) { zval *val = Z_REFVAL_P(ref); if (Z_TYPE_P(val) <= IS_FALSE) { @@ -1965,3 +2089,510 @@ static void ZEND_FASTCALL zend_jit_assign_to_typed_prop(zval *property_val, zend ZVAL_COPY_DEREF(result, value); } } + +static zend_never_inline void _zend_jit_assign_op_overloaded_property(zend_object *object, zend_string *name, void **cache_slot, zval *value, binary_op_type binary_op) +{ + zval *z; + zval rv, res; + + GC_ADDREF(object); + z = object->handlers->read_property(object, name, BP_VAR_R, cache_slot, &rv); + if (UNEXPECTED(EG(exception))) { + OBJ_RELEASE(object); +//??? if (UNEXPECTED(RETURN_VALUE_USED(opline))) { +//??? ZVAL_UNDEF(EX_VAR(opline->result.var)); +//??? } + return; + } + if (binary_op(&res, z, value) == SUCCESS) { + object->handlers->write_property(object, name, &res, cache_slot); + } +//??? if (UNEXPECTED(RETURN_VALUE_USED(opline))) { +//??? ZVAL_COPY(EX_VAR(opline->result.var), &res); +//??? } + zval_ptr_dtor(z); + zval_ptr_dtor(&res); + OBJ_RELEASE(object); +} + +static void ZEND_FASTCALL zend_jit_assign_op_to_typed_prop(zval *zptr, zend_property_info *prop_info, zval *value, binary_op_type binary_op) +{ + zend_execute_data *execute_data = EG(current_execute_data); + zval z_copy; + + binary_op(&z_copy, zptr, value); + if (EXPECTED(zend_verify_property_type(prop_info, &z_copy, EX_USES_STRICT_TYPES()))) { + zval_ptr_dtor(zptr); + ZVAL_COPY_VALUE(zptr, &z_copy); + } else { + zval_ptr_dtor(&z_copy); + } +} + +static void ZEND_FASTCALL zend_jit_assign_obj_op_helper(zend_object *zobj, zend_string *name, zval *value, void **cache_slot, binary_op_type binary_op) +{ + zval *zptr; + zend_property_info *prop_info; + + if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { + if (UNEXPECTED(Z_ISERROR_P(zptr))) { +//??? if (UNEXPECTED(RETURN_VALUE_USED(opline))) { +//??? ZVAL_NULL(EX_VAR(opline->result.var)); +//??? } + } else { +//??? zval *orig_zptr = zptr; + zend_reference *ref; + + do { + if (UNEXPECTED(Z_ISREF_P(zptr))) { + ref = Z_REF_P(zptr); + zptr = Z_REFVAL_P(zptr); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_jit_assign_op_to_typed_ref(ref, value, binary_op); + break; + } + } + +//??? if (OP2_TYPE == IS_CONST) { + prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); +//??? } else { +//??? prop_info = zend_object_fetch_property_type_info(Z_OBJ_P(object), orig_zptr); +//??? } + if (UNEXPECTED(prop_info)) { + /* special case for typed properties */ + zend_jit_assign_op_to_typed_prop(zptr, prop_info, value, binary_op); + } else { + binary_op(zptr, zptr, value); + } + } while (0); + +//??? if (UNEXPECTED(RETURN_VALUE_USED(opline))) { +//??? ZVAL_COPY(EX_VAR(opline->result.var), zptr); +//??? } + } + } else { + _zend_jit_assign_op_overloaded_property(zobj, name, cache_slot, value, binary_op); + } +} + +static ZEND_COLD zend_long _zend_jit_throw_inc_prop_error(zend_property_info *prop) +{ + zend_string *type_str = zend_type_to_string(prop->type); + zend_type_error("Cannot increment property %s::$%s of type %s past its maximal value", + ZSTR_VAL(prop->ce->name), + zend_get_unmangled_property_name(prop->name), + ZSTR_VAL(type_str)); + zend_string_release(type_str); + return ZEND_LONG_MAX; +} + +static ZEND_COLD zend_long _zend_jit_throw_dec_prop_error(zend_property_info *prop) +{ + zend_string *type_str = zend_type_to_string(prop->type); + zend_type_error("Cannot decrement property %s::$%s of type %s past its minimal value", + ZSTR_VAL(prop->ce->name), + zend_get_unmangled_property_name(prop->name), + ZSTR_VAL(type_str)); + zend_string_release(type_str); + return ZEND_LONG_MIN; +} + +static void ZEND_FASTCALL zend_jit_inc_typed_prop(zval *var_ptr, zend_property_info *prop_info) +{ + zend_execute_data *execute_data = EG(current_execute_data); + zval tmp; + + ZVAL_COPY(&tmp, var_ptr); + + increment_function(var_ptr); + + if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_DOUBLE) && Z_TYPE(tmp) == IS_LONG) { + if (!(ZEND_TYPE_FULL_MASK(prop_info->type) & MAY_BE_DOUBLE)) { + zend_long val = _zend_jit_throw_inc_prop_error(prop_info); + ZVAL_LONG(var_ptr, val); + } + } else if (UNEXPECTED(!zend_verify_property_type(prop_info, var_ptr, EX_USES_STRICT_TYPES()))) { + zval_ptr_dtor(var_ptr); + ZVAL_COPY_VALUE(var_ptr, &tmp); + } else { + zval_ptr_dtor(&tmp); + } +} + +static void ZEND_FASTCALL zend_jit_dec_typed_prop(zval *var_ptr, zend_property_info *prop_info) +{ + zend_execute_data *execute_data = EG(current_execute_data); + zval tmp; + + ZVAL_COPY(&tmp, var_ptr); + + decrement_function(var_ptr); + + if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_DOUBLE) && Z_TYPE(tmp) == IS_LONG) { + if (!(ZEND_TYPE_FULL_MASK(prop_info->type) & MAY_BE_DOUBLE)) { + zend_long val = _zend_jit_throw_dec_prop_error(prop_info); + ZVAL_LONG(var_ptr, val); + } + } else if (UNEXPECTED(!zend_verify_property_type(prop_info, var_ptr, EX_USES_STRICT_TYPES()))) { + zval_ptr_dtor(var_ptr); + ZVAL_COPY_VALUE(var_ptr, &tmp); + } else { + zval_ptr_dtor(&tmp); + } +} + +static void ZEND_FASTCALL zend_jit_pre_inc_typed_prop(zval *var_ptr, zend_property_info *prop_info, zval *result) +{ + zend_execute_data *execute_data = EG(current_execute_data); + zval tmp; + + if (!result) { + result = &tmp; + } + + ZVAL_COPY(result, var_ptr); + + increment_function(var_ptr); + + if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_DOUBLE) && Z_TYPE_P(result) == IS_LONG) { + if (!(ZEND_TYPE_FULL_MASK(prop_info->type) & MAY_BE_DOUBLE)) { + zend_long val = _zend_jit_throw_inc_prop_error(prop_info); + ZVAL_LONG(var_ptr, val); + } + } else if (UNEXPECTED(!zend_verify_property_type(prop_info, var_ptr, EX_USES_STRICT_TYPES()))) { + zval_ptr_dtor(var_ptr); + ZVAL_COPY_VALUE(var_ptr, result); + ZVAL_UNDEF(result); + } else if (result == &tmp) { + zval_ptr_dtor(&tmp); + } + if (UNEXPECTED(result)) { + ZVAL_COPY(result, var_ptr); + } +} + +static void ZEND_FASTCALL zend_jit_pre_dec_typed_prop(zval *var_ptr, zend_property_info *prop_info, zval *result) +{ + zend_execute_data *execute_data = EG(current_execute_data); + zval tmp; + + if (!result) { + result = &tmp; + } + + ZVAL_COPY(result, var_ptr); + + decrement_function(var_ptr); + + if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_DOUBLE) && Z_TYPE_P(result) == IS_LONG) { + if (!(ZEND_TYPE_FULL_MASK(prop_info->type) & MAY_BE_DOUBLE)) { + zend_long val = _zend_jit_throw_dec_prop_error(prop_info); + ZVAL_LONG(var_ptr, val); + } + } else if (UNEXPECTED(!zend_verify_property_type(prop_info, var_ptr, EX_USES_STRICT_TYPES()))) { + zval_ptr_dtor(var_ptr); + ZVAL_COPY_VALUE(var_ptr, result); + ZVAL_UNDEF(result); + } else if (result == &tmp) { + zval_ptr_dtor(&tmp); + } + if (UNEXPECTED(result)) { + ZVAL_COPY(result, var_ptr); + } +} + +static void ZEND_FASTCALL zend_jit_post_inc_typed_prop(zval *var_ptr, zend_property_info *prop_info, zval *result) +{ + zend_execute_data *execute_data = EG(current_execute_data); + + ZVAL_COPY(result, var_ptr); + + increment_function(var_ptr); + + if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_DOUBLE) && Z_TYPE_P(result) == IS_LONG) { + if (!(ZEND_TYPE_FULL_MASK(prop_info->type) & MAY_BE_DOUBLE)) { + zend_long val = _zend_jit_throw_inc_prop_error(prop_info); + ZVAL_LONG(var_ptr, val); + } + } else if (UNEXPECTED(!zend_verify_property_type(prop_info, var_ptr, EX_USES_STRICT_TYPES()))) { + zval_ptr_dtor(var_ptr); + ZVAL_COPY_VALUE(var_ptr, result); + ZVAL_UNDEF(result); + } +} + +static void ZEND_FASTCALL zend_jit_post_dec_typed_prop(zval *var_ptr, zend_property_info *prop_info, zval *result) +{ + zend_execute_data *execute_data = EG(current_execute_data); + + ZVAL_COPY(result, var_ptr); + + decrement_function(var_ptr); + + if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_DOUBLE) && Z_TYPE_P(result) == IS_LONG) { + if (!(ZEND_TYPE_FULL_MASK(prop_info->type) & MAY_BE_DOUBLE)) { + zend_long val = _zend_jit_throw_dec_prop_error(prop_info); + ZVAL_LONG(var_ptr, val); + } + } else if (UNEXPECTED(!zend_verify_property_type(prop_info, var_ptr, EX_USES_STRICT_TYPES()))) { + zval_ptr_dtor(var_ptr); + ZVAL_COPY_VALUE(var_ptr, result); + ZVAL_UNDEF(result); + } +} + +static void ZEND_FASTCALL zend_jit_pre_inc_obj_helper(zend_object *zobj, zend_string *name, void **cache_slot, zval *result) +{ + zval *prop; + + if (EXPECTED((prop = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { + if (UNEXPECTED(Z_ISERROR_P(prop))) { + if (UNEXPECTED(result)) { + ZVAL_NULL(result); + } + } else { + zend_property_info *prop_info = (zend_property_info *) CACHED_PTR_EX(cache_slot + 2); + + if (EXPECTED(Z_TYPE_P(prop) == IS_LONG)) { + fast_long_increment_function(prop); + if (UNEXPECTED(Z_TYPE_P(prop) != IS_LONG) && UNEXPECTED(prop_info) + && !(ZEND_TYPE_FULL_MASK(prop_info->type) & MAY_BE_DOUBLE)) { + zend_long val = _zend_jit_throw_inc_prop_error(prop_info); + ZVAL_LONG(prop, val); + } + } else { + do { + if (Z_ISREF_P(prop)) { + zend_reference *ref = Z_REF_P(prop); + prop = Z_REFVAL_P(prop); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_jit_pre_inc_typed_ref(ref, result); + break; + } + } + + if (UNEXPECTED(prop_info)) { + zend_jit_pre_inc_typed_prop(prop, prop_info, result); + return; + } else { + increment_function(prop); + } + } while (0); + } + if (UNEXPECTED(result)) { + ZVAL_COPY(result, prop); + } + } + } else { + zval rv; + zval *z; + zval z_copy; + + GC_ADDREF(zobj); + z = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, &rv); + if (UNEXPECTED(EG(exception))) { + OBJ_RELEASE(zobj); + if (UNEXPECTED(result)) { + ZVAL_NULL(result); + } + return; + } + + ZVAL_COPY_DEREF(&z_copy, z); + increment_function(&z_copy); + if (UNEXPECTED(result)) { + ZVAL_COPY(result, &z_copy); + } + zobj->handlers->write_property(zobj, name, &z_copy, cache_slot); + OBJ_RELEASE(zobj); + zval_ptr_dtor(&z_copy); + zval_ptr_dtor(z); + } +} + +static void ZEND_FASTCALL zend_jit_pre_dec_obj_helper(zend_object *zobj, zend_string *name, void **cache_slot, zval *result) +{ + zval *prop; + + if (EXPECTED((prop = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { + if (UNEXPECTED(Z_ISERROR_P(prop))) { + if (UNEXPECTED(result)) { + ZVAL_NULL(result); + } + } else { + zend_property_info *prop_info = (zend_property_info *) CACHED_PTR_EX(cache_slot + 2); + + if (EXPECTED(Z_TYPE_P(prop) == IS_LONG)) { + fast_long_decrement_function(prop); + if (UNEXPECTED(Z_TYPE_P(prop) != IS_LONG) && UNEXPECTED(prop_info) + && !(ZEND_TYPE_FULL_MASK(prop_info->type) & MAY_BE_DOUBLE)) { + zend_long val = _zend_jit_throw_dec_prop_error(prop_info); + ZVAL_LONG(prop, val); + } + } else { + do { + if (Z_ISREF_P(prop)) { + zend_reference *ref = Z_REF_P(prop); + prop = Z_REFVAL_P(prop); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_jit_pre_dec_typed_ref(ref, result); + break; + } + } + + if (UNEXPECTED(prop_info)) { + zend_jit_pre_dec_typed_prop(prop, prop_info, result); + return; + } else { + decrement_function(prop); + } + } while (0); + } + if (UNEXPECTED(result)) { + ZVAL_COPY(result, prop); + } + } + } else { + zval rv; + zval *z; + zval z_copy; + + GC_ADDREF(zobj); + z = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, &rv); + if (UNEXPECTED(EG(exception))) { + OBJ_RELEASE(zobj); + if (UNEXPECTED(result)) { + ZVAL_NULL(result); + } + return; + } + + ZVAL_COPY_DEREF(&z_copy, z); + decrement_function(&z_copy); + if (UNEXPECTED(result)) { + ZVAL_COPY(result, &z_copy); + } + zobj->handlers->write_property(zobj, name, &z_copy, cache_slot); + OBJ_RELEASE(zobj); + zval_ptr_dtor(&z_copy); + zval_ptr_dtor(z); + } +} + +static void ZEND_FASTCALL zend_jit_post_inc_obj_helper(zend_object *zobj, zend_string *name, void **cache_slot, zval *result) +{ + zval *prop; + + if (EXPECTED((prop = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { + if (UNEXPECTED(Z_ISERROR_P(prop))) { + ZVAL_NULL(result); + } else { + zend_property_info *prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); + + if (EXPECTED(Z_TYPE_P(prop) == IS_LONG)) { + ZVAL_LONG(result, Z_LVAL_P(prop)); + fast_long_increment_function(prop); + if (UNEXPECTED(Z_TYPE_P(prop) != IS_LONG) && UNEXPECTED(prop_info) + && !(ZEND_TYPE_FULL_MASK(prop_info->type) & MAY_BE_DOUBLE)) { + zend_long val = _zend_jit_throw_inc_prop_error(prop_info); + ZVAL_LONG(prop, val); + } + } else { + if (Z_ISREF_P(prop)) { + zend_reference *ref = Z_REF_P(prop); + prop = Z_REFVAL_P(prop); + if (ZEND_REF_HAS_TYPE_SOURCES(ref)) { + zend_jit_post_inc_typed_ref(ref, result); + return; + } + } + + if (UNEXPECTED(prop_info)) { + zend_jit_post_inc_typed_prop(prop, prop_info, result); + } else { + ZVAL_COPY(result, prop); + increment_function(prop); + } + } + } + } else { + zval rv; + zval *z; + zval z_copy; + + GC_ADDREF(zobj); + z = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, &rv); + if (UNEXPECTED(EG(exception))) { + OBJ_RELEASE(zobj); + ZVAL_UNDEF(result); + return; + } + + ZVAL_COPY_DEREF(&z_copy, z); + ZVAL_COPY(result, &z_copy); + increment_function(&z_copy); + zobj->handlers->write_property(zobj, name, &z_copy, cache_slot); + OBJ_RELEASE(zobj); + zval_ptr_dtor(&z_copy); + zval_ptr_dtor(z); + } +} + +static void ZEND_FASTCALL zend_jit_post_dec_obj_helper(zend_object *zobj, zend_string *name, void **cache_slot, zval *result) +{ + zval *prop; + + if (EXPECTED((prop = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { + if (UNEXPECTED(Z_ISERROR_P(prop))) { + ZVAL_NULL(result); + } else { + zend_property_info *prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); + + if (EXPECTED(Z_TYPE_P(prop) == IS_LONG)) { + ZVAL_LONG(result, Z_LVAL_P(prop)); + fast_long_decrement_function(prop); + if (UNEXPECTED(Z_TYPE_P(prop) != IS_LONG) && UNEXPECTED(prop_info) + && !(ZEND_TYPE_FULL_MASK(prop_info->type) & MAY_BE_DOUBLE)) { + zend_long val = _zend_jit_throw_dec_prop_error(prop_info); + ZVAL_LONG(prop, val); + } + } else { + if (Z_ISREF_P(prop)) { + zend_reference *ref = Z_REF_P(prop); + prop = Z_REFVAL_P(prop); + if (ZEND_REF_HAS_TYPE_SOURCES(ref)) { + zend_jit_post_dec_typed_ref(ref, result); + return; + } + } + + if (UNEXPECTED(prop_info)) { + zend_jit_post_dec_typed_prop(prop, prop_info, result); + } else { + ZVAL_COPY(result, prop); + decrement_function(prop); + } + } + } + } else { + zval rv; + zval *z; + zval z_copy; + + GC_ADDREF(zobj); + z = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, &rv); + if (UNEXPECTED(EG(exception))) { + OBJ_RELEASE(zobj); + ZVAL_UNDEF(result); + return; + } + + ZVAL_COPY_DEREF(&z_copy, z); + ZVAL_COPY(result, &z_copy); + decrement_function(&z_copy); + zobj->handlers->write_property(zobj, name, &z_copy, cache_slot); + OBJ_RELEASE(zobj); + zval_ptr_dtor(&z_copy); + zval_ptr_dtor(z); + } +} diff --git a/ext/opcache/jit/zend_jit_internal.h b/ext/opcache/jit/zend_jit_internal.h index 18a3096204959..0bbdb949a8a7a 100644 --- a/ext/opcache/jit/zend_jit_internal.h +++ b/ext/opcache/jit/zend_jit_internal.h @@ -211,6 +211,7 @@ typedef enum _zend_jit_trace_stop { #define ZEND_JIT_EXIT_FREE_OP1 (1<<5) #define ZEND_JIT_EXIT_FREE_OP2 (1<<6) #define ZEND_JIT_EXIT_PACKED_GUARD (1<<7) +#define ZEND_JIT_EXIT_DYNAMIC_CALL (1<<8) /* exit because of polymorphic INTI_DYNAMIC_CALL call */ typedef union _zend_op_trace_info { zend_op dummy; /* the size of this structure must be the same as zend_op */ @@ -458,7 +459,7 @@ ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_jit_loop_trace_helper(ZEND_OPCODE_HAN int ZEND_FASTCALL zend_jit_trace_hot_root(zend_execute_data *execute_data, const zend_op *opline); int ZEND_FASTCALL zend_jit_trace_exit(uint32_t exit_num, zend_jit_registers_buf *regs); -zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *execute_data, const zend_op *opline, zend_jit_trace_rec *trace_buffer, uint8_t start, zend_bool is_megamorphc); +zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *execute_data, const zend_op *opline, zend_jit_trace_rec *trace_buffer, uint8_t start, uint32_t is_megamorphc); static zend_always_inline const zend_op* zend_jit_trace_get_exit_opline(zend_jit_trace_rec *trace, const zend_op *opline, zend_bool *exit_if_true) { diff --git a/ext/opcache/jit/zend_jit_trace.c b/ext/opcache/jit/zend_jit_trace.c index 30aa0a71fcde1..e8cc51cd7f3a7 100644 --- a/ext/opcache/jit/zend_jit_trace.c +++ b/ext/opcache/jit/zend_jit_trace.c @@ -1361,13 +1361,15 @@ static zend_ssa *zend_jit_trace_build_tssa(zend_jit_trace_rec *trace_buffer, uin level = 0; for (;;p++) { if (p->op == ZEND_JIT_TRACE_VM) { - uint8_t orig_op1_type, op1_type, op2_type, op3_type; + uint8_t orig_op1_type, orig_op2_type, op1_type, op2_type, op3_type; +// zend_class_entry *op1_ce = NULL; + zend_class_entry *op2_ce = NULL; // TODO: range inference ??? opline = p->opline; op1_type = orig_op1_type = p->op1_type; - op2_type = p->op2_type; + op2_type = orig_op2_type = p->op2_type; op3_type = p->op3_type; if (op1_type & (IS_TRACE_REFERENCE|IS_TRACE_INDIRECT)) { op1_type = IS_UNKNOWN; @@ -1383,11 +1385,11 @@ static zend_ssa *zend_jit_trace_build_tssa(zend_jit_trace_rec *trace_buffer, uin } if ((p+1)->op == ZEND_JIT_TRACE_OP1_TYPE) { - // TODO: support for recorded classes ??? +// op1_ce = (zend_class_entry*)(p+1)->ce; p++; } if ((p+1)->op == ZEND_JIT_TRACE_OP2_TYPE) { - // TODO: support for recorded classes ??? + op2_ce = (zend_class_entry*)(p+1)->ce; p++; } @@ -1422,17 +1424,35 @@ static zend_ssa *zend_jit_trace_build_tssa(zend_jit_trace_rec *trace_buffer, uin } else if (orig_op1_type != IS_UNKNOWN && (orig_op1_type & IS_TRACE_INDIRECT) && opline->result_type == IS_UNUSED) { -// ADD_OP1_DATA_TRACE_GUARD(); + if (opline->opcode == ZEND_ASSIGN_DIM_OP) { + ADD_OP1_DATA_TRACE_GUARD(); + } ADD_OP2_TRACE_GUARD(); } break; + case ZEND_ASSIGN_OBJ_OP: + if (opline->extended_value == ZEND_POW + || opline->extended_value == ZEND_DIV) { + // TODO: check for division by zero ??? + break; + } + if (opline->result_type != IS_UNUSED) { + break; + } + /* break missing intentionally */ case ZEND_ASSIGN_OBJ: + case ZEND_PRE_INC_OBJ: + case ZEND_PRE_DEC_OBJ: + case ZEND_POST_INC_OBJ: + case ZEND_POST_DEC_OBJ: if (opline->op2_type != IS_CONST || Z_TYPE_P(RT_CONSTANT(opline, opline->op2)) != IS_STRING || Z_STRVAL_P(RT_CONSTANT(opline, opline->op2))[0] == '\0') { break; } -// ADD_OP1_DATA_TRACE_GUARD(); + if (opline->opcode == ZEND_ASSIGN_OBJ_OP) { + ADD_OP1_DATA_TRACE_GUARD(); + } ADD_OP1_TRACE_GUARD(); break; case ZEND_IS_EQUAL: @@ -1683,6 +1703,18 @@ static zend_ssa *zend_jit_trace_build_tssa(zend_jit_trace_rec *trace_buffer, uin } ADD_OP1_TRACE_GUARD(); break; + case ZEND_INIT_METHOD_CALL: + if (opline->op2_type != IS_CONST + || Z_TYPE_P(RT_CONSTANT(opline, opline->op2)) != IS_STRING) { + break; + } + ADD_OP1_TRACE_GUARD(); + break; + case ZEND_INIT_DYNAMIC_CALL: + if (orig_op2_type == IS_OBJECT && op2_ce == zend_ce_closure) { + ADD_OP2_TRACE_GUARD(); + } + break; default: break; } @@ -3343,8 +3375,10 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par uint8_t op2_type = p->op2_type; uint8_t op3_type = p->op3_type; uint8_t orig_op1_type = op1_type; + uint8_t orig_op2_type = op2_type; zend_bool op1_indirect; zend_class_entry *op1_ce = NULL; + zend_class_entry *op2_ce = NULL; opline = p->opline; if (op1_type & (IS_TRACE_REFERENCE|IS_TRACE_INDIRECT)) { @@ -3365,7 +3399,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par p++; } if ((p+1)->op == ZEND_JIT_TRACE_OP2_TYPE) { - // TODO: support for recorded classes ??? + op2_ce = (zend_class_entry*)(p+1)->ce; p++; } @@ -3718,6 +3752,147 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par goto jit_failure; } goto done; + case ZEND_PRE_INC_OBJ: + case ZEND_PRE_DEC_OBJ: + case ZEND_POST_INC_OBJ: + case ZEND_POST_DEC_OBJ: + if (opline->op2_type != IS_CONST + || Z_TYPE_P(RT_CONSTANT(opline, opline->op2)) != IS_STRING + || Z_STRVAL_P(RT_CONSTANT(opline, opline->op2))[0] == '\0') { + break; + } + ce = NULL; + ce_is_instanceof = 0; + delayed_fetch_this = 0; + op1_indirect = 0; + if (opline->op1_type == IS_UNUSED) { + op1_info = MAY_BE_OBJECT|MAY_BE_RC1|MAY_BE_RCN; + ce = op_array->scope; + ce_is_instanceof = (ce->ce_flags & ZEND_ACC_FINAL) != 0; + op1_addr = 0; + } else { + if (ssa_op->op1_use >= 0) { + delayed_fetch_this = ssa->var_info[ssa_op->op1_use].delayed_fetch_this; + } + op1_info = OP1_INFO(); + if (!(op1_info & MAY_BE_OBJECT)) { + break; + } + op1_addr = OP1_REG_ADDR(); + if (opline->op1_type == IS_VAR) { + if (orig_op1_type != IS_UNKNOWN + && (orig_op1_type & IS_TRACE_INDIRECT)) { + op1_indirect = 1; + if (!zend_jit_fetch_indirect_var(&dasm_state, opline, orig_op1_type, + &op1_info, &op1_addr, !ssa->var_info[ssa_op->op1_use].indirect_reference)) { + goto jit_failure; + } + } + } + if (orig_op1_type != IS_UNKNOWN + && (orig_op1_type & IS_TRACE_REFERENCE)) { + if (!zend_jit_fetch_reference(&dasm_state, opline, orig_op1_type, &op1_info, &op1_addr, + !ssa->var_info[ssa_op->op1_use].guarded_reference, 1)) { + goto jit_failure; + } + if (opline->op1_type == IS_CV + && zend_jit_var_may_alias(op_array, op_array_ssa, EX_VAR_TO_NUM(opline->op1.var)) == NO_ALIAS) { + ssa->var_info[ssa_op->op1_use].guarded_reference = 1; + } + } else { + CHECK_OP1_TRACE_TYPE(); + } + if (ssa->var_info && ssa->ops) { + if (ssa_op->op1_use >= 0) { + zend_ssa_var_info *op1_ssa = ssa->var_info + ssa_op->op1_use; + if (op1_ssa->ce && !op1_ssa->ce->create_object) { + ce = op1_ssa->ce; + ce_is_instanceof = op1_ssa->is_instanceof; + } + } + } + } + if (!zend_jit_incdec_obj(&dasm_state, opline, op_array, ssa, ssa_op, + op1_info, op1_addr, + op1_indirect, ce, ce_is_instanceof, delayed_fetch_this, op1_ce, + zend_may_throw(opline, ssa_op, op_array, ssa))) { + goto jit_failure; + } + goto done; + case ZEND_ASSIGN_OBJ_OP: + if (opline->extended_value == ZEND_POW + || opline->extended_value == ZEND_DIV) { + // TODO: check for division by zero ??? + break; + } + if (opline->result_type != IS_UNUSED) { + break; + } + if (opline->op2_type != IS_CONST + || Z_TYPE_P(RT_CONSTANT(opline, opline->op2)) != IS_STRING + || Z_STRVAL_P(RT_CONSTANT(opline, opline->op2))[0] == '\0') { + break; + } + ce = NULL; + ce_is_instanceof = 0; + delayed_fetch_this = 0; + op1_indirect = 0; + if (opline->op1_type == IS_UNUSED) { + op1_info = MAY_BE_OBJECT|MAY_BE_RC1|MAY_BE_RCN; + ce = op_array->scope; + ce_is_instanceof = (ce->ce_flags & ZEND_ACC_FINAL) != 0; + op1_addr = 0; + } else { + if (ssa_op->op1_use >= 0) { + delayed_fetch_this = ssa->var_info[ssa_op->op1_use].delayed_fetch_this; + } + op1_info = OP1_INFO(); + if (!(op1_info & MAY_BE_OBJECT)) { + break; + } + op1_addr = OP1_REG_ADDR(); + if (opline->op1_type == IS_VAR) { + if (orig_op1_type != IS_UNKNOWN + && (orig_op1_type & IS_TRACE_INDIRECT)) { + op1_indirect = 1; + if (!zend_jit_fetch_indirect_var(&dasm_state, opline, orig_op1_type, + &op1_info, &op1_addr, !ssa->var_info[ssa_op->op1_use].indirect_reference)) { + goto jit_failure; + } + } + } + if (orig_op1_type != IS_UNKNOWN + && (orig_op1_type & IS_TRACE_REFERENCE)) { + if (!zend_jit_fetch_reference(&dasm_state, opline, orig_op1_type, &op1_info, &op1_addr, + !ssa->var_info[ssa_op->op1_use].guarded_reference, 1)) { + goto jit_failure; + } + if (opline->op1_type == IS_CV + && zend_jit_var_may_alias(op_array, op_array_ssa, EX_VAR_TO_NUM(opline->op1.var)) == NO_ALIAS) { + ssa->var_info[ssa_op->op1_use].guarded_reference = 1; + } + } else { + CHECK_OP1_TRACE_TYPE(); + } + if (ssa->var_info && ssa->ops) { + if (ssa_op->op1_use >= 0) { + zend_ssa_var_info *op1_ssa = ssa->var_info + ssa_op->op1_use; + if (op1_ssa->ce && !op1_ssa->ce->create_object) { + ce = op1_ssa->ce; + ce_is_instanceof = op1_ssa->is_instanceof; + } + } + } + } + op1_data_info = OP1_DATA_INFO(); + CHECK_OP1_DATA_TRACE_TYPE(); + if (!zend_jit_assign_obj_op(&dasm_state, opline, op_array, ssa, ssa_op, + op1_info, op1_addr, op1_data_info, OP1_DATA_RANGE(), + op1_indirect, ce, ce_is_instanceof, delayed_fetch_this, op1_ce, + zend_may_throw(opline, ssa_op, op_array, ssa))) { + goto jit_failure; + } + goto done; case ZEND_ASSIGN_OBJ: if (opline->op2_type != IS_CONST || Z_TYPE_P(RT_CONSTANT(opline, opline->op2)) != IS_STRING @@ -4701,11 +4876,23 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par goto done; case ZEND_STRLEN: op1_info = OP1_INFO(); - CHECK_OP1_TRACE_TYPE(); - if ((op1_info & (MAY_BE_UNDEF|MAY_BE_ANY|MAY_BE_REF)) != MAY_BE_STRING) { - break; + op1_addr = OP1_REG_ADDR(); + if (orig_op1_type == (IS_TRACE_REFERENCE|IS_STRING)) { + if (!zend_jit_fetch_reference(&dasm_state, opline, orig_op1_type, &op1_info, &op1_addr, + !ssa->var_info[ssa_op->op1_use].guarded_reference, 1)) { + goto jit_failure; + } + if (opline->op1_type == IS_CV + && zend_jit_var_may_alias(op_array, op_array_ssa, EX_VAR_TO_NUM(opline->op1.var)) == NO_ALIAS) { + ssa->var_info[ssa_op->op1_use].guarded_reference = 1; + } + } else { + CHECK_OP1_TRACE_TYPE(); + if ((op1_info & (MAY_BE_UNDEF|MAY_BE_ANY|MAY_BE_REF)) != MAY_BE_STRING) { + break; + } } - if (!zend_jit_strlen(&dasm_state, opline, op1_info)) { + if (!zend_jit_strlen(&dasm_state, opline, op1_info, op1_addr)) { goto jit_failure; } goto done; @@ -4800,21 +4987,75 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par } 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)) { - goto jit_failure; + if (opline->op2_type != IS_CONST + || Z_TYPE_P(RT_CONSTANT(opline, opline->op2)) != IS_STRING) { + goto generic_dynamic_call; } - if ((p+1)->op == ZEND_JIT_TRACE_INIT_CALL && (p+1)->func) { - if (!zend_jit_init_fcall_guard(&dasm_state, 0, (p+1)->func, opline+1)) { - goto jit_failure; + delayed_fetch_this = 0; + ce = NULL; + ce_is_instanceof = 0; + if (opline->op1_type == IS_UNUSED) { + op1_info = MAY_BE_OBJECT|MAY_BE_RC1|MAY_BE_RCN; + ce = op_array->scope; + ce_is_instanceof = (ce->ce_flags & ZEND_ACC_FINAL) != 0; + op1_addr = 0; + } else { + op1_info = OP1_INFO(); + if (!(op1_info & MAY_BE_OBJECT)) { + goto generic_dynamic_call; + } + op1_addr = OP1_REG_ADDR(); + if (orig_op1_type != IS_UNKNOWN + && (orig_op1_type & IS_TRACE_REFERENCE)) { + if (!zend_jit_fetch_reference(&dasm_state, opline, orig_op1_type, &op1_info, &op1_addr, + !ssa->var_info[ssa_op->op1_use].guarded_reference, 1)) { + goto jit_failure; + } + if (opline->op1_type == IS_CV + && zend_jit_var_may_alias(op_array, op_array_ssa, EX_VAR_TO_NUM(opline->op1.var)) == NO_ALIAS) { + ssa->var_info[ssa_op->op1_use].guarded_reference = 1; + } + } else { + CHECK_OP1_TRACE_TYPE(); + } + if (ssa->var_info && ssa->ops) { + if (ssa_op->op1_use >= 0) { + zend_ssa_var_info *op1_ssa = ssa->var_info + ssa_op->op1_use; + if (op1_ssa->ce && !op1_ssa->ce->create_object) { + ce = op1_ssa->ce; + ce_is_instanceof = op1_ssa->is_instanceof; + } + } + } + if (ssa_op->op1_use >= 0) { + delayed_fetch_this = ssa->var_info[ssa_op->op1_use].delayed_fetch_this; } } + if (!zend_jit_init_method_call(&dasm_state, opline, + op_array_ssa->cfg.map ? op_array_ssa->cfg.map[opline - op_array->opcodes] : -1, + op_array, ssa, ssa_op, frame->call_level, + op1_info, op1_addr, ce, ce_is_instanceof, delayed_fetch_this, op1_ce, + p + 1)) { + goto jit_failure; + } + goto done; + case ZEND_INIT_DYNAMIC_CALL: + if (orig_op2_type != IS_OBJECT || op2_ce != zend_ce_closure) { + goto generic_dynamic_call; + } + op2_info = OP2_INFO(); + CHECK_OP2_TRACE_TYPE(); + if (!zend_jit_init_closure_call(&dasm_state, opline, op_array_ssa->cfg.map ? op_array_ssa->cfg.map[opline - op_array->opcodes] : -1, op_array, ssa, ssa_op, frame->call_level, p + 1)) { + goto jit_failure; + } goto done; case ZEND_INIT_STATIC_METHOD_CALL: +generic_dynamic_call: if (!zend_jit_trace_handler(&dasm_state, op_array, opline, zend_may_throw(opline, ssa_op, op_array, ssa), p + 1)) { goto jit_failure; } - if ((opline->op1_type != IS_CONST + if ((opline->opcode != ZEND_INIT_STATIC_METHOD_CALL + || opline->op1_type != IS_CONST || opline->op2_type != IS_CONST) && (p+1)->op == ZEND_JIT_TRACE_INIT_CALL && (p+1)->func) { if (!zend_jit_init_fcall_guard(&dasm_state, 0, (p+1)->func, opline+1)) { @@ -5887,7 +6128,7 @@ static void zend_jit_dump_exit_info(zend_jit_trace_info *t) if (t->exit_info[i].flags & ZEND_JIT_EXIT_RESTORE_CALL) { fprintf(stderr, "/CALL"); } - if (t->exit_info[i].flags & ZEND_JIT_EXIT_POLYMORPHISM) { + if (t->exit_info[i].flags & (ZEND_JIT_EXIT_POLYMORPHISM|ZEND_JIT_EXIT_DYNAMIC_CALL)) { fprintf(stderr, "/POLY"); } if (t->exit_info[i].flags & ZEND_JIT_EXIT_FREE_OP1) { @@ -6227,7 +6468,7 @@ int ZEND_FASTCALL zend_jit_trace_hot_side(zend_execute_data *execute_data, uint3 int ret = 0; uint32_t trace_num; zend_jit_trace_rec trace_buffer[ZEND_JIT_TRACE_MAX_LENGTH]; - zend_bool is_megamorphic = 0; + uint32_t is_megamorphic = 0; uint32_t polymorphism = 0; trace_num = ZEND_JIT_TRACE_NUM; @@ -6256,15 +6497,18 @@ int ZEND_FASTCALL zend_jit_trace_hot_side(zend_execute_data *execute_data, uint3 goto abort; } - if (EX(call) - && JIT_G(max_polymorphic_calls) > 0 - && (zend_jit_traces[parent_num].exit_info[exit_num].flags & ZEND_JIT_EXIT_POLYMORPHISM)) { - if (zend_jit_traces[parent_num].polymorphism >= JIT_G(max_polymorphic_calls) - 1) { - is_megamorphic = 1; - } else if (!zend_jit_traces[parent_num].polymorphism) { - polymorphism = 1; - } else if (exit_num == 0) { - polymorphism = zend_jit_traces[parent_num].polymorphism + 1; + if (JIT_G(max_polymorphic_calls) > 0) { + if ((zend_jit_traces[parent_num].exit_info[exit_num].flags & ZEND_JIT_EXIT_DYNAMIC_CALL) + || ((zend_jit_traces[parent_num].exit_info[exit_num].flags & ZEND_JIT_EXIT_POLYMORPHISM) + && EX(call))) { + if (zend_jit_traces[parent_num].polymorphism >= JIT_G(max_polymorphic_calls) - 1) { + is_megamorphic = zend_jit_traces[parent_num].exit_info[exit_num].flags & + (ZEND_JIT_EXIT_DYNAMIC_CALL | ZEND_JIT_EXIT_POLYMORPHISM); + } else if (!zend_jit_traces[parent_num].polymorphism) { + polymorphism = 1; + } else if (exit_num == 0) { + polymorphism = zend_jit_traces[parent_num].polymorphism + 1; + } } } diff --git a/ext/opcache/jit/zend_jit_vm_helpers.c b/ext/opcache/jit/zend_jit_vm_helpers.c index 88a4eeb3690a4..6cb8df08d9da1 100644 --- a/ext/opcache/jit/zend_jit_vm_helpers.c +++ b/ext/opcache/jit/zend_jit_vm_helpers.c @@ -474,7 +474,7 @@ static int zend_jit_trace_bad_loop_exit(const zend_op *opline) return 0; } -static int zend_jit_trace_record_fake_init_call_ex(zend_execute_data *call, zend_jit_trace_rec *trace_buffer, int idx, zend_bool is_megamorphic, uint32_t *megamorphic, uint32_t level, uint32_t init_level, uint32_t *call_level) +static int zend_jit_trace_record_fake_init_call_ex(zend_execute_data *call, zend_jit_trace_rec *trace_buffer, int idx, uint32_t is_megamorphic, uint32_t *megamorphic, uint32_t level, uint32_t init_level, uint32_t *call_level) { zend_jit_trace_stop stop ZEND_ATTRIBUTE_UNUSED = ZEND_JIT_TRACE_STOP_ERROR; @@ -507,7 +507,7 @@ static int zend_jit_trace_record_fake_init_call_ex(zend_execute_data *call, zend } func = (zend_function*)jit_extension->op_array; } - if (is_megamorphic + if (is_megamorphic == ZEND_JIT_EXIT_POLYMORPHISM /* TODO: use more accurate check ??? */ && ((ZEND_CALL_INFO(call) & ZEND_CALL_DYNAMIC) || func->common.scope)) { @@ -522,7 +522,7 @@ static int zend_jit_trace_record_fake_init_call_ex(zend_execute_data *call, zend return idx; } -static int zend_jit_trace_record_fake_init_call(zend_execute_data *call, zend_jit_trace_rec *trace_buffer, int idx, zend_bool is_megamorphic, uint32_t *megamorphic, uint32_t level) +static int zend_jit_trace_record_fake_init_call(zend_execute_data *call, zend_jit_trace_rec *trace_buffer, int idx, uint32_t is_megamorphic, uint32_t *megamorphic, uint32_t level) { uint32_t call_level = 0; @@ -570,7 +570,7 @@ static int zend_jit_trace_call_level(const zend_execute_data *call) * */ -zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex, const zend_op *op, zend_jit_trace_rec *trace_buffer, uint8_t start, zend_bool is_megamorphic) +zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex, const zend_op *op, zend_jit_trace_rec *trace_buffer, uint8_t start, uint32_t is_megamorphic) { #ifdef HAVE_GCC_GLOBAL_REGS @@ -929,6 +929,9 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex, if (JIT_G(max_polymorphic_calls) == 0 && zend_jit_may_be_polymorphic_call(opline - 1)) { func = NULL; + } else if (is_megamorphic == ZEND_JIT_EXIT_DYNAMIC_CALL + && trace_buffer[1].opline == opline - 1) { + func = NULL; } call_level = zend_jit_trace_call_level(EX(call)); ZEND_ASSERT(ret_level + level + call_level < 32); diff --git a/ext/opcache/jit/zend_jit_x86.dasc b/ext/opcache/jit/zend_jit_x86.dasc index aa193988082bb..927ed9081f14a 100644 --- a/ext/opcache/jit/zend_jit_x86.dasc +++ b/ext/opcache/jit/zend_jit_x86.dasc @@ -2665,7 +2665,9 @@ static int zend_jit_assign_const_stub(dasm_State **Dst) uint32_t val_info = MAY_BE_ANY|MAY_BE_RC1|MAY_BE_RCN; |->assign_const: - |.if X64 + |.if X64WIN + | sub r4, 0x28 + |.elif X64 | sub r4, 8 |.else | sub r4, 12 @@ -2677,7 +2679,9 @@ static int zend_jit_assign_const_stub(dasm_State **Dst) 0, 0)) { return 0; } - |.if X64 + |.if X64WIN + | add r4, 0x28 + |.elif X64 | add r4, 8 |.else | add r4, 12 @@ -2693,7 +2697,9 @@ static int zend_jit_assign_tmp_stub(dasm_State **Dst) uint32_t val_info = MAY_BE_ANY|MAY_BE_RC1|MAY_BE_RCN; |->assign_tmp: - |.if X64 + |.if X64WIN + | sub r4, 0x28 + |.elif X64 | sub r4, 8 |.else | sub r4, 12 @@ -2705,7 +2711,9 @@ static int zend_jit_assign_tmp_stub(dasm_State **Dst) 0, 0)) { return 0; } - |.if X64 + |.if X64WIN + | add r4, 0x28 + |.elif X64 | add r4, 8 |.else | add r4, 12 @@ -2721,7 +2729,9 @@ static int zend_jit_assign_var_stub(dasm_State **Dst) uint32_t val_info = MAY_BE_ANY|MAY_BE_RC1|MAY_BE_RCN|MAY_BE_REF; |->assign_var: - |.if X64 + |.if X64WIN + | sub r4, 0x28 + |.elif X64 | sub r4, 8 |.else | sub r4, 12 @@ -2733,7 +2743,9 @@ static int zend_jit_assign_var_stub(dasm_State **Dst) 0, 0)) { return 0; } - |.if X64 + |.if X64WIN + | add r4, 0x28 + |.elif X64 | add r4, 8 |.else | add r4, 12 @@ -2749,7 +2761,9 @@ static int zend_jit_assign_cv_noref_stub(dasm_State **Dst) uint32_t val_info = MAY_BE_ANY|MAY_BE_RC1|MAY_BE_RCN/*|MAY_BE_UNDEF*/; |->assign_cv_noref: - |.if X64 + |.if X64WIN + | sub r4, 0x28 + |.elif X64 | sub r4, 8 |.else | sub r4, 12 @@ -2761,7 +2775,9 @@ static int zend_jit_assign_cv_noref_stub(dasm_State **Dst) 0, 0)) { return 0; } - |.if X64 + |.if X64WIN + | add r4, 0x28 + |.elif X64 | add r4, 8 |.else | add r4, 12 @@ -2777,7 +2793,9 @@ static int zend_jit_assign_cv_stub(dasm_State **Dst) uint32_t val_info = MAY_BE_ANY|MAY_BE_RC1|MAY_BE_RCN|MAY_BE_REF/*|MAY_BE_UNDEF*/; |->assign_cv: - |.if X64 + |.if X64WIN + | sub r4, 0x28 + |.elif X64 | sub r4, 8 |.else | sub r4, 12 @@ -2789,7 +2807,9 @@ static int zend_jit_assign_cv_stub(dasm_State **Dst) 0, 0)) { return 0; } - |.if X64 + |.if X64WIN + | add r4, 0x28 + |.elif X64 | add r4, 8 |.else | add r4, 12 @@ -4044,24 +4064,14 @@ static int zend_jit_inc_dec(dasm_State **Dst, const zend_op *opline, uint32_t op | // ZVAL_DEREF(var_ptr); if (op1_info & MAY_BE_REF) { | IF_NOT_Z_TYPE, FCARG1a, IS_REFERENCE, >2 - | GET_Z_PTR FCARG2a, FCARG1a - | cmp aword [FCARG2a + offsetof(zend_reference, sources.ptr)], 0 - | lea FCARG1a, [FCARG2a + offsetof(zend_reference, val)] - | jz >2 - |.if X64 - if (RETURN_VALUE_USED(opline)) { - | LOAD_ZVAL_ADDR CARG3, res_addr - } else { - | mov CARG3, 0 - } - |.else - | sub r4, 12 - if (RETURN_VALUE_USED(opline)) { - | PUSH_ZVAL_ADDR res_addr, r0 - } else { - | push 0 - } - |.endif + | GET_Z_PTR FCARG1a, FCARG1a + | cmp aword [FCARG1a + offsetof(zend_reference, sources.ptr)], 0 + | jz >1 + if (RETURN_VALUE_USED(opline)) { + | LOAD_ZVAL_ADDR FCARG2a, res_addr + } else { + | xor FCARG2a, FCARG2a + } if (opline->opcode == ZEND_PRE_INC) { | EXT_CALL zend_jit_pre_inc_typed_ref, r0 } else if (opline->opcode == ZEND_PRE_DEC) { @@ -4073,11 +4083,10 @@ static int zend_jit_inc_dec(dasm_State **Dst, const zend_op *opline, uint32_t op } else { ZEND_UNREACHABLE(); } - |.if not(X64) - | add r4, 12 - |.endif zend_jit_check_exception(Dst); | jmp >3 + |1: + | lea FCARG1a, [FCARG1a + offsetof(zend_reference, val)] |2: } @@ -6431,7 +6440,7 @@ static int zend_jit_assign_dim_op(dasm_State **Dst, const zend_op *opline, uint3 IS_CV, opline->op1, var_addr, var_info, NULL, (opline+1)->op1_type, (opline+1)->op1, op3_addr, op1_data_info, op1_data_range, - 0, var_addr, op1_def_info, var_info, may_throw)) { + 0, var_addr, var_def_info, var_info, may_throw)) { return 0; } break; @@ -8459,7 +8468,16 @@ static int zend_jit_assign(dasm_State **Dst, const zend_op *opline, uint32_t op1 return 1; } -static int zend_jit_push_call_frame(dasm_State **Dst, const zend_op *opline, zend_function *func) +/* copy of hidden zend_closure */ +typedef struct _zend_closure { + zend_object std; + zend_function func; + zval this_ptr; + zend_class_entry *called_scope; + zif_handler orig_internal_handler; +} zend_closure; + +static int zend_jit_push_call_frame(dasm_State **Dst, const zend_op *opline, zend_function *func, zend_bool is_closure) { uint32_t used_stack; @@ -8469,15 +8487,26 @@ static int zend_jit_push_call_frame(dasm_State **Dst, const zend_op *opline, zen used_stack = (ZEND_CALL_FRAME_SLOT + opline->extended_value) * sizeof(zval); | // if (EXPECTED(ZEND_USER_CODE(func->type))) { - | test byte [r0 + offsetof(zend_function, type)], 1 - | mov FCARG1a, used_stack - | jnz >1 + if (!is_closure) { + | test byte [r0 + offsetof(zend_function, type)], 1 + | mov FCARG1a, used_stack + | jnz >1 + } else { + | mov FCARG1a, used_stack + } | // used_stack += (func->op_array.last_var + func->op_array.T - MIN(func->op_array.num_args, num_args)) * sizeof(zval); | mov edx, opline->extended_value - | cmp edx, dword [r0 + offsetof(zend_function, op_array.num_args)] - | cmova edx, dword [r0 + offsetof(zend_function, op_array.num_args)] - | sub edx, dword [r0 + offsetof(zend_function, op_array.last_var)] - | sub edx, dword [r0 + offsetof(zend_function, op_array.T)] + if (!is_closure) { + | cmp edx, dword [r0 + offsetof(zend_function, op_array.num_args)] + | cmova edx, dword [r0 + offsetof(zend_function, op_array.num_args)] + | sub edx, dword [r0 + offsetof(zend_function, op_array.last_var)] + | sub edx, dword [r0 + offsetof(zend_function, op_array.T)] + } else { + | cmp edx, dword [r0 + offsetof(zend_closure, func.op_array.num_args)] + | cmova edx, dword [r0 + offsetof(zend_closure, func.op_array.num_args)] + | sub edx, dword [r0 + offsetof(zend_closure, func.op_array.last_var)] + | sub edx, dword [r0 + offsetof(zend_closure, func.op_array.T)] + } | shl edx, 5 |.if X64 | movsxd r2, edx @@ -8513,7 +8542,6 @@ 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: - | SET_EX_OPLINE opline, r0 if (func) { | mov FCARG1d, used_stack } @@ -8522,9 +8550,15 @@ static int zend_jit_push_call_frame(dasm_State **Dst, const zend_op *opline, zen #else if (func && func->type == ZEND_INTERNAL_FUNCTION) { #endif + | SET_EX_OPLINE opline, r0 | EXT_CALL zend_jit_int_extend_stack_helper, r0 } else { - | mov FCARG2a, r0 + if (!is_closure) { + | mov FCARG2a, r0 + } else { + | lea FCARG2a, aword [r0 + offsetof(zend_closure, func)] + } + | SET_EX_OPLINE opline, r0 | EXT_CALL zend_jit_extend_stack_helper, r0 } | mov RX, r0 @@ -8538,22 +8572,86 @@ static int zend_jit_push_call_frame(dasm_State **Dst, const zend_op *opline, zen | MEM_OP2_1_ZTS add, aword, executor_globals, vm_stack_top, FCARG1a, r2 } | // zend_vm_init_call_frame(call, call_info, func, num_args, called_scope, object); - | // ZEND_SET_CALL_INFO(call, 0, call_info); - | mov dword EX:RX->This.u1.type_info, (IS_UNDEF | ZEND_CALL_NESTED_FUNCTION) - | // call->func = func; + if (JIT_G(trigger) != ZEND_JIT_ON_HOT_TRACE || opline->opcode != ZEND_INIT_METHOD_CALL) { + | // ZEND_SET_CALL_INFO(call, 0, call_info); + | mov dword EX:RX->This.u1.type_info, (IS_UNDEF | ZEND_CALL_NESTED_FUNCTION) + } #ifdef _WIN32 if (0) { #else if (func && func->type == ZEND_INTERNAL_FUNCTION) { #endif + | // call->func = func; |1: | ADDR_OP2_2 mov, aword EX:RX->func, func, r1 } else { - | mov aword EX:RX->func, r0 + if (!is_closure) { + | // call->func = func; + | mov aword EX:RX->func, r0 + } else { + | // call->func = &closure->func; + | lea r1, aword [r0 + offsetof(zend_closure, func)] + | mov aword EX:RX->func, r1 + } + |1: + } + if (opline->opcode == ZEND_INIT_METHOD_CALL) { + | // Z_PTR(call->This) = obj; + | mov r1, aword T1 + | mov aword EX:RX->This.value.ptr, r1 + if (opline->op1_type == IS_UNUSED) { + | // call->call_info |= ZEND_CALL_HAS_THIS; + if (JIT_G(trigger) == ZEND_JIT_ON_HOT_TRACE) { + | mov dword EX:RX->This.u1.type_info, ZEND_CALL_HAS_THIS + } else { + | or dword EX:RX->This.u1.type_info, ZEND_CALL_HAS_THIS + } + } else { + if (opline->op1_type == IS_CV) { + | // GC_ADDREF(obj); + | add dword [r1], 1 + } + | // call->call_info |= ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS; + if (JIT_G(trigger) == ZEND_JIT_ON_HOT_TRACE) { + | mov dword EX:RX->This.u1.type_info, (ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS) + } else { + | or dword EX:RX->This.u1.type_info, (ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS) + } + } + } else if (!is_closure) { + | // Z_CE(call->This) = called_scope; + | mov aword EX:RX->This.value.ptr, 0 + } else { + if (opline->op2_type == IS_CV) { + | // GC_ADDREF(closure); + | add dword [r0], 1 + } + | // object_or_called_scope = closure->called_scope; + | mov r1, aword [r0 + offsetof(zend_closure, called_scope)] + | mov aword EX:RX->This.value.ptr, r1 + | // call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_DYNAMIC | ZEND_CALL_CLOSURE | + | // (closure->func->common.fn_flags & ZEND_ACC_FAKE_CLOSURE); + | mov edx, dword [r0 + offsetof(zend_closure, func.common.fn_flags)] + | and edx, ZEND_ACC_FAKE_CLOSURE + | or edx, (ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_DYNAMIC | ZEND_CALL_CLOSURE) + | // if (Z_TYPE(closure->this_ptr) != IS_UNDEF) { + | cmp byte [r0 + offsetof(zend_closure, this_ptr.u1.v.type)], IS_UNDEF + | jz >1 + | // call_info |= ZEND_CALL_HAS_THIS; + | or edx, ZEND_CALL_HAS_THIS + | // object_or_called_scope = Z_OBJ(closure->this_ptr); + | mov r1, aword [r0 + offsetof(zend_closure, this_ptr.value.ptr)] + |1: + | // ZEND_SET_CALL_INFO(call, 0, call_info); + | or dword EX:RX->This.u1.type_info, edx + | // Z_PTR(call->This) = object_or_called_scope; + | mov aword EX:RX->This.value.ptr, r1 + | cmp aword [r0 + offsetof(zend_closure, func.op_array.run_time_cache__ptr)], 0 + | jnz >1 + | lea FCARG1a, aword [r0 + offsetof(zend_closure, func)] + | EXT_CALL zend_jit_init_func_run_time_cache_helper, r0 |1: } - | // Z_CE(call->This) = called_scope; - | mov aword EX:RX->This.value.ptr, 0 | // ZEND_CALL_NUM_ARGS(call) = num_args; | mov dword EX:RX->This.u2.num_args, opline->extended_value return 1; @@ -8940,7 +9038,7 @@ static int zend_jit_init_fcall(dasm_State **Dst, const zend_op *opline, uint32_t |3: } - if (!zend_jit_push_call_frame(Dst, opline, func)) { + if (!zend_jit_push_call_frame(Dst, opline, func, 0)) { return 0; } @@ -8956,129 +9054,465 @@ static int zend_jit_init_fcall(dasm_State **Dst, const zend_op *opline, uint32_t return 1; } -static uint32_t skip_valid_arguments(const zend_op_array *op_array, zend_ssa *ssa, const zend_call_info *call_info) +static int zend_jit_init_method_call(dasm_State **Dst, + const zend_op *opline, + uint32_t b, + const zend_op_array *op_array, + zend_ssa *ssa, + const zend_ssa_op *ssa_op, + int call_level, + uint32_t op1_info, + zend_jit_addr op1_addr, + zend_class_entry *ce, + zend_bool ce_is_instanceof, + zend_bool use_this, + zend_class_entry *trace_ce, + zend_jit_trace_rec *trace) { - uint32_t num_args = 0; - zend_function *func = call_info->callee_func; + zend_func_info *info = ZEND_FUNC_INFO(op_array); + zend_call_info *call_info = NULL; + zend_function *func = NULL; + zval *function_name; - while (num_args < call_info->num_args) { - zend_arg_info *arg_info = func->op_array.arg_info + num_args; + ZEND_ASSERT(opline->op2_type == IS_CONST); + ZEND_ASSERT(op1_info & MAY_BE_OBJECT); - if (ZEND_TYPE_IS_SET(arg_info->type)) { - if (ZEND_TYPE_IS_ONLY_MASK(arg_info->type)) { - zend_op *opline = call_info->arg_info[num_args].opline; - zend_ssa_op *ssa_op = &ssa->ops[opline - op_array->opcodes]; - uint32_t type_mask = ZEND_TYPE_PURE_MASK(arg_info->type); - if ((OP1_INFO() & (MAY_BE_ANY|MAY_BE_UNDEF)) & ~type_mask) { - break; + function_name = RT_CONSTANT(opline, opline->op2); + + if (opline->op1_type == IS_UNUSED || use_this) { + zend_jit_addr this_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FP, offsetof(zend_execute_data, This)); + + | GET_ZVAL_PTR FCARG1a, this_addr + } else { + if (op1_info & MAY_BE_REF) { + if (opline->op1_type == IS_CV) { + if (Z_REG(op1_addr) != ZREG_FCARG1a || Z_OFFSET(op1_addr) != 0) { + | LOAD_ZVAL_ADDR FCARG1a, op1_addr } + | ZVAL_DEREF FCARG1a, op1_info + op1_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FCARG1a, 0); } else { - break; + ZEND_ASSERT(Z_REG(op1_addr) == ZREG_FP); + | IF_NOT_ZVAL_TYPE op1_addr, IS_REFERENCE, >1 + | LOAD_ZVAL_ADDR FCARG1a, op1_addr + | EXT_CALL zend_jit_unref_helper, r0 + |1: } } - num_args++; - } - return num_args; -} - -static int zend_jit_do_fcall(dasm_State **Dst, const zend_op *opline, const zend_op_array *op_array, zend_ssa *ssa, int call_level, unsigned int next_block, zend_jit_trace_rec *trace) -{ - zend_func_info *info = ZEND_FUNC_INFO(op_array); - zend_call_info *call_info = NULL; - const zend_function *func = NULL; - uint32_t i; - zend_jit_addr res_addr; - uint32_t call_num_args = 0; - zend_bool unknown_num_args = 0; - const void *exit_addr = NULL; + if (op1_info & ((MAY_BE_UNDEF|MAY_BE_ANY)- MAY_BE_OBJECT)) { + if (JIT_G(trigger) == ZEND_JIT_ON_HOT_TRACE) { + int32_t exit_point = zend_jit_trace_get_exit_point(opline, ZEND_JIT_EXIT_TO_VM); + const void *exit_addr = zend_jit_trace_get_exit_addr(exit_point); - if (RETURN_VALUE_USED(opline)) { - res_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FP, opline->result.var); - } else { - /* CPU stack allocated temporary zval */ - res_addr = ZEND_ADDR_MEM_ZVAL(ZREG_R4, TMP_ZVAL_OFFSET); + if (!exit_addr) { + return 0; + } + | IF_NOT_ZVAL_TYPE op1_addr, IS_OBJECT, &exit_addr + } else { + | IF_NOT_ZVAL_TYPE op1_addr, IS_OBJECT, >1 + |.cold_code + |1: + if (Z_REG(op1_addr) != ZREG_FCARG1a || Z_OFFSET(op1_addr) != 0) { + | LOAD_ZVAL_ADDR FCARG1a, op1_addr + } + | SET_EX_OPLINE opline, r0 + | EXT_CALL zend_jit_invalid_method_call, r0 + | jmp ->exception_handler + |.code + } + } + | GET_ZVAL_PTR FCARG1a, op1_addr } - if ((opline-1)->opcode == ZEND_SEND_UNPACK || (opline-1)->opcode == ZEND_SEND_ARRAY || - (opline-1)->opcode == ZEND_CHECK_UNDEF_ARGS) { - unknown_num_args = 1; + if (delayed_call_chain) { + if (!zend_jit_save_call_chain(Dst, delayed_call_level)) { + return 0; + } } if (info) { call_info = info->callee_info; - while (call_info && call_info->caller_call_opline != opline) { + while (call_info && call_info->caller_init_opline != opline) { call_info = call_info->next_callee; } if (call_info && call_info->callee_func) { func = call_info->callee_func; } } - if (!func) { - /* resolve function at run time */ - } else if (func->type == ZEND_USER_FUNCTION) { - ZEND_ASSERT(opline->opcode != ZEND_DO_ICALL); - call_num_args = call_info->num_args; - } else if (func->type == ZEND_INTERNAL_FUNCTION) { - ZEND_ASSERT(opline->opcode != ZEND_DO_UCALL); - call_num_args = call_info->num_args; + + | mov aword T1, FCARG1a // save + + if (func) { + | // fbc = CACHED_PTR(opline->result.num + sizeof(void*)); + | mov r0, EX->run_time_cache + | mov r0, aword [r0 + opline->result.num + sizeof(void*)] + | test r0, r0 + | jz >1 } else { - ZEND_UNREACHABLE(); + | // if (CACHED_PTR(opline->result.num) == obj->ce)) { + | mov r0, EX->run_time_cache + | mov r2, aword [r0 + opline->result.num] + | cmp r2, [FCARG1a + offsetof(zend_object, ce)] + | jnz >1 + | // fbc = CACHED_PTR(opline->result.num + sizeof(void*)); + | mov r0, aword [r0 + opline->result.num + sizeof(void*)] } - if (trace && !func) { - if (trace->op == ZEND_JIT_TRACE_DO_ICALL) { - ZEND_ASSERT(trace->func->type == ZEND_INTERNAL_FUNCTION); -#ifndef ZEND_WIN32 - // TODO: ASLR may cause different addresses in different workers ??? - func = trace->func; - if (JIT_G(current_frame) && - JIT_G(current_frame)->call && - TRACE_FRAME_NUM_ARGS(JIT_G(current_frame)->call) >= 0) { - call_num_args = TRACE_FRAME_NUM_ARGS(JIT_G(current_frame)->call); - } else { - unknown_num_args = 1; - } + |.cold_code + |1: + | LOAD_ADDR FCARG2a, function_name + |.if X64 + | lea CARG3, aword T1 + |.else + | lea r0, aword T1 + | sub r4, 12 + | push r0 + |.endif + | SET_EX_OPLINE opline, r0 + | EXT_CALL zend_jit_find_method_helper, r0 + | test r0, r0 + | jz ->exception_handler + |.if not(X64) + | add r4, 12 + |.endif + | jmp >2 + |.code + |2: + + if (!func + && trace + && trace->op == ZEND_JIT_TRACE_INIT_CALL + && trace->func +#ifdef _WIN32 + && trace->func->type != ZEND_INTERNAL_FUNCTION #endif - } else if (trace->op == ZEND_JIT_TRACE_ENTER) { - ZEND_ASSERT(trace->func->type == ZEND_USER_FUNCTION); - if (zend_accel_in_shm(trace->func->op_array.opcodes)) { - func = trace->func; - if (JIT_G(current_frame) && - JIT_G(current_frame)->call && - TRACE_FRAME_NUM_ARGS(JIT_G(current_frame)->call) >= 0) { - call_num_args = TRACE_FRAME_NUM_ARGS(JIT_G(current_frame)->call); - } else { - unknown_num_args = 1; - } - } + ) { + int32_t exit_point; + const void *exit_addr; + + exit_point = zend_jit_trace_get_exit_point(opline, ZEND_JIT_EXIT_DYNAMIC_CALL); + exit_addr = zend_jit_trace_get_exit_addr(exit_point); + if (!exit_addr) { + return 0; } - } - bool may_have_extra_named_params = - opline->extended_value == ZEND_FCALL_MAY_HAVE_EXTRA_NAMED_PARAMS && - (!func || func->common.fn_flags & ZEND_ACC_VARIADIC); + func = (zend_function*)trace->func; - if (!reuse_ip) { - zend_jit_start_reuse_ip(); - | // call = EX(call); - | mov RX, EX->call + if (func->type == ZEND_USER_FUNCTION && + (!(func->common.fn_flags & ZEND_ACC_IMMUTABLE) || + (func->common.fn_flags & ZEND_ACC_CLOSURE) || + !func->common.function_name)) { + const zend_op *opcodes = func->op_array.opcodes; + + | .if X64 + || if (!IS_SIGNED_32BIT(opcodes)) { + | mov64 r1, ((ptrdiff_t)opcodes) + | cmp aword [r0 + offsetof(zend_op_array, opcodes)], r1 + || } else { + | cmp aword [r0 + offsetof(zend_op_array, opcodes)], opcodes + || } + | .else + | cmp aword [r0 + offsetof(zend_op_array, opcodes)], opcodes + | .endif + | jne &exit_addr + } else { + | .if X64 + || if (!IS_SIGNED_32BIT(func)) { + | mov64 r1, ((ptrdiff_t)func) + | cmp r0, r1 + || } else { + | cmp r0, func + || } + | .else + | cmp r0, func + | .endif + | jne &exit_addr + } } - zend_jit_stop_reuse_ip(); - - | // fbc = call->func; - | // mov r2, EX:RX->func ??? - | // SAVE_OPLINE(); - | SET_EX_OPLINE opline, r0 - if (opline->opcode == ZEND_DO_FCALL) { - if (!func) { - if (trace) { - uint32_t exit_point = zend_jit_trace_get_exit_point(opline, ZEND_JIT_EXIT_TO_VM); + if (!func) { + | // if (fbc->common.fn_flags & ZEND_ACC_STATIC) { + | test dword [r0 + offsetof(zend_function, common.fn_flags)], ZEND_ACC_STATIC + | jnz >1 + |.cold_code + |1: + } - exit_addr = zend_jit_trace_get_exit_addr(exit_point); - if (!exit_addr) { - return 0; - } + if (!func || (func->common.fn_flags & ZEND_ACC_STATIC) != 0) { + | mov FCARG1a, aword T1 // restore + | mov FCARG2a, r0 + |.if X64 + | mov CARG3d, opline->extended_value + |.else + | sub r4, 12 + | push opline->extended_value + |.endif + if (opline->op1_type & (IS_VAR|IS_TMP_VAR)) { + | EXT_CALL zend_jit_push_static_metod_call_frame_tmp, r0 + } else { + | EXT_CALL zend_jit_push_static_metod_call_frame, r0 + } + |.if not(X64) + | add r4, 12 + |.endif + if (opline->op1_type & (IS_VAR|IS_TMP_VAR)) { + | test r0, r0 + | jz ->exception_handler + } + | mov RX, r0 + } + + if (!func) { + | jmp >9 + |.code + } + + if (!func || (func->common.fn_flags & ZEND_ACC_STATIC) == 0) { + if (!zend_jit_push_call_frame(Dst, opline, func, 0)) { + return 0; + } + } + + if (!func) { + |9: + } + zend_jit_start_reuse_ip(); + + if (zend_jit_needs_call_chain(call_info, b, op_array, ssa, ssa_op, opline, trace)) { + if (!zend_jit_save_call_chain(Dst, call_level)) { + return 0; + } + } else { + delayed_call_chain = 1; + delayed_call_level = call_level; + } + + return 1; +} + +static int zend_jit_init_closure_call(dasm_State **Dst, + const zend_op *opline, + uint32_t b, + const zend_op_array *op_array, + zend_ssa *ssa, + const zend_ssa_op *ssa_op, + int call_level, + zend_jit_trace_rec *trace) +{ + zend_function *func = NULL; + zend_jit_addr op2_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FP, opline->op2.var); + + | GET_ZVAL_PTR r0, op2_addr + + if (ssa->var_info[ssa_op->op2_use].ce != zend_ce_closure + && !(ssa->var_info[ssa_op->op2_use].type & MAY_BE_CLASS_GUARD)) { + int32_t exit_point = zend_jit_trace_get_exit_point(opline, ZEND_JIT_EXIT_TO_VM); + const void *exit_addr = zend_jit_trace_get_exit_addr(exit_point); + + if (!exit_addr) { + return 0; + } + + |.if X64 + || if (!IS_SIGNED_32BIT(zend_ce_closure)) { + | mov64 FCARG1a, ((ptrdiff_t)zend_ce_closure) + | cmp aword [r0 + offsetof(zend_object, ce)], FCARG1a + || } else { + | cmp aword [r0 + offsetof(zend_object, ce)], zend_ce_closure + || } + |.else + | cmp aword [r0 + offsetof(zend_object, ce)], zend_ce_closure + |.endif + | jne &exit_addr + if (ssa->var_info && ssa_op->op2_use >= 0) { + ssa->var_info[ssa_op->op2_use].type |= MAY_BE_CLASS_GUARD; + ssa->var_info[ssa_op->op2_use].ce = zend_ce_closure; + ssa->var_info[ssa_op->op2_use].is_instanceof = 0; + } + } + + if (trace + && trace->op == ZEND_JIT_TRACE_INIT_CALL + && trace->func + && trace->func->type == ZEND_USER_FUNCTION) { + const zend_op *opcodes; + int32_t exit_point; + const void *exit_addr; + + func = (zend_function*)trace->func; + opcodes = func->op_array.opcodes; + exit_point = zend_jit_trace_get_exit_point(opline, ZEND_JIT_EXIT_DYNAMIC_CALL); + exit_addr = zend_jit_trace_get_exit_addr(exit_point); + if (!exit_addr) { + return 0; + } + + | .if X64 + || if (!IS_SIGNED_32BIT(opcodes)) { + | mov64 FCARG1a, ((ptrdiff_t)opcodes) + | cmp aword [r0 + offsetof(zend_closure, func.op_array.opcodes)], FCARG1a + || } else { + | cmp aword [r0 + offsetof(zend_closure, func.op_array.opcodes)], opcodes + || } + | .else + | cmp aword [r0 + offsetof(zend_closure, func.op_array.opcodes)], opcodes + | .endif + | jne &exit_addr + } + + if (delayed_call_chain) { + if (!zend_jit_save_call_chain(Dst, delayed_call_level)) { + return 0; + } + } + + if (!zend_jit_push_call_frame(Dst, opline, func, 1)) { + return 0; + } + + if (zend_jit_needs_call_chain(NULL, b, op_array, ssa, ssa_op, opline, trace)) { + if (!zend_jit_save_call_chain(Dst, call_level)) { + return 0; + } + } else { + delayed_call_chain = 1; + delayed_call_level = call_level; + } + + if (trace + && trace->op == ZEND_JIT_TRACE_END + && trace->stop == ZEND_JIT_TRACE_STOP_INTERPRETER) { + if (!zend_jit_set_valid_ip(Dst, opline + 1)) { + return 0; + } + } + + return 1; +} + +static uint32_t skip_valid_arguments(const zend_op_array *op_array, zend_ssa *ssa, const zend_call_info *call_info) +{ + uint32_t num_args = 0; + zend_function *func = call_info->callee_func; + + while (num_args < call_info->num_args) { + zend_arg_info *arg_info = func->op_array.arg_info + num_args; + + if (ZEND_TYPE_IS_SET(arg_info->type)) { + if (ZEND_TYPE_IS_ONLY_MASK(arg_info->type)) { + zend_op *opline = call_info->arg_info[num_args].opline; + zend_ssa_op *ssa_op = &ssa->ops[opline - op_array->opcodes]; + uint32_t type_mask = ZEND_TYPE_PURE_MASK(arg_info->type); + if ((OP1_INFO() & (MAY_BE_ANY|MAY_BE_UNDEF)) & ~type_mask) { + break; + } + } else { + break; + } + } + num_args++; + } + return num_args; +} + +static int zend_jit_do_fcall(dasm_State **Dst, const zend_op *opline, const zend_op_array *op_array, zend_ssa *ssa, int call_level, unsigned int next_block, zend_jit_trace_rec *trace) +{ + zend_func_info *info = ZEND_FUNC_INFO(op_array); + zend_call_info *call_info = NULL; + const zend_function *func = NULL; + uint32_t i; + zend_jit_addr res_addr; + uint32_t call_num_args = 0; + zend_bool unknown_num_args = 0; + const void *exit_addr = NULL; + + if (RETURN_VALUE_USED(opline)) { + res_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FP, opline->result.var); + } else { + /* CPU stack allocated temporary zval */ + res_addr = ZEND_ADDR_MEM_ZVAL(ZREG_R4, TMP_ZVAL_OFFSET); + } + + if ((opline-1)->opcode == ZEND_SEND_UNPACK || (opline-1)->opcode == ZEND_SEND_ARRAY || + (opline-1)->opcode == ZEND_CHECK_UNDEF_ARGS) { + unknown_num_args = 1; + } + + if (info) { + call_info = info->callee_info; + while (call_info && call_info->caller_call_opline != opline) { + call_info = call_info->next_callee; + } + if (call_info && call_info->callee_func) { + func = call_info->callee_func; + } + } + if (!func) { + /* resolve function at run time */ + } else if (func->type == ZEND_USER_FUNCTION) { + ZEND_ASSERT(opline->opcode != ZEND_DO_ICALL); + call_num_args = call_info->num_args; + } else if (func->type == ZEND_INTERNAL_FUNCTION) { + ZEND_ASSERT(opline->opcode != ZEND_DO_UCALL); + call_num_args = call_info->num_args; + } else { + ZEND_UNREACHABLE(); + } + + if (trace && !func) { + if (trace->op == ZEND_JIT_TRACE_DO_ICALL) { + ZEND_ASSERT(trace->func->type == ZEND_INTERNAL_FUNCTION); +#ifndef ZEND_WIN32 + // TODO: ASLR may cause different addresses in different workers ??? + func = trace->func; + if (JIT_G(current_frame) && + JIT_G(current_frame)->call && + TRACE_FRAME_NUM_ARGS(JIT_G(current_frame)->call) >= 0) { + call_num_args = TRACE_FRAME_NUM_ARGS(JIT_G(current_frame)->call); + } else { + unknown_num_args = 1; + } +#endif + } else if (trace->op == ZEND_JIT_TRACE_ENTER) { + ZEND_ASSERT(trace->func->type == ZEND_USER_FUNCTION); + if (zend_accel_in_shm(trace->func->op_array.opcodes)) { + func = trace->func; + if (JIT_G(current_frame) && + JIT_G(current_frame)->call && + TRACE_FRAME_NUM_ARGS(JIT_G(current_frame)->call) >= 0) { + call_num_args = TRACE_FRAME_NUM_ARGS(JIT_G(current_frame)->call); + } else { + unknown_num_args = 1; + } + } + } + } + + bool may_have_extra_named_params = + opline->extended_value == ZEND_FCALL_MAY_HAVE_EXTRA_NAMED_PARAMS && + (!func || func->common.fn_flags & ZEND_ACC_VARIADIC); + + if (!reuse_ip) { + zend_jit_start_reuse_ip(); + | // call = EX(call); + | mov RX, EX->call + } + zend_jit_stop_reuse_ip(); + + | // fbc = call->func; + | // mov r2, EX:RX->func ??? + | // SAVE_OPLINE(); + | SET_EX_OPLINE opline, r0 + + if (opline->opcode == ZEND_DO_FCALL) { + if (!func) { + if (trace) { + uint32_t exit_point = zend_jit_trace_get_exit_point(opline, ZEND_JIT_EXIT_TO_VM); + + exit_addr = zend_jit_trace_get_exit_addr(exit_point); + if (!exit_addr) { + return 0; + } | mov r0, EX:RX->func | test dword [r0 + offsetof(zend_op_array, fn_flags)], ZEND_ACC_DEPRECATED | jnz &exit_addr @@ -12304,14 +12738,13 @@ static int zend_jit_fetch_obj(dasm_State **Dst, return 1; } -static int zend_jit_assign_obj(dasm_State **Dst, +static int zend_jit_incdec_obj(dasm_State **Dst, const zend_op *opline, const zend_op_array *op_array, zend_ssa *ssa, const zend_ssa_op *ssa_op, uint32_t op1_info, zend_jit_addr op1_addr, - uint32_t val_info, zend_bool op1_indirect, zend_class_entry *ce, zend_bool ce_is_instanceof, @@ -12322,19 +12755,18 @@ static int zend_jit_assign_obj(dasm_State **Dst, zval *member; zend_string *name; zend_property_info *prop_info; - zend_jit_addr val_addr = OP1_DATA_ADDR(); - zend_jit_addr res_addr = 0; zend_jit_addr this_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FP, offsetof(zend_execute_data, This)); + zend_jit_addr res_addr = 0; zend_jit_addr prop_addr; zend_bool needs_slow_path = 0; - if (RETURN_VALUE_USED(opline)) { - res_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FP, opline->result.var); - } - ZEND_ASSERT(opline->op2_type == IS_CONST); ZEND_ASSERT(op1_info & MAY_BE_OBJECT); + if (opline->result_type != IS_UNUSED) { + res_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FP, opline->result.var); + } + member = RT_CONSTANT(opline, opline->op2); ZEND_ASSERT(Z_TYPE_P(member) == IS_STRING && Z_STRVAL_P(member)[0] != '\0'); name = Z_STR_P(member); @@ -12377,16 +12809,8 @@ static int zend_jit_assign_obj(dasm_State **Dst, | LOAD_ZVAL_ADDR FCARG1a, op1_addr } | LOAD_ADDR FCARG2a, ZSTR_VAL(name) - | EXT_CALL zend_jit_invalid_property_assign, r0 - if (RETURN_VALUE_USED(opline)) { - | SET_ZVAL_TYPE_INFO res_addr, IS_NULL - } - if (((opline+1)->op1_type & (IS_VAR|IS_TMP_VAR)) - && (val_info & (MAY_BE_REF|MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE))) { - | jmp >8 - } else { - | jmp ->exception_handler - } + | EXT_CALL zend_jit_invalid_property_incdec, r0 + | jmp ->exception_handler |.code } } @@ -12422,13 +12846,702 @@ static int zend_jit_assign_obj(dasm_State **Dst, | mov r0, EX->run_time_cache | mov r2, aword [r0 + opline->extended_value] | cmp r2, aword [FCARG1a + offsetof(zend_object, ce)] - | jne >5 + | jne >7 if (!ce || ce_is_instanceof || (ce->ce_flags & ZEND_ACC_HAS_TYPE_HINTS)) { - | mov FCARG2a, aword [r0 + (opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS) + sizeof(void*) * 2] + | cmp aword [r0 + opline->extended_value + sizeof(void*) * 2], 0 + | jnz >7 } | mov r0, aword [r0 + opline->extended_value + sizeof(void*)] | test r0, r0 - | jl >5 + | jl >7 + | IF_TYPE byte [FCARG1a + r0 + 8], IS_UNDEF, >7 + | add FCARG1a, r0 + prop_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FCARG1a, 0); + } else { + prop_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FCARG1a, prop_info->offset); + if (JIT_G(trigger) == ZEND_JIT_ON_HOT_TRACE) { + int32_t exit_point = zend_jit_trace_get_exit_point(opline, ZEND_JIT_EXIT_TO_VM); + const void *exit_addr = zend_jit_trace_get_exit_addr(exit_point); + + if (!exit_addr) { + return 0; + } + | IF_TYPE byte [FCARG1a + prop_info->offset + 8], IS_UNDEF, &exit_addr + } else { + | IF_TYPE byte [FCARG1a + prop_info->offset + 8], IS_UNDEF, >7 + needs_slow_path = 1; + } + if (ZEND_TYPE_IS_SET(prop_info->type)) { + | SET_EX_OPLINE opline, r0 + if (ce && ce->ce_flags & ZEND_ACC_IMMUTABLE) { + | LOAD_ADDR FCARG2a, prop_info + } else { + int prop_info_offset = + (((prop_info->offset - (sizeof(zend_object) - sizeof(zval))) / sizeof(zval)) * sizeof(void*)); + + | mov r0, aword [FCARG1a + offsetof(zend_object, ce)] + | mov r0, aword [r0 + offsetof(zend_class_entry, properties_info_table)] + | mov FCARG2a, aword[r0 + prop_info_offset] + } + | LOAD_ZVAL_ADDR FCARG1a, prop_addr + if (opline->result_type == IS_UNUSED) { + switch (opline->opcode) { + case ZEND_PRE_INC_OBJ: + case ZEND_POST_INC_OBJ: + | EXT_CALL zend_jit_inc_typed_prop, r0 + break; + case ZEND_PRE_DEC_OBJ: + case ZEND_POST_DEC_OBJ: + | EXT_CALL zend_jit_dec_typed_prop, r0 + break; + default: + ZEND_UNREACHABLE(); + } + } else { + |.if X64 + | LOAD_ZVAL_ADDR CARG3, res_addr + |.else + | sub r4, 12 + | PUSH_ZVAL_ADDR res_addr, r0 + |.endif + switch (opline->opcode) { + case ZEND_PRE_INC_OBJ: + | EXT_CALL zend_jit_pre_inc_typed_prop, r0 + break; + case ZEND_PRE_DEC_OBJ: + | EXT_CALL zend_jit_pre_dec_typed_prop, r0 + break; + case ZEND_POST_INC_OBJ: + | EXT_CALL zend_jit_post_inc_typed_prop, r0 + break; + case ZEND_POST_DEC_OBJ: + | EXT_CALL zend_jit_post_dec_typed_prop, r0 + break; + default: + ZEND_UNREACHABLE(); + } + |.if not(X64) + | add r4, 12 + |.endif + } + } + } + + if (!prop_info || !ZEND_TYPE_IS_SET(prop_info->type)) { + zend_jit_addr var_addr = prop_addr; + + var_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FCARG1a, 0); + | LOAD_ZVAL_ADDR FCARG1a, prop_addr + + | IF_NOT_ZVAL_TYPE var_addr, IS_REFERENCE, >2 + | GET_ZVAL_PTR FCARG1a, var_addr + | cmp aword [FCARG1a + offsetof(zend_reference, sources.ptr)], 0 + | jnz >1 + | lea FCARG1a, aword [FCARG1a + offsetof(zend_reference, val)] + |.cold_code + |1: + if (opline) { + | SET_EX_OPLINE opline, r0 + } + if (opline->result_type == IS_UNUSED) { + | xor FCARG2a, FCARG2a + } else { + | LOAD_ZVAL_ADDR FCARG2a, res_addr + } + switch (opline->opcode) { + case ZEND_PRE_INC_OBJ: + | EXT_CALL zend_jit_pre_inc_typed_ref, r0 + break; + case ZEND_PRE_DEC_OBJ: + | EXT_CALL zend_jit_pre_dec_typed_ref, r0 + break; + case ZEND_POST_INC_OBJ: + | EXT_CALL zend_jit_post_inc_typed_ref, r0 + break; + case ZEND_POST_DEC_OBJ: + | EXT_CALL zend_jit_post_dec_typed_ref, r0 + break; + default: + ZEND_UNREACHABLE(); + } + | jmp >9 + |.code + + |2: + | IF_NOT_ZVAL_TYPE var_addr, IS_LONG, >2 + if (opline->opcode == ZEND_POST_INC_OBJ || opline->opcode == ZEND_POST_DEC_OBJ) { + if (opline->result_type != IS_UNUSED) { + | ZVAL_COPY_VALUE res_addr, -1, var_addr, MAY_BE_LONG, ZREG_R1, ZREG_R2 + } + } + if (opline->opcode == ZEND_PRE_INC_OBJ || opline->opcode == ZEND_POST_INC_OBJ) { + | LONG_OP_WITH_32BIT_CONST add, var_addr, Z_L(1) + } else { + | LONG_OP_WITH_32BIT_CONST sub, var_addr, Z_L(1) + } + | jo >3 + if (opline->opcode == ZEND_PRE_INC_OBJ || opline->opcode == ZEND_PRE_DEC_OBJ) { + if (opline->result_type != IS_UNUSED) { + | ZVAL_COPY_VALUE res_addr, -1, var_addr, MAY_BE_LONG, ZREG_R0, ZREG_R2 + } + } + |.cold_code + |2: + if (opline->opcode == ZEND_POST_INC_OBJ || opline->opcode == ZEND_POST_DEC_OBJ) { + | ZVAL_COPY_VALUE res_addr, -1, var_addr, MAY_BE_ANY, ZREG_R0, ZREG_R2 + | TRY_ADDREF MAY_BE_ANY, ah, r2 + } + if (opline->opcode == ZEND_PRE_INC_OBJ || opline->opcode == ZEND_POST_INC_OBJ) { + if (opline->opcode == ZEND_PRE_INC_OBJ && opline->result_type != IS_UNUSED) { + | LOAD_ZVAL_ADDR FCARG2a, res_addr + | EXT_CALL zend_jit_pre_inc, r0 + } else { + | EXT_CALL increment_function, r0 + } + } else { + if (opline->opcode == ZEND_PRE_DEC_OBJ && opline->result_type != IS_UNUSED) { + | LOAD_ZVAL_ADDR FCARG2a, res_addr + | EXT_CALL zend_jit_pre_dec, r0 + } else { + | EXT_CALL decrement_function, r0 + } + } + | jmp >4 + + |3: + if (opline->opcode == ZEND_PRE_INC_OBJ || opline->opcode == ZEND_POST_INC_OBJ) { + |.if X64 + | mov64 rax, 0x43e0000000000000 + | SET_ZVAL_LVAL var_addr, rax + if (opline->opcode == ZEND_PRE_INC_OBJ && opline->result_type != IS_UNUSED) { + | SET_ZVAL_LVAL res_addr, rax + } + |.else + | SET_ZVAL_LVAL var_addr, 0 + | SET_ZVAL_W2 var_addr, 0x41e00000 + if (opline->opcode == ZEND_PRE_INC_OBJ && opline->result_type != IS_UNUSED) { + | SET_ZVAL_LVAL res_addr, 0 + | SET_ZVAL_W2 res_addr, 0x41e00000 + } + |.endif + } else { + |.if X64 + | mov64 rax, 0xc3e0000000000000 + | SET_ZVAL_LVAL var_addr, rax + if (opline->opcode == ZEND_PRE_DEC_OBJ && opline->result_type != IS_UNUSED) { + | SET_ZVAL_LVAL res_addr, rax + } + |.else + | SET_ZVAL_LVAL var_addr, 0x00200000 + | SET_ZVAL_W2 var_addr, 0xc1e00000 + if (opline->opcode == ZEND_PRE_DEC_OBJ && opline->result_type != IS_UNUSED) { + | SET_ZVAL_LVAL res_addr, 0x00200000 + | SET_ZVAL_W2 res_addr, 0xc1e00000 + } + |.endif + } + | jmp >4 + |.code + |4: + } + + if (needs_slow_path) { + |.cold_code + |7: + | SET_EX_OPLINE opline, r0 + | // value = zobj->handlers->write_property(zobj, name, value, CACHE_ADDR(opline->extended_value)); + | LOAD_ADDR FCARG2a, name + |.if X64 + | mov CARG3, EX->run_time_cache + | add CARG3, opline->extended_value + if (opline->result_type == IS_UNUSED) { + | xor CARG4, CARG4 + } else { + | LOAD_ZVAL_ADDR CARG4, res_addr + } + |.else + | sub r4, 8 + if (opline->result_type == IS_UNUSED) { + | push 0 + } else { + | PUSH_ZVAL_ADDR res_addr, r0 + } + | mov r0, EX->run_time_cache + | add r0, opline->extended_value + | push r0 + |.endif + + switch (opline->opcode) { + case ZEND_PRE_INC_OBJ: + | EXT_CALL zend_jit_pre_inc_obj_helper, r0 + break; + case ZEND_PRE_DEC_OBJ: + | EXT_CALL zend_jit_pre_dec_obj_helper, r0 + break; + case ZEND_POST_INC_OBJ: + | EXT_CALL zend_jit_post_inc_obj_helper, r0 + break; + case ZEND_POST_DEC_OBJ: + | EXT_CALL zend_jit_post_dec_obj_helper, r0 + break; + default: + ZEND_UNREACHABLE(); + } + + |.if not(X64) + | add r4, 8 + |.endif + + | jmp >9 + |.code + } + + |9: + if (opline->op1_type != IS_UNUSED && !use_this && !op1_indirect) { + | FREE_OP opline->op1_type, opline->op1, op1_info, 1, opline + } + + if (may_throw) { + if (!zend_jit_check_exception(Dst)) { + return 0; + } + } + + return 1; +} + +static int zend_jit_assign_obj_op(dasm_State **Dst, + const zend_op *opline, + const zend_op_array *op_array, + zend_ssa *ssa, + const zend_ssa_op *ssa_op, + uint32_t op1_info, + zend_jit_addr op1_addr, + uint32_t val_info, + zend_ssa_range *val_range, + zend_bool op1_indirect, + zend_class_entry *ce, + zend_bool ce_is_instanceof, + zend_bool use_this, + zend_class_entry *trace_ce, + int may_throw) +{ + zval *member; + zend_string *name; + zend_property_info *prop_info; + zend_jit_addr val_addr = OP1_DATA_ADDR(); + zend_jit_addr this_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FP, offsetof(zend_execute_data, This)); + zend_jit_addr prop_addr; + zend_bool needs_slow_path = 0; + binary_op_type binary_op = get_binary_op(opline->extended_value); + + ZEND_ASSERT(opline->op2_type == IS_CONST); + ZEND_ASSERT(op1_info & MAY_BE_OBJECT); + ZEND_ASSERT(opline->result_type == IS_UNUSED); + + member = RT_CONSTANT(opline, opline->op2); + ZEND_ASSERT(Z_TYPE_P(member) == IS_STRING && Z_STRVAL_P(member)[0] != '\0'); + name = Z_STR_P(member); + prop_info = zend_get_known_property_info(ce, name, opline->op1_type == IS_UNUSED, op_array->filename); + + if (opline->op1_type == IS_UNUSED || use_this) { + | GET_ZVAL_PTR FCARG1a, this_addr + } else { + if (opline->op1_type == IS_VAR + && (op1_info & MAY_BE_INDIRECT) + && Z_REG(op1_addr) == ZREG_FP) { + | LOAD_ZVAL_ADDR FCARG1a, op1_addr + | IF_NOT_Z_TYPE FCARG1a, IS_INDIRECT, >1 + | GET_Z_PTR FCARG1a, FCARG1a + |1: + op1_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FCARG1a, 0); + } + if (op1_info & MAY_BE_REF) { + if (Z_REG(op1_addr) != ZREG_FCARG1a || Z_OFFSET(op1_addr) != 0) { + | LOAD_ZVAL_ADDR FCARG1a, op1_addr + } + | ZVAL_DEREF FCARG1a, op1_info + op1_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FCARG1a, 0); + } + if (op1_info & ((MAY_BE_UNDEF|MAY_BE_ANY)- MAY_BE_OBJECT)) { + if (JIT_G(trigger) == ZEND_JIT_ON_HOT_TRACE) { + int32_t exit_point = zend_jit_trace_get_exit_point(opline, ZEND_JIT_EXIT_TO_VM); + const void *exit_addr = zend_jit_trace_get_exit_addr(exit_point); + + if (!exit_addr) { + return 0; + } + | IF_NOT_ZVAL_TYPE op1_addr, IS_OBJECT, &exit_addr + } else { + | IF_NOT_ZVAL_TYPE op1_addr, IS_OBJECT, >1 + |.cold_code + |1: + | SET_EX_OPLINE opline, r0 + if (Z_REG(op1_addr) != ZREG_FCARG1a || Z_OFFSET(op1_addr) != 0) { + | LOAD_ZVAL_ADDR FCARG1a, op1_addr + } + | LOAD_ADDR FCARG2a, ZSTR_VAL(name) + if (op1_info & MAY_BE_UNDEF) { + | EXT_CALL zend_jit_invalid_property_assign_op, r0 + } else { + | EXT_CALL zend_jit_invalid_property_assign, r0 + } + if (((opline+1)->op1_type & (IS_VAR|IS_TMP_VAR)) + && (val_info & (MAY_BE_REF|MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE))) { + | jmp >8 + } else { + | jmp ->exception_handler + } + |.code + } + } + | GET_ZVAL_PTR FCARG1a, op1_addr + } + + if (!prop_info && trace_ce && (trace_ce->ce_flags & ZEND_ACC_IMMUTABLE)) { + prop_info = zend_get_known_property_info(trace_ce, name, opline->op1_type == IS_UNUSED, op_array->filename); + if (prop_info) { + ce = trace_ce; + ce_is_instanceof = 0; + if (!(op1_info & MAY_BE_CLASS_GUARD)) { + if (!zend_jit_class_guard(Dst, opline, trace_ce)) { + return 0; + } + if (ssa->var_info && ssa_op->op1_use >= 0) { + ssa->var_info[ssa_op->op1_use].type |= MAY_BE_CLASS_GUARD; + ssa->var_info[ssa_op->op1_use].ce = ce; + ssa->var_info[ssa_op->op1_use].is_instanceof = ce_is_instanceof; + } + if (ssa->var_info && ssa_op->op1_def >= 0) { + ssa->var_info[ssa_op->op1_def].type |= MAY_BE_CLASS_GUARD; + ssa->var_info[ssa_op->op1_def].ce = ce; + ssa->var_info[ssa_op->op1_def].is_instanceof = ce_is_instanceof; + } + } + } + } + + if (!prop_info) { + needs_slow_path = 1; + + | mov r0, EX->run_time_cache + | mov r2, aword [r0 + (opline+1)->extended_value] + | cmp r2, aword [FCARG1a + offsetof(zend_object, ce)] + | jne >7 + if (!ce || ce_is_instanceof || (ce->ce_flags & ZEND_ACC_HAS_TYPE_HINTS)) { + | cmp aword [r0 + ((opline+1)->extended_value & ~ZEND_FETCH_OBJ_FLAGS) + sizeof(void*) * 2], 0 + | jnz >7 + } + | mov r0, aword [r0 + (opline+1)->extended_value + sizeof(void*)] + | test r0, r0 + | jl >7 + | IF_TYPE byte [FCARG1a + r0 + 8], IS_UNDEF, >7 + | add FCARG1a, r0 + prop_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FCARG1a, 0); + } else { + prop_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FCARG1a, prop_info->offset); + if (JIT_G(trigger) == ZEND_JIT_ON_HOT_TRACE) { + int32_t exit_point = zend_jit_trace_get_exit_point(opline, ZEND_JIT_EXIT_TO_VM); + const void *exit_addr = zend_jit_trace_get_exit_addr(exit_point); + + if (!exit_addr) { + return 0; + } + | IF_TYPE byte [FCARG1a + prop_info->offset + 8], IS_UNDEF, &exit_addr + } else { + | IF_TYPE byte [FCARG1a + prop_info->offset + 8], IS_UNDEF, >7 + needs_slow_path = 1; + } + if (ZEND_TYPE_IS_SET(prop_info->type)) { + uint32_t info = val_info; + + | // value = zend_assign_to_typed_prop(prop_info, property_val, value EXECUTE_DATA_CC); + | SET_EX_OPLINE opline, r0 + if (ce && ce->ce_flags & ZEND_ACC_IMMUTABLE) { + | LOAD_ADDR FCARG2a, prop_info + } else { + int prop_info_offset = + (((prop_info->offset - (sizeof(zend_object) - sizeof(zval))) / sizeof(zval)) * sizeof(void*)); + + | mov r0, aword [FCARG1a + offsetof(zend_object, ce)] + | mov r0, aword [r0 + offsetof(zend_class_entry, properties_info_table)] + | mov FCARG2a, aword[r0 + prop_info_offset] + } + | LOAD_ZVAL_ADDR FCARG1a, prop_addr + |.if X64 + | LOAD_ZVAL_ADDR CARG3, val_addr + | LOAD_ADDR CARG4, binary_op + |.else + | sub r4, 8 + | PUSH_ADDR binary_op, r0 + | PUSH_ZVAL_ADDR val_addr, r0 + |.endif + + | EXT_CALL zend_jit_assign_op_to_typed_prop, r0 + + |.if not(X64) + | add r4, 8 + |.endif + + if (info & (MAY_BE_REF|MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE)) { + info |= MAY_BE_RC1|MAY_BE_RCN; + } + + | FREE_OP (opline+1)->op1_type, (opline+1)->op1, info, 0, opline + } + } + + if (!prop_info || !ZEND_TYPE_IS_SET(prop_info->type)) { + zend_jit_addr var_addr = prop_addr; + uint32_t var_info = MAY_BE_ANY|MAY_BE_REF|MAY_BE_RC1|MAY_BE_RCN; + uint32_t var_def_info = MAY_BE_ANY|MAY_BE_REF|MAY_BE_RC1|MAY_BE_RCN; + + var_addr = ZEND_ADDR_MEM_ZVAL(ZREG_R0, 0); + | LOAD_ZVAL_ADDR r0, prop_addr + + | IF_NOT_ZVAL_TYPE var_addr, IS_REFERENCE, >2 + | GET_ZVAL_PTR FCARG1a, var_addr + | cmp aword [FCARG1a + offsetof(zend_reference, sources.ptr)], 0 + | jnz >1 + | lea r0, aword [FCARG1a + offsetof(zend_reference, val)] + |.cold_code + |1: + if (Z_MODE(val_addr) != IS_MEM_ZVAL || Z_REG(val_addr) != ZREG_FCARG2a || Z_OFFSET(val_addr) != 0) { + | LOAD_ZVAL_ADDR FCARG2a, val_addr + } + if (opline) { + | SET_EX_OPLINE opline, r0 + } + |.if X64 + | LOAD_ADDR CARG3, binary_op + |.else + | sub r4, 12 + | PUSH_ADDR binary_op, r0 + |.endif + | EXT_CALL zend_jit_assign_op_to_typed_ref, r0 + |.if not(X64) + | add r4, 12 + |.endif + | jmp >9 + |.code + |2: + + switch (opline->extended_value) { + case ZEND_ADD: + case ZEND_SUB: + case ZEND_MUL: + case ZEND_DIV: + if (!zend_jit_math_helper(Dst, opline, opline->extended_value, IS_CV, opline->op1, var_addr, var_info, (opline+1)->op1_type, (opline+1)->op1, val_addr, val_info, 0, var_addr, var_def_info, var_info, + 1 /* may overflow */, 0)) { + return 0; + } + break; + case ZEND_BW_OR: + case ZEND_BW_AND: + case ZEND_BW_XOR: + case ZEND_SL: + case ZEND_SR: + case ZEND_MOD: + if (!zend_jit_long_math_helper(Dst, opline, opline->extended_value, + IS_CV, opline->op1, var_addr, var_info, NULL, + (opline+1)->op1_type, (opline+1)->op1, val_addr, val_info, + val_range, + 0, var_addr, var_def_info, var_info, 0)) { + return 0; + } + break; + case ZEND_CONCAT: + if (!zend_jit_concat_helper(Dst, opline, IS_CV, opline->op1, var_addr, var_info, (opline+1)->op1_type, (opline+1)->op1, val_addr, val_info, var_addr, + 0)) { + return 0; + } + break; + default: + ZEND_UNREACHABLE(); + } + } + + if (needs_slow_path) { + |.cold_code + |7: + | SET_EX_OPLINE opline, r0 + | // value = zobj->handlers->write_property(zobj, name, value, CACHE_ADDR(opline->extended_value)); + | LOAD_ADDR FCARG2a, name + |.if X64 + | LOAD_ZVAL_ADDR CARG3, val_addr + | mov CARG4, EX->run_time_cache + | add CARG4, (opline+1)->extended_value + |.if X64WIN + | LOAD_ADDR r0, binary_op + | mov aword A5, r0 + |.else + | LOAD_ADDR CARG5, binary_op + |.endif + |.else + | sub r4, 4 + | PUSH_ADDR binary_op, r0 + | mov r0, EX->run_time_cache + | add r0, (opline+1)->extended_value + | push r0 + | PUSH_ZVAL_ADDR val_addr, r0 + |.endif + + | EXT_CALL zend_jit_assign_obj_op_helper, r0 + + |.if not(X64) + | add r4, 4 + |.endif + + if (val_info & (MAY_BE_REF|MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE)) { + val_info |= MAY_BE_RC1|MAY_BE_RCN; + } + + |8: + | // FREE_OP_DATA(); + | FREE_OP (opline+1)->op1_type, (opline+1)->op1, val_info, 0, opline + | jmp >9 + |.code + } + + |9: + if (opline->op1_type != IS_UNUSED && !use_this && !op1_indirect) { + | FREE_OP opline->op1_type, opline->op1, op1_info, 1, opline + } + + if (may_throw) { + if (!zend_jit_check_exception(Dst)) { + return 0; + } + } + + return 1; +} + +static int zend_jit_assign_obj(dasm_State **Dst, + const zend_op *opline, + const zend_op_array *op_array, + zend_ssa *ssa, + const zend_ssa_op *ssa_op, + uint32_t op1_info, + zend_jit_addr op1_addr, + uint32_t val_info, + zend_bool op1_indirect, + zend_class_entry *ce, + zend_bool ce_is_instanceof, + zend_bool use_this, + zend_class_entry *trace_ce, + int may_throw) +{ + zval *member; + zend_string *name; + zend_property_info *prop_info; + zend_jit_addr val_addr = OP1_DATA_ADDR(); + zend_jit_addr res_addr = 0; + zend_jit_addr this_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FP, offsetof(zend_execute_data, This)); + zend_jit_addr prop_addr; + zend_bool needs_slow_path = 0; + + if (RETURN_VALUE_USED(opline)) { + res_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FP, opline->result.var); + } + + ZEND_ASSERT(opline->op2_type == IS_CONST); + ZEND_ASSERT(op1_info & MAY_BE_OBJECT); + + member = RT_CONSTANT(opline, opline->op2); + ZEND_ASSERT(Z_TYPE_P(member) == IS_STRING && Z_STRVAL_P(member)[0] != '\0'); + name = Z_STR_P(member); + prop_info = zend_get_known_property_info(ce, name, opline->op1_type == IS_UNUSED, op_array->filename); + + if (opline->op1_type == IS_UNUSED || use_this) { + | GET_ZVAL_PTR FCARG1a, this_addr + } else { + if (opline->op1_type == IS_VAR + && (op1_info & MAY_BE_INDIRECT) + && Z_REG(op1_addr) == ZREG_FP) { + | LOAD_ZVAL_ADDR FCARG1a, op1_addr + | IF_NOT_Z_TYPE FCARG1a, IS_INDIRECT, >1 + | GET_Z_PTR FCARG1a, FCARG1a + |1: + op1_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FCARG1a, 0); + } + if (op1_info & MAY_BE_REF) { + if (Z_REG(op1_addr) != ZREG_FCARG1a || Z_OFFSET(op1_addr) != 0) { + | LOAD_ZVAL_ADDR FCARG1a, op1_addr + } + | ZVAL_DEREF FCARG1a, op1_info + op1_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FCARG1a, 0); + } + if (op1_info & ((MAY_BE_UNDEF|MAY_BE_ANY)- MAY_BE_OBJECT)) { + if (JIT_G(trigger) == ZEND_JIT_ON_HOT_TRACE) { + int32_t exit_point = zend_jit_trace_get_exit_point(opline, ZEND_JIT_EXIT_TO_VM); + const void *exit_addr = zend_jit_trace_get_exit_addr(exit_point); + + if (!exit_addr) { + return 0; + } + | IF_NOT_ZVAL_TYPE op1_addr, IS_OBJECT, &exit_addr + } else { + | IF_NOT_ZVAL_TYPE op1_addr, IS_OBJECT, >1 + |.cold_code + |1: + | SET_EX_OPLINE opline, r0 + if (Z_REG(op1_addr) != ZREG_FCARG1a || Z_OFFSET(op1_addr) != 0) { + | LOAD_ZVAL_ADDR FCARG1a, op1_addr + } + | LOAD_ADDR FCARG2a, ZSTR_VAL(name) + | EXT_CALL zend_jit_invalid_property_assign, r0 + if (RETURN_VALUE_USED(opline)) { + | SET_ZVAL_TYPE_INFO res_addr, IS_NULL + } + if (((opline+1)->op1_type & (IS_VAR|IS_TMP_VAR)) + && (val_info & (MAY_BE_REF|MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE))) { + | jmp >8 + } else { + | jmp ->exception_handler + } + |.code + } + } + | GET_ZVAL_PTR FCARG1a, op1_addr + } + + if (!prop_info && trace_ce && (trace_ce->ce_flags & ZEND_ACC_IMMUTABLE)) { + prop_info = zend_get_known_property_info(trace_ce, name, opline->op1_type == IS_UNUSED, op_array->filename); + if (prop_info) { + ce = trace_ce; + ce_is_instanceof = 0; + if (!(op1_info & MAY_BE_CLASS_GUARD)) { + if (!zend_jit_class_guard(Dst, opline, trace_ce)) { + return 0; + } + if (ssa->var_info && ssa_op->op1_use >= 0) { + ssa->var_info[ssa_op->op1_use].type |= MAY_BE_CLASS_GUARD; + ssa->var_info[ssa_op->op1_use].ce = ce; + ssa->var_info[ssa_op->op1_use].is_instanceof = ce_is_instanceof; + } + if (ssa->var_info && ssa_op->op1_def >= 0) { + ssa->var_info[ssa_op->op1_def].type |= MAY_BE_CLASS_GUARD; + ssa->var_info[ssa_op->op1_def].ce = ce; + ssa->var_info[ssa_op->op1_def].is_instanceof = ce_is_instanceof; + } + } + } + } + + if (!prop_info) { + needs_slow_path = 1; + + | mov r0, EX->run_time_cache + | mov r2, aword [r0 + opline->extended_value] + | cmp r2, aword [FCARG1a + offsetof(zend_object, ce)] + | jne >5 + if (!ce || ce_is_instanceof || (ce->ce_flags & ZEND_ACC_HAS_TYPE_HINTS)) { + | mov FCARG2a, aword [r0 + (opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS) + sizeof(void*) * 2] + } + | mov r0, aword [r0 + opline->extended_value + sizeof(void*)] + | test r0, r0 + | jl >5 | IF_TYPE byte [FCARG1a + r0 + 8], IS_UNDEF, >5 | add FCARG1a, r0 prop_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FCARG1a, 0); @@ -12708,7 +13821,7 @@ static int zend_jit_echo(dasm_State **Dst, const zend_op *opline, uint32_t op1_i return 1; } -static int zend_jit_strlen(dasm_State **Dst, const zend_op *opline, uint32_t op1_info) +static int zend_jit_strlen(dasm_State **Dst, const zend_op *opline, uint32_t op1_info, zend_jit_addr op1_addr) { zend_jit_addr res_addr = RES_ADDR(); @@ -12723,17 +13836,13 @@ static int zend_jit_strlen(dasm_State **Dst, const zend_op *opline, uint32_t op1 | SET_ZVAL_LVAL res_addr, len | SET_ZVAL_TYPE_INFO res_addr, IS_LONG } else { - zend_jit_addr op1_addr = OP1_ADDR(); - ZEND_ASSERT((op1_info & (MAY_BE_UNDEF|MAY_BE_ANY|MAY_BE_REF)) == MAY_BE_STRING); | GET_ZVAL_PTR r0, op1_addr | mov r0, aword [r0 + offsetof(zend_string, len)] | SET_ZVAL_LVAL res_addr, r0 | SET_ZVAL_TYPE_INFO res_addr, IS_LONG - if (opline->op1_type & (IS_VAR|IS_TMP_VAR)) { - | ZVAL_PTR_DTOR op1_addr, op1_info, 0, 0, opline - } + | FREE_OP opline->op1_type, opline->op1, op1_info, 0, opline } return 1; } @@ -13496,10 +14605,12 @@ static int zend_jit_in_array(dasm_State **Dst, const zend_op *opline, uint32_t o | // result = zend_hash_find_ex(ht, Z_STR_P(op1), OP1_TYPE == IS_CONST); | LOAD_ADDR FCARG1a, ht - | GET_ZVAL_PTR FCARG2a, op1_addr if (opline->op1_type != IS_CONST) { + | GET_ZVAL_PTR FCARG2a, op1_addr | EXT_CALL zend_hash_find, r0 } else { + zend_string *str = Z_STR_P(RT_CONSTANT(opline, opline->op1)); + | LOAD_ADDR FCARG2a, str | EXT_CALL _zend_hash_find_known_hash, r0 } | test r0, r0 diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c index 63bd8eb792562..9fa91e83797ce 100644 --- a/ext/openssl/openssl.c +++ b/ext/openssl/openssl.c @@ -1182,7 +1182,7 @@ PHP_MINIT_FUNCTION(openssl) REGISTER_LONG_CONSTANT("X509_PURPOSE_ANY", X509_PURPOSE_ANY, CONST_CS|CONST_PERSISTENT); #endif - /* signature algorithm constants */ + /* digest algorithm constants */ REGISTER_LONG_CONSTANT("OPENSSL_ALGO_SHA1", OPENSSL_ALGO_SHA1, CONST_CS|CONST_PERSISTENT); REGISTER_LONG_CONSTANT("OPENSSL_ALGO_MD5", OPENSSL_ALGO_MD5, CONST_CS|CONST_PERSISTENT); REGISTER_LONG_CONSTANT("OPENSSL_ALGO_MD4", OPENSSL_ALGO_MD4, CONST_CS|CONST_PERSISTENT); @@ -1563,7 +1563,7 @@ PHP_FUNCTION(openssl_spki_new) mdtype = php_openssl_get_evp_md_from_algo(algo); if (!mdtype) { - php_error_docref(NULL, E_WARNING, "Unknown signature algorithm"); + php_error_docref(NULL, E_WARNING, "Unknown digest algorithm"); goto cleanup; } @@ -1589,7 +1589,7 @@ PHP_FUNCTION(openssl_spki_new) if (!NETSCAPE_SPKI_sign(spki, pkey, mdtype)) { php_openssl_store_errors(); - php_error_docref(NULL, E_WARNING, "Unable to sign with specified algorithm"); + php_error_docref(NULL, E_WARNING, "Unable to sign with specified digest algorithm"); goto cleanup; } @@ -1845,7 +1845,7 @@ zend_string* php_openssl_x509_fingerprint(X509 *peer, const char *method, zend_b zend_string *ret; if (!(mdtype = EVP_get_digestbyname(method))) { - php_error_docref(NULL, E_WARNING, "Unknown signature algorithm"); + php_error_docref(NULL, E_WARNING, "Unknown digest algorithm"); return NULL; } else if (!X509_digest(peer, mdtype, md, &n)) { php_openssl_store_errors(); @@ -2313,7 +2313,7 @@ PHP_FUNCTION(openssl_x509_checkpurpose) Z_PARAM_OBJ_OF_CLASS_OR_STR(cert_obj, php_openssl_certificate_ce, cert_str) Z_PARAM_LONG(purpose) Z_PARAM_OPTIONAL - Z_PARAM_ARRAY_OR_NULL(zcainfo) + Z_PARAM_ARRAY(zcainfo) Z_PARAM_STRING_OR_NULL(untrusted, untrusted_len) ZEND_PARSE_PARAMETERS_END(); @@ -3753,7 +3753,7 @@ static EVP_PKEY * php_openssl_generate_private_key(struct php_x509_request * req { EC_KEY *eckey; if (req->curve_name == NID_undef) { - php_error_docref(NULL, E_WARNING, "Missing configuration value: 'curve_name' not set"); + php_error_docref(NULL, E_WARNING, "Missing configuration value: \"curve_name\" not set"); return NULL; } eckey = EC_KEY_new_by_curve_name(req->curve_name); @@ -4465,11 +4465,13 @@ PHP_FUNCTION(openssl_pkey_get_private) size_t passphrase_len = sizeof("")-1; php_openssl_pkey_object *key_object; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "z|s", &cert, &passphrase, &passphrase_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z|s!", &cert, &passphrase, &passphrase_len) == FAILURE) { RETURN_THROWS(); } - PHP_OPENSSL_CHECK_SIZE_T_TO_INT(passphrase_len, passphrase, 2); + if (passphrase) { + PHP_OPENSSL_CHECK_SIZE_T_TO_INT(passphrase_len, passphrase, 2); + } pkey = php_openssl_pkey_from_zval(cert, 0, passphrase, passphrase_len); if (pkey == NULL) { @@ -4805,7 +4807,7 @@ PHP_FUNCTION(openssl_pbkdf2) } if (!digest) { - php_error_docref(NULL, E_WARNING, "Unknown signature algorithm"); + php_error_docref(NULL, E_WARNING, "Unknown digest algorithm"); RETURN_FALSE; } @@ -4847,7 +4849,7 @@ PHP_FUNCTION(openssl_pkcs7_verify) RETVAL_LONG(-1); - if (zend_parse_parameters(ZEND_NUM_ARGS(), "pl|pappp", &filename, &filename_len, + if (zend_parse_parameters(ZEND_NUM_ARGS(), "pl|p!ap!p!p!", &filename, &filename_len, &flags, &signersfilename, &signersfilename_len, &cainfo, &extracerts, &extracerts_len, &datafilename, &datafilename_len, &p7bfilename, &p7bfilename_len) == FAILURE) { RETURN_THROWS(); @@ -6082,7 +6084,7 @@ PHP_FUNCTION(openssl_cms_decrypt) Z_PARAM_PATH(outfilename, outfilename_len) Z_PARAM_ZVAL(recipcert) Z_PARAM_OPTIONAL - Z_PARAM_ZVAL(recipkey) + Z_PARAM_ZVAL_OR_NULL(recipkey) Z_PARAM_LONG(encoding) ZEND_PARSE_PARAMETERS_END(); @@ -6128,8 +6130,7 @@ PHP_FUNCTION(openssl_cms_decrypt) cms = SMIME_read_CMS(in, &datain); break; default: - php_error_docref(NULL, E_WARNING, - "Unknown OPENSSL encoding"); + zend_argument_value_error(5, "must be an OPENSSL_ENCODING_* constant"); goto clean_exit; } @@ -6456,13 +6457,18 @@ PHP_FUNCTION(openssl_sign) char * data; size_t data_len; EVP_MD_CTX *md_ctx; - zval *method = NULL; - zend_long signature_algo = OPENSSL_ALGO_SHA1; + zend_string *method_str = NULL; + zend_long method_long = OPENSSL_ALGO_SHA1; const EVP_MD *mdtype; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "szz|z", &data, &data_len, &signature, &key, &method) == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_START(3, 4) + Z_PARAM_STRING(data, data_len) + Z_PARAM_ZVAL(signature) + Z_PARAM_ZVAL(key) + Z_PARAM_OPTIONAL + Z_PARAM_STR_OR_LONG(method_str, method_long) + ZEND_PARSE_PARAMETERS_END(); + pkey = php_openssl_pkey_from_zval(key, 0, "", 0); if (pkey == NULL) { if (!EG(exception)) { @@ -6471,20 +6477,13 @@ PHP_FUNCTION(openssl_sign) RETURN_FALSE; } - if (method == NULL || Z_TYPE_P(method) == IS_LONG) { - if (method != NULL) { - signature_algo = Z_LVAL_P(method); - } - mdtype = php_openssl_get_evp_md_from_algo(signature_algo); - } else if (Z_TYPE_P(method) == IS_STRING) { - mdtype = EVP_get_digestbyname(Z_STRVAL_P(method)); + if (method_str) { + mdtype = EVP_get_digestbyname(ZSTR_VAL(method_str)); } else { - // TODO Use proper ZPP check. - zend_argument_type_error(4, "must be of type string|int|null, %s given" , zend_zval_type_name(method)); - RETURN_THROWS(); + mdtype = php_openssl_get_evp_md_from_algo(method_long); } if (!mdtype) { - php_error_docref(NULL, E_WARNING, "Unknown signature algorithm"); + php_error_docref(NULL, E_WARNING, "Unknown digest algorithm"); RETURN_FALSE; } @@ -6522,29 +6521,26 @@ PHP_FUNCTION(openssl_verify) size_t data_len; char * signature; size_t signature_len; - zval *method = NULL; - zend_long signature_algo = OPENSSL_ALGO_SHA1; + zend_string *method_str = NULL; + zend_long method_long = OPENSSL_ALGO_SHA1; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "ssz|z", &data, &data_len, &signature, &signature_len, &key, &method) == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_START(3, 4) + Z_PARAM_STRING(data, data_len) + Z_PARAM_STRING(signature, signature_len) + Z_PARAM_ZVAL(key) + Z_PARAM_OPTIONAL + Z_PARAM_STR_OR_LONG(method_str, method_long) + ZEND_PARSE_PARAMETERS_END(); PHP_OPENSSL_CHECK_SIZE_T_TO_UINT(signature_len, signature, 2); - if (method == NULL || Z_TYPE_P(method) == IS_LONG) { - if (method != NULL) { - signature_algo = Z_LVAL_P(method); - } - mdtype = php_openssl_get_evp_md_from_algo(signature_algo); - } else if (Z_TYPE_P(method) == IS_STRING) { - mdtype = EVP_get_digestbyname(Z_STRVAL_P(method)); + if (method_str) { + mdtype = EVP_get_digestbyname(ZSTR_VAL(method_str)); } else { - // TODO Use proper ZPP check. - zend_argument_type_error(4, "must be of type string|int|null, %s given" , zend_zval_type_name(method)); - RETURN_THROWS(); + mdtype = php_openssl_get_evp_md_from_algo(method_long); } if (!mdtype) { - php_error_docref(NULL, E_WARNING, "Unknown signature algorithm"); + php_error_docref(NULL, E_WARNING, "Unknown digest algorithm"); RETURN_FALSE; } @@ -6579,8 +6575,8 @@ PHP_FUNCTION(openssl_seal) unsigned char iv_buf[EVP_MAX_IV_LENGTH + 1], *buf = NULL, **eks; char * data; size_t data_len; - char *method =NULL; - size_t method_len = 0; + char *method; + size_t method_len; const EVP_CIPHER *cipher; EVP_CIPHER_CTX *ctx; @@ -6600,13 +6596,13 @@ PHP_FUNCTION(openssl_seal) cipher = EVP_get_cipherbyname(method); if (!cipher) { - php_error_docref(NULL, E_WARNING, "Unknown signature algorithm"); + php_error_docref(NULL, E_WARNING, "Unknown cipher algorithm"); RETURN_FALSE; } iv_len = EVP_CIPHER_iv_length(cipher); if (!iv && iv_len > 0) { - zend_argument_value_error(6, "must provide an IV for chosen cipher algorithm"); + zend_argument_value_error(6, "cannot be null for the chosen cipher algorithm"); RETURN_THROWS(); } @@ -6707,11 +6703,11 @@ PHP_FUNCTION(openssl_open) size_t data_len; char * ekey; size_t ekey_len; - char *method = NULL, *iv = NULL; - size_t method_len = 0, iv_len = 0; + char *method, *iv = NULL; + size_t method_len, iv_len = 0; const EVP_CIPHER *cipher; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "szszs|s", &data, &data_len, &opendata, + if (zend_parse_parameters(ZEND_NUM_ARGS(), "szszs|s!", &data, &data_len, &opendata, &ekey, &ekey_len, &privkey, &method, &method_len, &iv, &iv_len) == FAILURE) { RETURN_THROWS(); } @@ -6729,14 +6725,14 @@ PHP_FUNCTION(openssl_open) cipher = EVP_get_cipherbyname(method); if (!cipher) { - php_error_docref(NULL, E_WARNING, "Unknown signature algorithm"); + php_error_docref(NULL, E_WARNING, "Unknown cipher algorithm"); RETURN_FALSE; } cipher_iv_len = EVP_CIPHER_iv_length(cipher); if (cipher_iv_len > 0) { if (!iv) { - zend_argument_value_error(6, "must provide an IV for chosen cipher algorithm"); + zend_argument_value_error(6, "cannot be null for the chosen cipher algorithm"); RETURN_THROWS(); } if ((size_t)cipher_iv_len != iv_len) { @@ -6782,7 +6778,7 @@ static void php_openssl_add_method(const OBJ_NAME *name, void *arg) /* {{{ */ } /* }}} */ -/* {{{ Return array of available digest methods */ +/* {{{ Return array of available digest algorithms */ PHP_FUNCTION(openssl_get_md_methods) { zend_bool aliases = 0; @@ -6797,7 +6793,7 @@ PHP_FUNCTION(openssl_get_md_methods) } /* }}} */ -/* {{{ Return array of available cipher methods */ +/* {{{ Return array of available cipher algorithms */ PHP_FUNCTION(openssl_get_cipher_methods) { zend_bool aliases = 0; @@ -6858,7 +6854,7 @@ PHP_FUNCTION(openssl_digest) } mdtype = EVP_get_digestbyname(method); if (!mdtype) { - php_error_docref(NULL, E_WARNING, "Unknown signature algorithm"); + php_error_docref(NULL, E_WARNING, "Unknown digest algorithm"); RETURN_FALSE; } @@ -7012,7 +7008,7 @@ static int php_openssl_cipher_init(const EVP_CIPHER *cipher_type, } } else if (!enc && tag && tag_len > 0) { if (!mode->is_aead) { - php_error_docref(NULL, E_WARNING, "The tag cannot be used because the cipher method does not support AEAD"); + php_error_docref(NULL, E_WARNING, "The tag cannot be used because the cipher algorithm does not support AEAD"); } else if (!EVP_CIPHER_CTX_ctrl(cipher_ctx, mode->aead_set_tag_flag, tag_len, (unsigned char *) tag)) { php_error_docref(NULL, E_WARNING, "Setting tag for AEAD cipher decryption failed"); return FAILURE; @@ -7024,7 +7020,7 @@ static int php_openssl_cipher_init(const EVP_CIPHER *cipher_type, if (key_len > password_len) { if ((OPENSSL_DONT_ZERO_PAD_KEY & options) && !EVP_CIPHER_CTX_set_key_length(cipher_ctx, password_len)) { php_openssl_store_errors(); - php_error_docref(NULL, E_WARNING, "Key length cannot be set for the cipher method"); + php_error_docref(NULL, E_WARNING, "Key length cannot be set for the cipher algorithm"); return FAILURE; } key = emalloc(key_len); diff --git a/ext/openssl/openssl.stub.php b/ext/openssl/openssl.stub.php index 36fdcf42af24c..21bc936b08fa2 100644 --- a/ext/openssl/openssl.stub.php +++ b/ext/openssl/openssl.stub.php @@ -14,77 +14,74 @@ final class OpenSSLAsymmetricKey { } -function openssl_x509_export_to_file(OpenSSLCertificate|string $x509, string $outfilename, bool $notext = true): bool {} +function openssl_x509_export_to_file(OpenSSLCertificate|string $certificate, string $output_filename, bool $no_text = true): bool {} -/** @param string $out */ -function openssl_x509_export(OpenSSLCertificate|string $x509, &$out, bool $notext = true): bool {} +/** @param string $output */ +function openssl_x509_export(OpenSSLCertificate|string $certificate, &$output, bool $no_text = true): bool {} -function openssl_x509_fingerprint(OpenSSLCertificate|string $x509, string $method = "sha1", bool $raw_output = false): string|false {} +function openssl_x509_fingerprint(OpenSSLCertificate|string $certificate, string $digest_algorithm = "sha1", bool $raw_output = false): string|false {} -/** @param OpenSSLAsymmetricKey|OpenSSLCertificate|array|string $key */ -function openssl_x509_check_private_key(OpenSSLCertificate|string $x509, $key): bool {} +/** @param OpenSSLAsymmetricKey|OpenSSLCertificate|array|string $private_key */ +function openssl_x509_check_private_key(OpenSSLCertificate|string $certificate, $private_key): bool {} -/** @param OpenSSLAsymmetricKey|OpenSSLCertificate|array|string $key */ -function openssl_x509_verify(OpenSSLCertificate|string $x509, $key): int {} +/** @param OpenSSLAsymmetricKey|OpenSSLCertificate|array|string $public_key */ +function openssl_x509_verify(OpenSSLCertificate|string $certificate, $public_key): int {} -function openssl_x509_parse(OpenSSLCertificate|string $x509, bool $shortname = true): array|false {} +function openssl_x509_parse(OpenSSLCertificate|string $certificate, bool $short_names = true): array|false {} -function openssl_x509_checkpurpose(OpenSSLCertificate|string $x509, int $purpose, ?array $cainfo = [], ?string $untrustedfile = null): bool|int {} +function openssl_x509_checkpurpose(OpenSSLCertificate|string $certificate, int $purpose, array $ca_info = [], ?string $untrusted_certificates_file = null): bool|int {} -function openssl_x509_read(OpenSSLCertificate|string $x509): OpenSSLCertificate|false {} +function openssl_x509_read(OpenSSLCertificate|string $certificate): OpenSSLCertificate|false {} /** @deprecated */ -function openssl_x509_free(OpenSSLCertificate $x509): void {} +function openssl_x509_free(OpenSSLCertificate $certificate): void {} -/** @param OpenSSLAsymmetricKey|OpenSSLCertificate|array|string $priv_key */ -function openssl_pkcs12_export_to_file(OpenSSLCertificate|string $x509cert, string $filename, $priv_key, string $pass, array $args = []): bool {} +/** @param OpenSSLAsymmetricKey|OpenSSLCertificate|array|string $private_key */ +function openssl_pkcs12_export_to_file(OpenSSLCertificate|string $certificate, string $output_filename, $private_key, string $passphrase, array $options = []): bool {} /** - * @param string $out - * @param OpenSSLAsymmetricKey|OpenSSLCertificate|array|string $priv_key + * @param string $output + * @param OpenSSLAsymmetricKey|OpenSSLCertificate|array|string $private_key */ -function openssl_pkcs12_export(OpenSSLCertificate|string $x509, &$out, $priv_key, string $pass, array $args = []): bool {} +function openssl_pkcs12_export(OpenSSLCertificate|string $certificate, &$output, $private_key, string $passphrase, array $options = []): bool {} -/** @param array $certs */ -function openssl_pkcs12_read(string $pkcs12, &$certs, string $pass): bool {} +/** @param array $certificates */ +function openssl_pkcs12_read(string $pkcs12, &$certificates, string $passphrase): bool {} -function openssl_csr_export_to_file(OpenSSLCertificateSigningRequest|string $csr, string $outfilename, bool $notext = true): bool {} +function openssl_csr_export_to_file(OpenSSLCertificateSigningRequest|string $csr, string $output_filename, bool $no_text = true): bool {} -/** @param OpenSSLAsymmetricKey $out */ -function openssl_csr_export(OpenSSLCertificateSigningRequest|string $csr, &$out, bool $notext = true): bool {} +/** @param OpenSSLAsymmetricKey $output */ +function openssl_csr_export(OpenSSLCertificateSigningRequest|string $csr, &$output, bool $no_text = true): bool {} -/** @param OpenSSLAsymmetricKey|OpenSSLCertificate|array|string $priv_key */ -function openssl_csr_sign(OpenSSLCertificateSigningRequest|string $csr, OpenSSLCertificate|string|null $cacert, $priv_key, int $days, ?array $config_args = null, int $serial = 0): OpenSSLCertificate|false {} +/** @param OpenSSLAsymmetricKey|OpenSSLCertificate|array|string $private_key */ +function openssl_csr_sign(OpenSSLCertificateSigningRequest|string $csr, OpenSSLCertificate|string|null $ca_certificate, $private_key, int $days, ?array $options = null, int $serial = 0): OpenSSLCertificate|false {} -/** @param OpenSSLAsymmetricKey $privkey */ -function openssl_csr_new(array $dn, &$privkey, ?array $configargs = null, ?array $extraattribs = null): OpenSSLCertificateSigningRequest|false {} +/** @param OpenSSLAsymmetricKey $private_key */ +function openssl_csr_new(array $distinguished_names, &$private_key, ?array $options = null, ?array $extra_attributes = null): OpenSSLCertificateSigningRequest|false {} -function openssl_csr_get_subject(OpenSSLCertificateSigningRequest|string $csr, bool $use_shortnames = true): array|false {} +function openssl_csr_get_subject(OpenSSLCertificateSigningRequest|string $csr, bool $short_names = true): array|false {} -function openssl_csr_get_public_key(OpenSSLCertificateSigningRequest|string $csr, bool $use_shortnames = true): OpenSSLAsymmetricKey|false {} +function openssl_csr_get_public_key(OpenSSLCertificateSigningRequest|string $csr, bool $short_names = true): OpenSSLAsymmetricKey|false {} -function openssl_pkey_new(?array $configargs = null): OpenSSLAsymmetricKey|false {} +function openssl_pkey_new(?array $options = null): OpenSSLAsymmetricKey|false {} -/** - * @param OpenSSLAsymmetricKey|OpenSSLCertificate|array|string $key - * @param string $out - */ -function openssl_pkey_export_to_file($key, string $outfilename, ?string $passphrase = null, ?array $configargs = null): bool {} +/** @param OpenSSLAsymmetricKey|OpenSSLCertificate|array|string $key */ +function openssl_pkey_export_to_file($key, string $output_filename, ?string $passphrase = null, ?array $options = null): bool {} /** * @param OpenSSLAsymmetricKey|OpenSSLCertificate|array|string $key - * @param string $out + * @param string $output */ -function openssl_pkey_export($key, &$out, ?string $passphrase = null, ?array $configargs = null): bool {} +function openssl_pkey_export($key, &$output, ?string $passphrase = null, ?array $options = null): bool {} -/** @param OpenSSLAsymmetricKey|OpenSSLCertificate|array|string $cert */ -function openssl_pkey_get_public($cert): OpenSSLAsymmetricKey|false {} +/** @param OpenSSLAsymmetricKey|OpenSSLCertificate|array|string $public_key */ +function openssl_pkey_get_public($public_key): OpenSSLAsymmetricKey|false {} /** - * @param OpenSSLAsymmetricKey|OpenSSLCertificate|array|string $cert + * @param OpenSSLAsymmetricKey|OpenSSLCertificate|array|string $public_key * @alias openssl_pkey_get_public */ -function openssl_get_publickey($cert): OpenSSLAsymmetricKey|false {} +function openssl_get_publickey($public_key): OpenSSLAsymmetricKey|false {} /** @deprecated */ function openssl_pkey_free(OpenSSLAsymmetricKey $key): void {} @@ -95,105 +92,100 @@ function openssl_pkey_free(OpenSSLAsymmetricKey $key): void {} */ function openssl_free_key(OpenSSLAsymmetricKey $key): void {} -/** @param OpenSSLAsymmetricKey|OpenSSLCertificate|array|string $key */ -function openssl_pkey_get_private($key, string $passphrase = UNKNOWN): OpenSSLAsymmetricKey|false {} +/** @param OpenSSLAsymmetricKey|OpenSSLCertificate|array|string $private_key */ +function openssl_pkey_get_private($private_key, ?string $passphrase = null): OpenSSLAsymmetricKey|false {} /** - * @param OpenSSLAsymmetricKey|OpenSSLCertificate|array|string $key + * @param OpenSSLAsymmetricKey|OpenSSLCertificate|array|string $private_key * @alias openssl_pkey_get_private */ -function openssl_get_privatekey($key, string $passphrase = UNKNOWN): OpenSSLAsymmetricKey|false {} +function openssl_get_privatekey($private_key, ?string $passphrase = null): OpenSSLAsymmetricKey|false {} function openssl_pkey_get_details(OpenSSLAsymmetricKey $key): array|false {} -function openssl_pbkdf2(string $password, string $salt, int $key_length, int $iterations, string $digest_algorithm = 'sha1'): string|false {} +function openssl_pbkdf2(string $passphrase, string $salt, int $key_length, int $iterations, string $digest_algorithm = "sha1"): string|false {} -function openssl_pkcs7_verify(string $filename, int $flags, string $signerscerts = UNKNOWN, array $cainfo = UNKNOWN, string $extracerts = UNKNOWN, string $content = UNKNOWN, string $pk7 = UNKNOWN): bool|int {} +function openssl_pkcs7_verify(string $input_filename, int $flags, ?string $signers_certificates_filename = null, array $ca_info = [], ?string $untrusted_certificates_filename = null, ?string $content = null, ?string $output_filename = null): bool|int {} -/** @param OpenSSLCertificate|array|string $recipcerts */ -function openssl_pkcs7_encrypt(string $infile, string $outfile, $recipcerts, ?array $headers, int $flags = 0, int $cipher = OPENSSL_CIPHER_RC2_40): bool {} +/** @param OpenSSLCertificate|array|string $certificate */ +function openssl_pkcs7_encrypt(string $input_filename, string $output_filename, $certificate, ?array $headers, int $flags = 0, int $cipher_algorithm = OPENSSL_CIPHER_RC2_40): bool {} -/** @param OpenSSLAsymmetricKey|OpenSSLCertificate|array|string $signkey */ -function openssl_pkcs7_sign(string $infile, string $outfile, OpenSSLCertificate|string $signcert, $signkey, ?array $headers, int $flags = PKCS7_DETACHED, ?string $extracertsfilename = null): bool {} +/** @param OpenSSLAsymmetricKey|OpenSSLCertificate|array|string $private_key */ +function openssl_pkcs7_sign(string $input_filename, string $output_filename, OpenSSLCertificate|string $certificate, $private_key, ?array $headers, int $flags = PKCS7_DETACHED, ?string $untrusted_certificates_filename = null): bool {} /** - * @param OpenSSLCertificate|string $recipcert - * @param OpenSSLAsymmetricKey|OpenSSLCertificate|array|string|null $recipkey + * @param OpenSSLCertificate|string $certificate + * @param OpenSSLAsymmetricKey|OpenSSLCertificate|array|string|null $private_key */ -function openssl_pkcs7_decrypt(string $infilename, string $outfilename, $recipcert, $recipkey = null): bool {} +function openssl_pkcs7_decrypt(string $input_filename, string $output_filename, $certificate, $private_key = null): bool {} -/** @param array $certs */ -function openssl_pkcs7_read(string $infilename, &$certs): bool {} +/** @param array $certificates */ +function openssl_pkcs7_read(string $input_filename, &$certificates): bool {} -function openssl_cms_verify(string $filename, int $flags = 0, ?string $signerscerts = null, ?array $cainfo = null, ?string $extracerts = null, ?string $content = null, ?string $pk7 = null, ?string $sigfile = null, int $encoding = OPENSSL_ENCODING_SMIME): bool {} +function openssl_cms_verify(string $input_filename, int $flags = 0, ?string $certificates = null, array $ca_info = [], ?string $untrusted_certificates_filename = null, ?string $content = null, ?string $pk7 = null, ?string $sigfile = null, int $encoding = OPENSSL_ENCODING_SMIME): bool {} -/** @param OpenSSLCertificate|array|string $recipcerts */ -function openssl_cms_encrypt(string $infile, string $outfile, $recipcerts, ?array $headers, int $flags = 0, int $encoding = OPENSSL_ENCODING_SMIME, int $cipher = OPENSSL_CIPHER_RC2_40): bool {} +/** @param OpenSSLCertificate|array|string $certificate */ +function openssl_cms_encrypt(string $input_filename, string $output_filename, $certificate, ?array $headers, int $flags = 0, int $encoding = OPENSSL_ENCODING_SMIME, int $cipher_algorithm = OPENSSL_CIPHER_RC2_40): bool {} -/** @param OpenSSLAsymmetricKey|OpenSSLCertificate|array|string $signkey */ -function openssl_cms_sign(string $infile, string $outfile, OpenSSLCertificate|string $signcert, $signkey, ?array $headers, int $flags = 0, int $encoding = OPENSSL_ENCODING_SMIME, ?string $extracertsfilename = null): bool {} +/** @param OpenSSLAsymmetricKey|OpenSSLCertificate|array|string $private_key */ +function openssl_cms_sign(string $input_filename, string $output_filename, OpenSSLCertificate|string $certificate, $private_key, ?array $headers, int $flags = 0, int $encoding = OPENSSL_ENCODING_SMIME, ?string $untrusted_certificates_filename = null): bool {} /** - * @param OpenSSLCertificate|string $recipcert - * @param OpenSSLAsymmetricKey|OpenSSLCertificate|array|string $recipkey + * @param OpenSSLCertificate|string $certificate + * @param OpenSSLAsymmetricKey|OpenSSLCertificate|array|string|null $private_key */ -function openssl_cms_decrypt(string $infilename, string $outfilename, $recipcert, $recipkey = UNKNOWN, int $encoding = OPENSSL_ENCODING_SMIME): bool {} +function openssl_cms_decrypt(string $input_filename, string $output_filename, $certificate, $private_key = null, int $encoding = OPENSSL_ENCODING_SMIME): bool {} -/** @param array $certs */ -function openssl_cms_read(string $infilename, &$certs): bool {} +/** @param array $certificates */ +function openssl_cms_read(string $input_filename, &$certificates): bool {} /** - * @param string $crypted - * @param OpenSSLAsymmetricKey|OpenSSLCertificate|array|string $key + * @param string $encrypted_data + * @param OpenSSLAsymmetricKey|OpenSSLCertificate|array|string $private_key */ -function openssl_private_encrypt(string $data, &$crypted, $key, int $padding = OPENSSL_PKCS1_PADDING): bool {} +function openssl_private_encrypt(string $data, &$encrypted_data, $private_key, int $padding = OPENSSL_PKCS1_PADDING): bool {} /** - * @param string $crypted - * @param OpenSSLAsymmetricKey|OpenSSLCertificate|array|string $key + * @param string $decrypted_data + * @param OpenSSLAsymmetricKey|OpenSSLCertificate|array|string $private_key */ -function openssl_private_decrypt(string $data, &$crypted, $key, int $padding = OPENSSL_PKCS1_PADDING): bool {} +function openssl_private_decrypt(string $data, &$decrypted_data, $private_key, int $padding = OPENSSL_PKCS1_PADDING): bool {} /** - * @param string $crypted - * @param OpenSSLAsymmetricKey|OpenSSLCertificate|array|string $key + * @param string $encrypted_data + * @param OpenSSLAsymmetricKey|OpenSSLCertificate|array|string $public_key */ -function openssl_public_encrypt(string $data, &$crypted, $key, int $padding = OPENSSL_PKCS1_PADDING): bool {} +function openssl_public_encrypt(string $data, &$encrypted_data, $public_key, int $padding = OPENSSL_PKCS1_PADDING): bool {} /** - * @param string $crypted - * @param OpenSSLAsymmetricKey|OpenSSLCertificate|array|string $key + * @param string $decrypted_data + * @param OpenSSLAsymmetricKey|OpenSSLCertificate|array|string $public_key */ -function openssl_public_decrypt(string $data, &$crypted, $key, int $padding = OPENSSL_PKCS1_PADDING): bool {} +function openssl_public_decrypt(string $data, &$decrypted_data, $public_key, int $padding = OPENSSL_PKCS1_PADDING): bool {} function openssl_error_string(): string|false {} /** * @param string $signature - * @param OpenSSLAsymmetricKey|OpenSSLCertificate|array|string $key - * @param int|string $method + * @param OpenSSLAsymmetricKey|OpenSSLCertificate|array|string $private_key */ -function openssl_sign(string $data, &$signature, $key, $method = OPENSSL_ALGO_SHA1): bool {} +function openssl_sign(string $data, &$signature, $private_key, string|int $algorithm = OPENSSL_ALGO_SHA1): bool {} -/** - * @param OpenSSLAsymmetricKey|OpenSSLCertificate|array|string $key - * @param int|string $method - */ -function openssl_verify(string $data, string $signature, $key, $method = OPENSSL_ALGO_SHA1): int|false {} +/** @param OpenSSLAsymmetricKey|OpenSSLCertificate|array|string $public_key */ +function openssl_verify(string $data, string $signature, $public_key, string|int $algorithm = OPENSSL_ALGO_SHA1): int|false {} /** - * @param string $sealdata - * @param array $ekeys - * @param OpenSSLAsymmetricKey|OpenSSLCertificate|array|string $pubkeys + * @param string $sealed_data + * @param array $encrypted_keys * @param string $iv */ -function openssl_seal(string $data, &$sealdata, &$ekeys, array $pubkeys, string $method, &$iv = UNKNOWN): int|false {} +function openssl_seal(string $data, &$sealed_data, &$encrypted_keys, array $public_key, string $cipher_algorithm, &$iv = null): int|false {} /** - * @param string $opendata - * @param OpenSSLAsymmetricKey|OpenSSLCertificate|array|string $privkey + * @param string $output + * @param OpenSSLAsymmetricKey|OpenSSLCertificate|array|string $private_key */ -function openssl_open(string $data, &$opendata, string $ekey, $privkey, string $method, string $iv = UNKNOWN): bool {} +function openssl_open(string $data, &$output, string $encrypted_key, $private_key, string $cipher_algorithm, ?string $iv = null): bool {} function openssl_get_md_methods(bool $aliases = false): array {} @@ -203,27 +195,27 @@ function openssl_get_cipher_methods(bool $aliases = false): array {} function openssl_get_curve_names(): array|false {} #endif -function openssl_digest(string $data, string $method, bool $raw_output = false): string|false {} +function openssl_digest(string $data, string $digest_algorithm, bool $raw_output = false): string|false {} /** @param string $tag */ -function openssl_encrypt(string $data, string $method, string $password, int $options = 0, string $iv = '', &$tag = UNKNOWN, string $aad = '', int $tag_length = 16): string|false {} +function openssl_encrypt(string $data, string $cipher_algorithm, string $passphrase, int $options = 0, string $iv = "", &$tag = null, string $aad = "", int $tag_length = 16): string|false {} -function openssl_decrypt(string $data, string $method, string $password, int $options = 0, string $iv = '', string $tag = UNKNOWN, string $aad = ''): string|false {} +function openssl_decrypt(string $data, string $cipher_algorithm, string $passphrase, int $options = 0, string $iv = "", string $tag = "", string $aad = ""): string|false {} -function openssl_cipher_iv_length(string $method): int|false {} +function openssl_cipher_iv_length(string $cipher_algorithm): int|false {} -function openssl_dh_compute_key(string $pub_key, OpenSSLAsymmetricKey $dh_key): string|false {} +function openssl_dh_compute_key(string $public_key, OpenSSLAsymmetricKey $private_key): string|false {} /** - * @param OpenSSLAsymmetricKey|OpenSSLCertificate|array|string $peer_pub_key - * @param OpenSSLAsymmetricKey|OpenSSLCertificate|array|string $priv_key + * @param OpenSSLAsymmetricKey|OpenSSLCertificate|array|string $public_key + * @param OpenSSLAsymmetricKey|OpenSSLCertificate|array|string $private_key */ -function openssl_pkey_derive($peer_pub_key, $priv_key, int $keylen = 0): string|false {} +function openssl_pkey_derive($public_key, $private_key, int $key_length = 0): string|false {} -/** @param bool $result_is_strong */ -function openssl_random_pseudo_bytes(int $length, &$result_is_strong = UNKNOWN): string {} +/** @param bool $strong_result */ +function openssl_random_pseudo_bytes(int $length, &$strong_result = null): string {} -function openssl_spki_new(OpenSSLAsymmetricKey $privkey, string $challenge, int $algo = OPENSSL_ALGO_MD5): string|false {} +function openssl_spki_new(OpenSSLAsymmetricKey $private_key, string $challenge, int $digest_algorithm = OPENSSL_ALGO_MD5): string|false {} function openssl_spki_verify(string $spki): bool {} diff --git a/ext/openssl/openssl_arginfo.h b/ext/openssl/openssl_arginfo.h index dd877268228cd..7700cba8e5480 100644 --- a/ext/openssl/openssl_arginfo.h +++ b/ext/openssl/openssl_arginfo.h @@ -1,134 +1,134 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 7f1066b832ce307914f641de5ed2c40ec10290ba */ + * Stub hash: 40f9897413f966bd483d8f133f6fa3b80910e3d5 */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_openssl_x509_export_to_file, 0, 2, _IS_BOOL, 0) - ZEND_ARG_OBJ_TYPE_MASK(0, x509, OpenSSLCertificate, MAY_BE_STRING, NULL) - ZEND_ARG_TYPE_INFO(0, outfilename, IS_STRING, 0) - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, notext, _IS_BOOL, 0, "true") + ZEND_ARG_OBJ_TYPE_MASK(0, certificate, OpenSSLCertificate, MAY_BE_STRING, NULL) + ZEND_ARG_TYPE_INFO(0, output_filename, IS_STRING, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, no_text, _IS_BOOL, 0, "true") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_openssl_x509_export, 0, 2, _IS_BOOL, 0) - ZEND_ARG_OBJ_TYPE_MASK(0, x509, OpenSSLCertificate, MAY_BE_STRING, NULL) - ZEND_ARG_INFO(1, out) - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, notext, _IS_BOOL, 0, "true") + ZEND_ARG_OBJ_TYPE_MASK(0, certificate, OpenSSLCertificate, MAY_BE_STRING, NULL) + ZEND_ARG_INFO(1, output) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, no_text, _IS_BOOL, 0, "true") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_openssl_x509_fingerprint, 0, 1, MAY_BE_STRING|MAY_BE_FALSE) - ZEND_ARG_OBJ_TYPE_MASK(0, x509, OpenSSLCertificate, MAY_BE_STRING, NULL) - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, method, IS_STRING, 0, "\"sha1\"") + ZEND_ARG_OBJ_TYPE_MASK(0, certificate, OpenSSLCertificate, MAY_BE_STRING, NULL) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, digest_algorithm, IS_STRING, 0, "\"sha1\"") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, raw_output, _IS_BOOL, 0, "false") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_openssl_x509_check_private_key, 0, 2, _IS_BOOL, 0) - ZEND_ARG_OBJ_TYPE_MASK(0, x509, OpenSSLCertificate, MAY_BE_STRING, NULL) - ZEND_ARG_INFO(0, key) + ZEND_ARG_OBJ_TYPE_MASK(0, certificate, OpenSSLCertificate, MAY_BE_STRING, NULL) + ZEND_ARG_INFO(0, private_key) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_openssl_x509_verify, 0, 2, IS_LONG, 0) - ZEND_ARG_OBJ_TYPE_MASK(0, x509, OpenSSLCertificate, MAY_BE_STRING, NULL) - ZEND_ARG_INFO(0, key) + ZEND_ARG_OBJ_TYPE_MASK(0, certificate, OpenSSLCertificate, MAY_BE_STRING, NULL) + ZEND_ARG_INFO(0, public_key) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_openssl_x509_parse, 0, 1, MAY_BE_ARRAY|MAY_BE_FALSE) - ZEND_ARG_OBJ_TYPE_MASK(0, x509, OpenSSLCertificate, MAY_BE_STRING, NULL) - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, shortname, _IS_BOOL, 0, "true") + ZEND_ARG_OBJ_TYPE_MASK(0, certificate, OpenSSLCertificate, MAY_BE_STRING, NULL) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, short_names, _IS_BOOL, 0, "true") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_openssl_x509_checkpurpose, 0, 2, MAY_BE_BOOL|MAY_BE_LONG) - ZEND_ARG_OBJ_TYPE_MASK(0, x509, OpenSSLCertificate, MAY_BE_STRING, NULL) + ZEND_ARG_OBJ_TYPE_MASK(0, certificate, OpenSSLCertificate, MAY_BE_STRING, NULL) ZEND_ARG_TYPE_INFO(0, purpose, IS_LONG, 0) - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, cainfo, IS_ARRAY, 1, "[]") - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, untrustedfile, IS_STRING, 1, "null") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, ca_info, IS_ARRAY, 0, "[]") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, untrusted_certificates_file, IS_STRING, 1, "null") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_openssl_x509_read, 0, 1, OpenSSLCertificate, MAY_BE_FALSE) - ZEND_ARG_OBJ_TYPE_MASK(0, x509, OpenSSLCertificate, MAY_BE_STRING, NULL) + ZEND_ARG_OBJ_TYPE_MASK(0, certificate, OpenSSLCertificate, MAY_BE_STRING, NULL) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_openssl_x509_free, 0, 1, IS_VOID, 0) - ZEND_ARG_OBJ_INFO(0, x509, OpenSSLCertificate, 0) + ZEND_ARG_OBJ_INFO(0, certificate, OpenSSLCertificate, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_openssl_pkcs12_export_to_file, 0, 4, _IS_BOOL, 0) - ZEND_ARG_OBJ_TYPE_MASK(0, x509cert, OpenSSLCertificate, MAY_BE_STRING, NULL) - ZEND_ARG_TYPE_INFO(0, filename, IS_STRING, 0) - ZEND_ARG_INFO(0, priv_key) - ZEND_ARG_TYPE_INFO(0, pass, IS_STRING, 0) - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, args, IS_ARRAY, 0, "[]") + ZEND_ARG_OBJ_TYPE_MASK(0, certificate, OpenSSLCertificate, MAY_BE_STRING, NULL) + ZEND_ARG_TYPE_INFO(0, output_filename, IS_STRING, 0) + ZEND_ARG_INFO(0, private_key) + ZEND_ARG_TYPE_INFO(0, passphrase, IS_STRING, 0) + 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_openssl_pkcs12_export, 0, 4, _IS_BOOL, 0) - ZEND_ARG_OBJ_TYPE_MASK(0, x509, OpenSSLCertificate, MAY_BE_STRING, NULL) - ZEND_ARG_INFO(1, out) - ZEND_ARG_INFO(0, priv_key) - ZEND_ARG_TYPE_INFO(0, pass, IS_STRING, 0) - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, args, IS_ARRAY, 0, "[]") + ZEND_ARG_OBJ_TYPE_MASK(0, certificate, OpenSSLCertificate, MAY_BE_STRING, NULL) + ZEND_ARG_INFO(1, output) + ZEND_ARG_INFO(0, private_key) + ZEND_ARG_TYPE_INFO(0, passphrase, IS_STRING, 0) + 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_openssl_pkcs12_read, 0, 3, _IS_BOOL, 0) ZEND_ARG_TYPE_INFO(0, pkcs12, IS_STRING, 0) - ZEND_ARG_INFO(1, certs) - ZEND_ARG_TYPE_INFO(0, pass, IS_STRING, 0) + ZEND_ARG_INFO(1, certificates) + ZEND_ARG_TYPE_INFO(0, passphrase, IS_STRING, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_openssl_csr_export_to_file, 0, 2, _IS_BOOL, 0) ZEND_ARG_OBJ_TYPE_MASK(0, csr, OpenSSLCertificateSigningRequest, MAY_BE_STRING, NULL) - ZEND_ARG_TYPE_INFO(0, outfilename, IS_STRING, 0) - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, notext, _IS_BOOL, 0, "true") + ZEND_ARG_TYPE_INFO(0, output_filename, IS_STRING, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, no_text, _IS_BOOL, 0, "true") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_openssl_csr_export, 0, 2, _IS_BOOL, 0) ZEND_ARG_OBJ_TYPE_MASK(0, csr, OpenSSLCertificateSigningRequest, MAY_BE_STRING, NULL) - ZEND_ARG_INFO(1, out) - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, notext, _IS_BOOL, 0, "true") + ZEND_ARG_INFO(1, output) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, no_text, _IS_BOOL, 0, "true") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_openssl_csr_sign, 0, 4, OpenSSLCertificate, MAY_BE_FALSE) ZEND_ARG_OBJ_TYPE_MASK(0, csr, OpenSSLCertificateSigningRequest, MAY_BE_STRING, NULL) - ZEND_ARG_OBJ_TYPE_MASK(0, cacert, OpenSSLCertificate, MAY_BE_STRING|MAY_BE_NULL, NULL) - ZEND_ARG_INFO(0, priv_key) + ZEND_ARG_OBJ_TYPE_MASK(0, ca_certificate, OpenSSLCertificate, MAY_BE_STRING|MAY_BE_NULL, NULL) + ZEND_ARG_INFO(0, private_key) ZEND_ARG_TYPE_INFO(0, days, IS_LONG, 0) - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, config_args, IS_ARRAY, 1, "null") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, options, IS_ARRAY, 1, "null") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, serial, IS_LONG, 0, "0") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_openssl_csr_new, 0, 2, OpenSSLCertificateSigningRequest, MAY_BE_FALSE) - ZEND_ARG_TYPE_INFO(0, dn, IS_ARRAY, 0) - ZEND_ARG_INFO(1, privkey) - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, configargs, IS_ARRAY, 1, "null") - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, extraattribs, IS_ARRAY, 1, "null") + ZEND_ARG_TYPE_INFO(0, distinguished_names, IS_ARRAY, 0) + ZEND_ARG_INFO(1, private_key) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, options, IS_ARRAY, 1, "null") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, extra_attributes, IS_ARRAY, 1, "null") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_openssl_csr_get_subject, 0, 1, MAY_BE_ARRAY|MAY_BE_FALSE) ZEND_ARG_OBJ_TYPE_MASK(0, csr, OpenSSLCertificateSigningRequest, MAY_BE_STRING, NULL) - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, use_shortnames, _IS_BOOL, 0, "true") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, short_names, _IS_BOOL, 0, "true") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_openssl_csr_get_public_key, 0, 1, OpenSSLAsymmetricKey, MAY_BE_FALSE) ZEND_ARG_OBJ_TYPE_MASK(0, csr, OpenSSLCertificateSigningRequest, MAY_BE_STRING, NULL) - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, use_shortnames, _IS_BOOL, 0, "true") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, short_names, _IS_BOOL, 0, "true") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_openssl_pkey_new, 0, 0, OpenSSLAsymmetricKey, MAY_BE_FALSE) - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, configargs, IS_ARRAY, 1, "null") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, options, IS_ARRAY, 1, "null") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_openssl_pkey_export_to_file, 0, 2, _IS_BOOL, 0) ZEND_ARG_INFO(0, key) - ZEND_ARG_TYPE_INFO(0, outfilename, IS_STRING, 0) + ZEND_ARG_TYPE_INFO(0, output_filename, IS_STRING, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, passphrase, IS_STRING, 1, "null") - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, configargs, IS_ARRAY, 1, "null") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, options, IS_ARRAY, 1, "null") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_openssl_pkey_export, 0, 2, _IS_BOOL, 0) ZEND_ARG_INFO(0, key) - ZEND_ARG_INFO(1, out) + ZEND_ARG_INFO(1, output) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, passphrase, IS_STRING, 1, "null") - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, configargs, IS_ARRAY, 1, "null") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, options, IS_ARRAY, 1, "null") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_openssl_pkey_get_public, 0, 1, OpenSSLAsymmetricKey, MAY_BE_FALSE) - ZEND_ARG_INFO(0, cert) + ZEND_ARG_INFO(0, public_key) ZEND_END_ARG_INFO() #define arginfo_openssl_get_publickey arginfo_openssl_pkey_get_public @@ -140,8 +140,8 @@ ZEND_END_ARG_INFO() #define arginfo_openssl_free_key arginfo_openssl_pkey_free ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_openssl_pkey_get_private, 0, 1, OpenSSLAsymmetricKey, MAY_BE_FALSE) - ZEND_ARG_INFO(0, key) - ZEND_ARG_TYPE_INFO(0, passphrase, IS_STRING, 0) + ZEND_ARG_INFO(0, private_key) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, passphrase, IS_STRING, 1, "null") ZEND_END_ARG_INFO() #define arginfo_openssl_get_privatekey arginfo_openssl_pkey_get_private @@ -151,60 +151,60 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_openssl_pkey_get_details, 0, 1, ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_openssl_pbkdf2, 0, 4, MAY_BE_STRING|MAY_BE_FALSE) - ZEND_ARG_TYPE_INFO(0, password, IS_STRING, 0) + ZEND_ARG_TYPE_INFO(0, passphrase, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, salt, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, key_length, IS_LONG, 0) ZEND_ARG_TYPE_INFO(0, iterations, IS_LONG, 0) - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, digest_algorithm, IS_STRING, 0, "\'sha1\'") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, digest_algorithm, IS_STRING, 0, "\"sha1\"") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_openssl_pkcs7_verify, 0, 2, MAY_BE_BOOL|MAY_BE_LONG) - ZEND_ARG_TYPE_INFO(0, filename, IS_STRING, 0) + ZEND_ARG_TYPE_INFO(0, input_filename, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, flags, IS_LONG, 0) - ZEND_ARG_TYPE_INFO(0, signerscerts, IS_STRING, 0) - ZEND_ARG_TYPE_INFO(0, cainfo, IS_ARRAY, 0) - ZEND_ARG_TYPE_INFO(0, extracerts, IS_STRING, 0) - ZEND_ARG_TYPE_INFO(0, content, IS_STRING, 0) - ZEND_ARG_TYPE_INFO(0, pk7, IS_STRING, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, signers_certificates_filename, IS_STRING, 1, "null") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, ca_info, IS_ARRAY, 0, "[]") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, untrusted_certificates_filename, IS_STRING, 1, "null") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, content, IS_STRING, 1, "null") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, output_filename, IS_STRING, 1, "null") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_openssl_pkcs7_encrypt, 0, 4, _IS_BOOL, 0) - ZEND_ARG_TYPE_INFO(0, infile, IS_STRING, 0) - ZEND_ARG_TYPE_INFO(0, outfile, IS_STRING, 0) - ZEND_ARG_INFO(0, recipcerts) + ZEND_ARG_TYPE_INFO(0, input_filename, IS_STRING, 0) + ZEND_ARG_TYPE_INFO(0, output_filename, IS_STRING, 0) + ZEND_ARG_INFO(0, certificate) ZEND_ARG_TYPE_INFO(0, headers, IS_ARRAY, 1) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, flags, IS_LONG, 0, "0") - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, cipher, IS_LONG, 0, "OPENSSL_CIPHER_RC2_40") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, cipher_algorithm, IS_LONG, 0, "OPENSSL_CIPHER_RC2_40") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_openssl_pkcs7_sign, 0, 5, _IS_BOOL, 0) - ZEND_ARG_TYPE_INFO(0, infile, IS_STRING, 0) - ZEND_ARG_TYPE_INFO(0, outfile, IS_STRING, 0) - ZEND_ARG_OBJ_TYPE_MASK(0, signcert, OpenSSLCertificate, MAY_BE_STRING, NULL) - ZEND_ARG_INFO(0, signkey) + ZEND_ARG_TYPE_INFO(0, input_filename, IS_STRING, 0) + ZEND_ARG_TYPE_INFO(0, output_filename, IS_STRING, 0) + ZEND_ARG_OBJ_TYPE_MASK(0, certificate, OpenSSLCertificate, MAY_BE_STRING, NULL) + ZEND_ARG_INFO(0, private_key) ZEND_ARG_TYPE_INFO(0, headers, IS_ARRAY, 1) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, flags, IS_LONG, 0, "PKCS7_DETACHED") - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, extracertsfilename, IS_STRING, 1, "null") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, untrusted_certificates_filename, IS_STRING, 1, "null") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_openssl_pkcs7_decrypt, 0, 3, _IS_BOOL, 0) - ZEND_ARG_TYPE_INFO(0, infilename, IS_STRING, 0) - ZEND_ARG_TYPE_INFO(0, outfilename, IS_STRING, 0) - ZEND_ARG_INFO(0, recipcert) - ZEND_ARG_INFO_WITH_DEFAULT_VALUE(0, recipkey, "null") + ZEND_ARG_TYPE_INFO(0, input_filename, IS_STRING, 0) + ZEND_ARG_TYPE_INFO(0, output_filename, IS_STRING, 0) + ZEND_ARG_INFO(0, certificate) + ZEND_ARG_INFO_WITH_DEFAULT_VALUE(0, private_key, "null") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_openssl_pkcs7_read, 0, 2, _IS_BOOL, 0) - ZEND_ARG_TYPE_INFO(0, infilename, IS_STRING, 0) - ZEND_ARG_INFO(1, certs) + ZEND_ARG_TYPE_INFO(0, input_filename, IS_STRING, 0) + ZEND_ARG_INFO(1, certificates) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_openssl_cms_verify, 0, 1, _IS_BOOL, 0) - ZEND_ARG_TYPE_INFO(0, filename, IS_STRING, 0) + ZEND_ARG_TYPE_INFO(0, input_filename, IS_STRING, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, flags, IS_LONG, 0, "0") - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, signerscerts, IS_STRING, 1, "null") - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, cainfo, IS_ARRAY, 1, "null") - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, extracerts, IS_STRING, 1, "null") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, certificates, IS_STRING, 1, "null") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, ca_info, IS_ARRAY, 0, "[]") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, untrusted_certificates_filename, IS_STRING, 1, "null") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, content, IS_STRING, 1, "null") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, pk7, IS_STRING, 1, "null") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, sigfile, IS_STRING, 1, "null") @@ -212,31 +212,31 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_openssl_cms_verify, 0, 1, _IS_BO ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_openssl_cms_encrypt, 0, 4, _IS_BOOL, 0) - ZEND_ARG_TYPE_INFO(0, infile, IS_STRING, 0) - ZEND_ARG_TYPE_INFO(0, outfile, IS_STRING, 0) - ZEND_ARG_INFO(0, recipcerts) + ZEND_ARG_TYPE_INFO(0, input_filename, IS_STRING, 0) + ZEND_ARG_TYPE_INFO(0, output_filename, IS_STRING, 0) + ZEND_ARG_INFO(0, certificate) ZEND_ARG_TYPE_INFO(0, headers, IS_ARRAY, 1) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, flags, IS_LONG, 0, "0") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, encoding, IS_LONG, 0, "OPENSSL_ENCODING_SMIME") - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, cipher, IS_LONG, 0, "OPENSSL_CIPHER_RC2_40") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, cipher_algorithm, IS_LONG, 0, "OPENSSL_CIPHER_RC2_40") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_openssl_cms_sign, 0, 5, _IS_BOOL, 0) - ZEND_ARG_TYPE_INFO(0, infile, IS_STRING, 0) - ZEND_ARG_TYPE_INFO(0, outfile, IS_STRING, 0) - ZEND_ARG_OBJ_TYPE_MASK(0, signcert, OpenSSLCertificate, MAY_BE_STRING, NULL) - ZEND_ARG_INFO(0, signkey) + ZEND_ARG_TYPE_INFO(0, input_filename, IS_STRING, 0) + ZEND_ARG_TYPE_INFO(0, output_filename, IS_STRING, 0) + ZEND_ARG_OBJ_TYPE_MASK(0, certificate, OpenSSLCertificate, MAY_BE_STRING, NULL) + ZEND_ARG_INFO(0, private_key) ZEND_ARG_TYPE_INFO(0, headers, IS_ARRAY, 1) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, flags, IS_LONG, 0, "0") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, encoding, IS_LONG, 0, "OPENSSL_ENCODING_SMIME") - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, extracertsfilename, IS_STRING, 1, "null") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, untrusted_certificates_filename, IS_STRING, 1, "null") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_openssl_cms_decrypt, 0, 3, _IS_BOOL, 0) - ZEND_ARG_TYPE_INFO(0, infilename, IS_STRING, 0) - ZEND_ARG_TYPE_INFO(0, outfilename, IS_STRING, 0) - ZEND_ARG_INFO(0, recipcert) - ZEND_ARG_INFO(0, recipkey) + ZEND_ARG_TYPE_INFO(0, input_filename, IS_STRING, 0) + ZEND_ARG_TYPE_INFO(0, output_filename, IS_STRING, 0) + ZEND_ARG_INFO(0, certificate) + ZEND_ARG_INFO_WITH_DEFAULT_VALUE(0, private_key, "null") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, encoding, IS_LONG, 0, "OPENSSL_ENCODING_SMIME") ZEND_END_ARG_INFO() @@ -244,16 +244,31 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_openssl_private_encrypt, 0, 3, _IS_BOOL, 0) ZEND_ARG_TYPE_INFO(0, data, IS_STRING, 0) - ZEND_ARG_INFO(1, crypted) - ZEND_ARG_INFO(0, key) + ZEND_ARG_INFO(1, encrypted_data) + ZEND_ARG_INFO(0, private_key) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, padding, IS_LONG, 0, "OPENSSL_PKCS1_PADDING") ZEND_END_ARG_INFO() -#define arginfo_openssl_private_decrypt arginfo_openssl_private_encrypt +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_openssl_private_decrypt, 0, 3, _IS_BOOL, 0) + ZEND_ARG_TYPE_INFO(0, data, IS_STRING, 0) + ZEND_ARG_INFO(1, decrypted_data) + ZEND_ARG_INFO(0, private_key) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, padding, IS_LONG, 0, "OPENSSL_PKCS1_PADDING") +ZEND_END_ARG_INFO() -#define arginfo_openssl_public_encrypt arginfo_openssl_private_encrypt +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_openssl_public_encrypt, 0, 3, _IS_BOOL, 0) + ZEND_ARG_TYPE_INFO(0, data, IS_STRING, 0) + ZEND_ARG_INFO(1, encrypted_data) + ZEND_ARG_INFO(0, public_key) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, padding, IS_LONG, 0, "OPENSSL_PKCS1_PADDING") +ZEND_END_ARG_INFO() -#define arginfo_openssl_public_decrypt arginfo_openssl_private_encrypt +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_openssl_public_decrypt, 0, 3, _IS_BOOL, 0) + ZEND_ARG_TYPE_INFO(0, data, IS_STRING, 0) + ZEND_ARG_INFO(1, decrypted_data) + ZEND_ARG_INFO(0, public_key) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, padding, IS_LONG, 0, "OPENSSL_PKCS1_PADDING") +ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_openssl_error_string, 0, 0, MAY_BE_STRING|MAY_BE_FALSE) ZEND_END_ARG_INFO() @@ -261,33 +276,33 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_openssl_sign, 0, 3, _IS_BOOL, 0) ZEND_ARG_TYPE_INFO(0, data, IS_STRING, 0) ZEND_ARG_INFO(1, signature) - ZEND_ARG_INFO(0, key) - ZEND_ARG_INFO_WITH_DEFAULT_VALUE(0, method, "OPENSSL_ALGO_SHA1") + ZEND_ARG_INFO(0, private_key) + ZEND_ARG_TYPE_MASK(0, algorithm, MAY_BE_STRING|MAY_BE_LONG, "OPENSSL_ALGO_SHA1") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_openssl_verify, 0, 3, MAY_BE_LONG|MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(0, data, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, signature, IS_STRING, 0) - ZEND_ARG_INFO(0, key) - ZEND_ARG_INFO_WITH_DEFAULT_VALUE(0, method, "OPENSSL_ALGO_SHA1") + ZEND_ARG_INFO(0, public_key) + ZEND_ARG_TYPE_MASK(0, algorithm, MAY_BE_STRING|MAY_BE_LONG, "OPENSSL_ALGO_SHA1") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_openssl_seal, 0, 5, MAY_BE_LONG|MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(0, data, IS_STRING, 0) - ZEND_ARG_INFO(1, sealdata) - ZEND_ARG_INFO(1, ekeys) - ZEND_ARG_TYPE_INFO(0, pubkeys, IS_ARRAY, 0) - ZEND_ARG_TYPE_INFO(0, method, IS_STRING, 0) - ZEND_ARG_INFO(1, iv) + ZEND_ARG_INFO(1, sealed_data) + ZEND_ARG_INFO(1, encrypted_keys) + ZEND_ARG_TYPE_INFO(0, public_key, IS_ARRAY, 0) + ZEND_ARG_TYPE_INFO(0, cipher_algorithm, IS_STRING, 0) + ZEND_ARG_INFO_WITH_DEFAULT_VALUE(1, iv, "null") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_openssl_open, 0, 5, _IS_BOOL, 0) ZEND_ARG_TYPE_INFO(0, data, IS_STRING, 0) - ZEND_ARG_INFO(1, opendata) - ZEND_ARG_TYPE_INFO(0, ekey, IS_STRING, 0) - ZEND_ARG_INFO(0, privkey) - ZEND_ARG_TYPE_INFO(0, method, IS_STRING, 0) - ZEND_ARG_TYPE_INFO(0, iv, IS_STRING, 0) + ZEND_ARG_INFO(1, output) + ZEND_ARG_TYPE_INFO(0, encrypted_key, IS_STRING, 0) + ZEND_ARG_INFO(0, private_key) + ZEND_ARG_TYPE_INFO(0, cipher_algorithm, IS_STRING, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, iv, IS_STRING, 1, "null") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_openssl_get_md_methods, 0, 0, IS_ARRAY, 0) @@ -303,55 +318,55 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_openssl_digest, 0, 2, MAY_BE_STRING|MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(0, data, IS_STRING, 0) - ZEND_ARG_TYPE_INFO(0, method, IS_STRING, 0) + ZEND_ARG_TYPE_INFO(0, digest_algorithm, IS_STRING, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, raw_output, _IS_BOOL, 0, "false") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_openssl_encrypt, 0, 3, MAY_BE_STRING|MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(0, data, IS_STRING, 0) - ZEND_ARG_TYPE_INFO(0, method, IS_STRING, 0) - ZEND_ARG_TYPE_INFO(0, password, IS_STRING, 0) + ZEND_ARG_TYPE_INFO(0, cipher_algorithm, IS_STRING, 0) + ZEND_ARG_TYPE_INFO(0, passphrase, IS_STRING, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, options, IS_LONG, 0, "0") - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, iv, IS_STRING, 0, "\'\'") - ZEND_ARG_INFO(1, tag) - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, aad, IS_STRING, 0, "\'\'") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, iv, IS_STRING, 0, "\"\"") + ZEND_ARG_INFO_WITH_DEFAULT_VALUE(1, tag, "null") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, aad, IS_STRING, 0, "\"\"") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, tag_length, IS_LONG, 0, "16") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_openssl_decrypt, 0, 3, MAY_BE_STRING|MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(0, data, IS_STRING, 0) - ZEND_ARG_TYPE_INFO(0, method, IS_STRING, 0) - ZEND_ARG_TYPE_INFO(0, password, IS_STRING, 0) + ZEND_ARG_TYPE_INFO(0, cipher_algorithm, IS_STRING, 0) + ZEND_ARG_TYPE_INFO(0, passphrase, IS_STRING, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, options, IS_LONG, 0, "0") - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, iv, IS_STRING, 0, "\'\'") - ZEND_ARG_TYPE_INFO(0, tag, IS_STRING, 0) - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, aad, IS_STRING, 0, "\'\'") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, iv, IS_STRING, 0, "\"\"") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, tag, IS_STRING, 0, "\"\"") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, aad, IS_STRING, 0, "\"\"") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_openssl_cipher_iv_length, 0, 1, MAY_BE_LONG|MAY_BE_FALSE) - ZEND_ARG_TYPE_INFO(0, method, IS_STRING, 0) + ZEND_ARG_TYPE_INFO(0, cipher_algorithm, IS_STRING, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_openssl_dh_compute_key, 0, 2, MAY_BE_STRING|MAY_BE_FALSE) - ZEND_ARG_TYPE_INFO(0, pub_key, IS_STRING, 0) - ZEND_ARG_OBJ_INFO(0, dh_key, OpenSSLAsymmetricKey, 0) + ZEND_ARG_TYPE_INFO(0, public_key, IS_STRING, 0) + ZEND_ARG_OBJ_INFO(0, private_key, OpenSSLAsymmetricKey, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_openssl_pkey_derive, 0, 2, MAY_BE_STRING|MAY_BE_FALSE) - ZEND_ARG_INFO(0, peer_pub_key) - ZEND_ARG_INFO(0, priv_key) - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, keylen, IS_LONG, 0, "0") + ZEND_ARG_INFO(0, public_key) + ZEND_ARG_INFO(0, private_key) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, key_length, IS_LONG, 0, "0") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_openssl_random_pseudo_bytes, 0, 1, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, length, IS_LONG, 0) - ZEND_ARG_INFO(1, result_is_strong) + ZEND_ARG_INFO_WITH_DEFAULT_VALUE(1, strong_result, "null") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_openssl_spki_new, 0, 2, MAY_BE_STRING|MAY_BE_FALSE) - ZEND_ARG_OBJ_INFO(0, privkey, OpenSSLAsymmetricKey, 0) + ZEND_ARG_OBJ_INFO(0, private_key, OpenSSLAsymmetricKey, 0) ZEND_ARG_TYPE_INFO(0, challenge, IS_STRING, 0) - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, algo, IS_LONG, 0, "OPENSSL_ALGO_MD5") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, digest_algorithm, IS_LONG, 0, "OPENSSL_ALGO_MD5") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_openssl_spki_verify, 0, 1, _IS_BOOL, 0) diff --git a/ext/openssl/tests/bug38261.phpt b/ext/openssl/tests/bug38261.phpt index 827f3aca75535..9cb16e3e8f70d 100644 --- a/ext/openssl/tests/bug38261.phpt +++ b/ext/openssl/tests/bug38261.phpt @@ -40,6 +40,6 @@ try { --EXPECT-- bool(false) bool(false) -openssl_x509_parse(): Argument #1 ($x509) must be of type OpenSSLCertificate|string, array given +openssl_x509_parse(): Argument #1 ($certificate) must be of type OpenSSLCertificate|string, array given bool(false) -openssl_x509_parse(): Argument #1 ($x509) must be of type OpenSSLCertificate|string, stdClass given +openssl_x509_parse(): Argument #1 ($certificate) must be of type OpenSSLCertificate|string, stdClass given diff --git a/ext/openssl/tests/bug60632.phpt b/ext/openssl/tests/bug60632.phpt index 3f2b0f0197e01..483b58f347f82 100644 --- a/ext/openssl/tests/bug60632.phpt +++ b/ext/openssl/tests/bug60632.phpt @@ -27,4 +27,4 @@ try { } ?> --EXPECT-- -openssl_seal(): Argument #6 ($iv) must provide an IV for chosen cipher algorithm +openssl_seal(): Argument #6 ($iv) cannot be null for the chosen cipher algorithm diff --git a/ext/openssl/tests/bug68912.phpt b/ext/openssl/tests/bug68912.phpt index 64d1a9b60a515..97e75df54572d 100644 --- a/ext/openssl/tests/bug68912.phpt +++ b/ext/openssl/tests/bug68912.phpt @@ -19,4 +19,4 @@ try { } ?> --EXPECT-- -openssl_spki_new(): Argument #1 ($privkey) must be of type OpenSSLAsymmetricKey, resource given +openssl_spki_new(): Argument #1 ($private_key) must be of type OpenSSLAsymmetricKey, resource given diff --git a/ext/openssl/tests/bug70438.phpt b/ext/openssl/tests/bug70438.phpt index 173f0a0066645..8f19f6ac1719a 100644 --- a/ext/openssl/tests/bug70438.phpt +++ b/ext/openssl/tests/bug70438.phpt @@ -26,7 +26,7 @@ openssl_open($sealed, $decrypted, $ekeys[0], $priv_key, $cipher, $iv); echo $decrypted; ?> --EXPECTF-- -openssl_seal(): Argument #6 ($iv) must provide an IV for chosen cipher algorithm +openssl_seal(): Argument #6 ($iv) cannot be null for the chosen cipher algorithm -Warning: openssl_seal(): Unknown signature algorithm in %s on line %d +Warning: openssl_seal(): Unknown cipher algorithm in %s on line %d openssl_seal() test diff --git a/ext/openssl/tests/openssl_csr_sign_basic.phpt b/ext/openssl/tests/openssl_csr_sign_basic.phpt index 8d32ad1943acd..7d856b71bf677 100644 --- a/ext/openssl/tests/openssl_csr_sign_basic.phpt +++ b/ext/openssl/tests/openssl_csr_sign_basic.phpt @@ -76,7 +76,7 @@ bool(false) Warning: openssl_csr_sign(): X.509 Certificate Signing Request cannot be retrieved in %s on line %d bool(false) openssl_csr_sign(): Argument #1 ($csr) must be of type OpenSSLCertificateSigningRequest|string, array given -openssl_csr_sign(): Argument #2 ($cacert) must be of type OpenSSLCertificate|string|null, array given +openssl_csr_sign(): Argument #2 ($ca_certificate) must be of type OpenSSLCertificate|string|null, array given Key array must be of the form array(0 => key, 1 => phrase) object(OpenSSLCertificate)#%d (0) { } diff --git a/ext/openssl/tests/openssl_encrypt_error.phpt b/ext/openssl/tests/openssl_encrypt_error.phpt index 53bc371f4606f..0b1bc662f77cc 100644 --- a/ext/openssl/tests/openssl_encrypt_error.phpt +++ b/ext/openssl/tests/openssl_encrypt_error.phpt @@ -28,5 +28,5 @@ bool(false) Warning: openssl_encrypt(): The authenticated tag cannot be provided for cipher that doesn not support AEAD in %s on line %d string(44) "iPR4HulskuaP5Z6me5uImk6BqVyJG73+63tkPauVZYk=" -Warning: openssl_encrypt(): Key length cannot be set for the cipher method in %s on line %d +Warning: openssl_encrypt(): Key length cannot be set for the cipher algorithm in %s on line %d bool(false) diff --git a/ext/openssl/tests/openssl_pkcs12_export_basic.phpt b/ext/openssl/tests/openssl_pkcs12_export_basic.phpt index fc8a146c0c4e4..03947f3a497f5 100644 --- a/ext/openssl/tests/openssl_pkcs12_export_basic.phpt +++ b/ext/openssl/tests/openssl_pkcs12_export_basic.phpt @@ -53,4 +53,4 @@ bool(false) Warning: openssl_pkcs12_export(): X.509 Certificate cannot be retrieved in %s on line %d bool(false) -openssl_pkcs12_export(): Argument #1 ($x509) must be of type OpenSSLCertificate|string, OpenSSLAsymmetricKey given +openssl_pkcs12_export(): Argument #1 ($certificate) must be of type OpenSSLCertificate|string, OpenSSLAsymmetricKey given diff --git a/ext/openssl/tests/openssl_pkcs12_export_to_file_basic.phpt b/ext/openssl/tests/openssl_pkcs12_export_to_file_basic.phpt index 69363fe34f55a..43d51753a01a2 100644 --- a/ext/openssl/tests/openssl_pkcs12_export_to_file_basic.phpt +++ b/ext/openssl/tests/openssl_pkcs12_export_to_file_basic.phpt @@ -58,4 +58,4 @@ bool(false) Warning: openssl_pkcs12_export_to_file(): X.509 Certificate cannot be retrieved in %s on line %d bool(false) -openssl_pkcs12_export_to_file(): Argument #1 ($x509cert) must be of type OpenSSLCertificate|string, OpenSSLAsymmetricKey given +openssl_pkcs12_export_to_file(): Argument #1 ($certificate) must be of type OpenSSLCertificate|string, OpenSSLAsymmetricKey given diff --git a/ext/openssl/tests/openssl_seal_basic.phpt b/ext/openssl/tests/openssl_seal_basic.phpt index bdbbd01208aa6..16efb05a665c5 100644 --- a/ext/openssl/tests/openssl_seal_basic.phpt +++ b/ext/openssl/tests/openssl_seal_basic.phpt @@ -40,13 +40,13 @@ var_dump(openssl_seal($data, $sealed, $ekeys, array($wrong), $method)); --EXPECTF-- Warning: openssl_seal(): Not a public key (1th member of pubkeys) in %s on line %d bool(false) -openssl_seal(): Argument #4 ($pubkeys) cannot be empty +openssl_seal(): Argument #4 ($public_key) cannot be empty int(19) int(19) Warning: openssl_seal(): Not a public key (2th member of pubkeys) in %s on line %d bool(false) -openssl_seal(): Argument #4 ($pubkeys) cannot be empty +openssl_seal(): Argument #4 ($public_key) cannot be empty Warning: openssl_seal(): Not a public key (1th member of pubkeys) in %s on line %d bool(false) diff --git a/ext/openssl/tests/openssl_x509_export_basic.phpt b/ext/openssl/tests/openssl_x509_export_basic.phpt index 43dc843b702b3..2f872960199ca 100644 --- a/ext/openssl/tests/openssl_x509_export_basic.phpt +++ b/ext/openssl/tests/openssl_x509_export_basic.phpt @@ -40,7 +40,7 @@ bool(true) Warning: openssl_x509_export(): X.509 Certificate cannot be retrieved in %s on line %d bool(false) bool(true) -openssl_x509_export(): Argument #1 ($x509) must be of type OpenSSLCertificate|string, array given +openssl_x509_export(): Argument #1 ($certificate) must be of type OpenSSLCertificate|string, array given int(0) int(0) int(%d) diff --git a/ext/openssl/tests/openssl_x509_export_to_file_basic.phpt b/ext/openssl/tests/openssl_x509_export_to_file_basic.phpt index 71a494f40196f..60cbd480c3903 100644 --- a/ext/openssl/tests/openssl_x509_export_to_file_basic.phpt +++ b/ext/openssl/tests/openssl_x509_export_to_file_basic.phpt @@ -39,6 +39,6 @@ bool(true) Warning: openssl_x509_export_to_file(): X.509 Certificate cannot be retrieved in %s on line %d bool(false) bool(true) -openssl_x509_export_to_file(): Argument #1 ($x509) must be of type OpenSSLCertificate|string, array given +openssl_x509_export_to_file(): Argument #1 ($certificate) must be of type OpenSSLCertificate|string, array given --- bool(true) diff --git a/ext/openssl/tests/openssl_x509_fingerprint_basic.phpt b/ext/openssl/tests/openssl_x509_fingerprint_basic.phpt index c4524ada0b1a0..456049edf9585 100644 --- a/ext/openssl/tests/openssl_x509_fingerprint_basic.phpt +++ b/ext/openssl/tests/openssl_x509_fingerprint_basic.phpt @@ -40,5 +40,5 @@ Warning: openssl_x509_fingerprint(): X.509 Certificate cannot be retrieved in %s bool(false) ** Testing bad hash method ** -Warning: openssl_x509_fingerprint(): Unknown signature algorithm in %s on line %d +Warning: openssl_x509_fingerprint(): Unknown digest algorithm in %s on line %d bool(false) diff --git a/ext/openssl/tests/openssl_x509_read_basic.phpt b/ext/openssl/tests/openssl_x509_read_basic.phpt index e4d956b120706..60d7a1eee7751 100644 --- a/ext/openssl/tests/openssl_x509_read_basic.phpt +++ b/ext/openssl/tests/openssl_x509_read_basic.phpt @@ -42,5 +42,5 @@ Warning: openssl_x509_read(): X.509 Certificate cannot be retrieved in %s on lin bool(false) object(OpenSSLCertificate)#%d (0) { } -openssl_x509_read(): Argument #1 ($x509) must be of type OpenSSLCertificate|string, array given -openssl_x509_read(): Argument #1 ($x509) must be of type OpenSSLCertificate|string, array given +openssl_x509_read(): Argument #1 ($certificate) must be of type OpenSSLCertificate|string, array given +openssl_x509_read(): Argument #1 ($certificate) must be of type OpenSSLCertificate|string, array given diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c index 35285a42dd287..42c423e6bd8cf 100644 --- a/ext/pcre/php_pcre.c +++ b/ext/pcre/php_pcre.c @@ -2398,9 +2398,9 @@ PHP_FUNCTION(preg_replace_callback) /* {{{ Perform Perl-style regular expression replacement using replacement callback. */ PHP_FUNCTION(preg_replace_callback_array) { - zval zv, *replace, *subject, *zcount = NULL; - HashTable *pattern; - zend_string *str_idx_regex; + zval zv, *replace, *zcount = NULL; + HashTable *pattern, *subject_ht; + zend_string *subject_str, *str_idx_regex; zend_long limit = -1, flags = 0; size_t replace_count = 0; zend_fcall_info fci; @@ -2409,7 +2409,7 @@ PHP_FUNCTION(preg_replace_callback_array) /* Get function parameters and do error-checking. */ ZEND_PARSE_PARAMETERS_START(2, 5) Z_PARAM_ARRAY_HT(pattern) - Z_PARAM_ZVAL(subject) + Z_PARAM_ARRAY_HT_OR_STR(subject_ht, subject_str) Z_PARAM_OPTIONAL Z_PARAM_LONG(limit) Z_PARAM_ZVAL(zcount) @@ -2420,41 +2420,66 @@ PHP_FUNCTION(preg_replace_callback_array) fci.object = NULL; fci.named_params = NULL; + if (subject_ht) { + GC_TRY_ADDREF(subject_ht); + } else { + GC_TRY_ADDREF(subject_str); + } + ZEND_HASH_FOREACH_STR_KEY_VAL(pattern, str_idx_regex, replace) { if (!str_idx_regex) { php_error_docref(NULL, E_WARNING, "Delimiter must not be alphanumeric or backslash"); - zval_ptr_dtor(return_value); - RETURN_NULL(); + RETVAL_NULL(); + goto error; } if (!zend_is_callable_ex(replace, NULL, 0, NULL, &fcc, NULL)) { zend_argument_type_error(1, "must contain only valid callbacks"); - RETURN_THROWS(); + goto error; } ZVAL_COPY_VALUE(&fci.function_name, replace); replace_count += preg_replace_func_impl(&zv, str_idx_regex, /* regex_ht */ NULL, &fci, &fcc, - Z_STR_P(subject), Z_ARRVAL_P(subject), - limit, flags); - - if (subject != return_value) { - subject = return_value; - } else { - zval_ptr_dtor(return_value); + subject_str, subject_ht, limit, flags); + switch (Z_TYPE(zv)) { + case IS_ARRAY: + ZEND_ASSERT(subject_ht); + zend_array_release(subject_ht); + subject_ht = Z_ARR(zv); + break; + case IS_STRING: + ZEND_ASSERT(subject_str); + zend_string_release(subject_str); + subject_str = Z_STR(zv); + break; + case IS_NULL: + RETVAL_NULL(); + goto error; + EMPTY_SWITCH_DEFAULT_CASE() } - ZVAL_COPY_VALUE(return_value, &zv); - - if (UNEXPECTED(EG(exception))) { - zval_ptr_dtor(return_value); - RETURN_NULL(); + if (EG(exception)) { + goto error; } } ZEND_HASH_FOREACH_END(); if (zcount) { ZEND_TRY_ASSIGN_REF_LONG(zcount, replace_count); } + + if (subject_ht) { + RETURN_ARR(subject_ht); + } else { + RETURN_STR(subject_str); + } + +error: + if (subject_ht) { + zend_array_release(subject_ht); + } else { + zend_string_release(subject_str); + } } /* }}} */ diff --git a/ext/pcre/php_pcre.stub.php b/ext/pcre/php_pcre.stub.php index eb8b4f3b173c9..f620d119fd538 100644 --- a/ext/pcre/php_pcre.stub.php +++ b/ext/pcre/php_pcre.stub.php @@ -17,11 +17,8 @@ function preg_filter(string|array $regex, string|array $replace, string|array $s /** @param int $count */ function preg_replace_callback(string|array $regex, callable $callback, string|array $subject, int $limit = -1, &$count = null, int $flags = 0): string|array|null {} -/** - * @param array|string $subject - * @param int $count - */ -function preg_replace_callback_array(array $pattern, $subject, int $limit = -1, &$count = null, int $flags = 0): string|array|null {} +/** @param int $count */ +function preg_replace_callback_array(array $pattern, string|array $subject, int $limit = -1, &$count = null, int $flags = 0): string|array|null {} function preg_split(string $pattern, string $subject, int $limit = -1, int $flags = 0): array|false {} diff --git a/ext/pcre/php_pcre_arginfo.h b/ext/pcre/php_pcre_arginfo.h index 42019169107f0..d1d816cfa0f39 100644 --- a/ext/pcre/php_pcre_arginfo.h +++ b/ext/pcre/php_pcre_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 8e8fea5b33408e8a1a39c1b1ae71f16fe1bdd391 */ + * Stub hash: 8270971708afa7fa9d82bec0f84c66cc8283f17d */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_preg_match, 0, 2, MAY_BE_LONG|MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(0, pattern, IS_STRING, 0) @@ -38,7 +38,7 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_preg_replace_callback_array, 0, 2, MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_NULL) ZEND_ARG_TYPE_INFO(0, pattern, IS_ARRAY, 0) - ZEND_ARG_INFO(0, subject) + ZEND_ARG_TYPE_MASK(0, subject, MAY_BE_STRING|MAY_BE_ARRAY, NULL) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, limit, IS_LONG, 0, "-1") ZEND_ARG_INFO_WITH_DEFAULT_VALUE(1, count, "null") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, flags, IS_LONG, 0, "0") diff --git a/ext/pcre/tests/bug73392.phpt b/ext/pcre/tests/bug73392.phpt index 704cc3d3515bc..7546f5d99fb8d 100644 --- a/ext/pcre/tests/bug73392.phpt +++ b/ext/pcre/tests/bug73392.phpt @@ -21,7 +21,5 @@ var_dump(preg_replace_callback_array( ), 'a')); ?> --EXPECTF-- -Warning: preg_replace_callback_array(): Delimiter must not be alphanumeric or backslash in %sbug73392.php on line %d - Warning: preg_replace_callback_array(): Delimiter must not be alphanumeric or backslash in %sbug73392.php on line %d NULL diff --git a/ext/pcre/tests/preg_replace_callback_array.phpt b/ext/pcre/tests/preg_replace_callback_array.phpt index ffefa2cc2634b..cf872547f3fb1 100644 --- a/ext/pcre/tests/preg_replace_callback_array.phpt +++ b/ext/pcre/tests/preg_replace_callback_array.phpt @@ -39,11 +39,21 @@ var_dump(preg_replace_callback_array( "/c/" => new Rep, "/a/" => 'b', "/b/" => function($a) { return "ok"; }), 'a', -1, $count)); - var_dump($count); + +var_dump(preg_replace_callback_array( + array('/a/' => 'b', "/c/" => new Rep), + array('a', 'c'))); + ?> --EXPECT-- string(2) "ok" string(2) "ok" string(2) "ok" int(2) +array(2) { + [0]=> + string(1) "b" + [1]=> + string(1) "d" +} diff --git a/ext/pdo_mysql/pdo_mysql.c b/ext/pdo_mysql/pdo_mysql.c index 73b4ccd7b13c2..84828edaa45ae 100644 --- a/ext/pdo_mysql/pdo_mysql.c +++ b/ext/pdo_mysql/pdo_mysql.c @@ -63,10 +63,7 @@ static MYSQLND * pdo_mysql_convert_zv_to_mysqlnd(zval * zv) if (Z_TYPE_P(zv) == IS_OBJECT && instanceof_function(Z_OBJCE_P(zv), php_pdo_get_dbh_ce())) { pdo_dbh_t * dbh = Z_PDO_DBH_P(zv); - if (!dbh) { - php_error_docref(NULL, E_WARNING, "Failed to retrieve handle from object store"); - return NULL; - } + ZEND_ASSERT(dbh); if (dbh->driver != &pdo_mysql_driver) { php_error_docref(NULL, E_WARNING, "Provided PDO instance is not using MySQL but %s", dbh->driver->driver_name); diff --git a/ext/pdo_oci/oci_statement.c b/ext/pdo_oci/oci_statement.c index 6e121dd9b717b..0ab043f041d75 100644 --- a/ext/pdo_oci/oci_statement.c +++ b/ext/pdo_oci/oci_statement.c @@ -197,10 +197,7 @@ static sb4 oci_bind_input_cb(dvoid *ctx, OCIBind *bindp, ub4 iter, ub4 index, dv pdo_oci_bound_param *P = (pdo_oci_bound_param*)param->driver_data; zval *parameter; - if (!param) { - php_error_docref(NULL, E_WARNING, "param is NULL in oci_bind_input_cb; this should not happen"); - return OCI_ERROR; - } + ZEND_ASSERT(param); *indpp = &P->indicator; @@ -236,10 +233,7 @@ static sb4 oci_bind_output_cb(dvoid *ctx, OCIBind *bindp, ub4 iter, ub4 index, d pdo_oci_bound_param *P = (pdo_oci_bound_param*)param->driver_data; zval *parameter; - if (!param) { - php_error_docref(NULL, E_WARNING, "param is NULL in oci_bind_output_cb; this should not happen"); - return OCI_ERROR; - } + ZEND_ASSERT(param); if (Z_ISREF(param->parameter)) parameter = Z_REFVAL(param->parameter); @@ -509,11 +503,7 @@ static sb4 oci_define_callback(dvoid *octxp, OCIDefine *define, ub4 iter, dvoid *alenpp = &col->datalen; *indpp = (dvoid *)&col->indicator; break; - - default: - php_error_docref(NULL, E_WARNING, - "unhandled datatype in oci_define_callback; this should not happen"); - return OCI_ERROR; + EMPTY_SWITCH_DEFAULT_CASE(); } return OCI_CONTINUE; diff --git a/ext/pdo_pgsql/pgsql_driver.c b/ext/pdo_pgsql/pgsql_driver.c index 38ea304a30e9b..2666ae66e146f 100644 --- a/ext/pdo_pgsql/pgsql_driver.c +++ b/ext/pdo_pgsql/pgsql_driver.c @@ -566,8 +566,8 @@ PHP_METHOD(PDO_PGSql_Ext, pgsqlCopyFromArray) } if (!zend_hash_num_elements(Z_ARRVAL_P(pg_rows))) { - php_error_docref(NULL, E_WARNING, "Cannot copy from an empty array"); - RETURN_FALSE; + zend_argument_value_error(2, "cannot be empty"); + RETURN_THROWS(); } dbh = Z_PDO_DBH_P(ZEND_THIS); @@ -1061,13 +1061,13 @@ PHP_METHOD(PDO_PGSql_Ext, pgsqlGetNotify) } if (result_type != PDO_FETCH_BOTH && result_type != PDO_FETCH_ASSOC && result_type != PDO_FETCH_NUM) { - php_error_docref(NULL, E_WARNING, "Invalid result type"); - RETURN_FALSE; + zend_argument_value_error(1, "must be one of PDO::FETCH_BOTH, PDO::FETCH_ASSOC, or PDO::FETCH_NUM"); + RETURN_THROWS(); } if (ms_timeout < 0) { - php_error_docref(NULL, E_WARNING, "Invalid timeout"); - RETURN_FALSE; + zend_argument_value_error(2, "must be greater than or equal to 0"); + RETURN_THROWS(); #ifdef ZEND_ENABLE_ZVAL_LONG64 } else if (ms_timeout > INT_MAX) { php_error_docref(NULL, E_WARNING, "Timeout was shrunk to %d", INT_MAX); diff --git a/ext/pgsql/pgsql.c b/ext/pgsql/pgsql.c index c5ee4ffebc66d..314f28404a615 100644 --- a/ext/pgsql/pgsql.c +++ b/ext/pgsql/pgsql.c @@ -1468,8 +1468,8 @@ PHP_FUNCTION(pg_last_notice) RETURN_TRUE; break; default: - php_error_docref(NULL, E_WARNING, - "Invalid option specified (" ZEND_LONG_FMT ")", option); + zend_argument_value_error(2, "must be one of PGSQL_NOTICE_LAST, PGSQL_NOTICE_ALL, or PGSQL_NOTICE_CLEAR"); + RETURN_THROWS(); } RETURN_FALSE; } @@ -1555,7 +1555,12 @@ PHP_FUNCTION(pg_field_table) RETURN_THROWS(); } - if (fnum < 0 || fnum >= PQnfields(pg_result->result)) { + if (fnum < 0) { + zend_argument_value_error(2, "must be greater than or equal to 0"); + RETURN_THROWS(); + } + + if (fnum >= PQnfields(pg_result->result)) { php_error_docref(NULL, E_WARNING, "Bad field offset specified"); RETURN_FALSE; } @@ -1638,10 +1643,14 @@ static void php_pgsql_get_field_info(INTERNAL_FUNCTION_PARAMETERS, int entry_typ RETURN_THROWS(); } + if (field < 0) { + zend_argument_value_error(2, "must be greater than or equal to 0"); + RETURN_THROWS(); + } pgsql_result = pg_result->result; - if (field < 0 || field >= PQnfields(pgsql_result)) { + if (field >= PQnfields(pgsql_result)) { php_error_docref(NULL, E_WARNING, "Bad field offset specified"); RETURN_FALSE; } @@ -1758,7 +1767,11 @@ PHP_FUNCTION(pg_fetch_result) } pg_result->row++; } else { - if (row < 0 || row >= PQntuples(pgsql_result)) { + if (row < 0) { + zend_argument_value_error(2, "must be greater than or equal to 0"); + RETURN_THROWS(); + } + if (row >= PQntuples(pgsql_result)) { php_error_docref(NULL, E_WARNING, "Unable to jump to row " ZEND_LONG_FMT " on PostgreSQL result index " ZEND_LONG_FMT, row, Z_LVAL_P(result)); RETURN_FALSE; @@ -1772,7 +1785,11 @@ PHP_FUNCTION(pg_fetch_result) RETURN_FALSE; } } else { - if (field_offset < 0 || field_offset >= PQnfields(pgsql_result)) { + if (field_offset < 0) { + zend_argument_value_error(argc, "must be greater than or equal to 0"); + RETURN_THROWS(); + } + if (field_offset >= PQnfields(pgsql_result)) { php_error_docref(NULL, E_WARNING, "Bad column offset specified"); RETURN_FALSE; } @@ -1815,13 +1832,13 @@ static void php_pgsql_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, zend_long result_ } if (!row_is_null && row < 0) { - php_error_docref(NULL, E_WARNING, "The row parameter must be greater or equal to zero"); - RETURN_FALSE; + zend_argument_value_error(2, "must be greater than or equal to 0"); + RETURN_THROWS(); } if (!(result_type & PGSQL_BOTH)) { - php_error_docref(NULL, E_WARNING, "Invalid result type"); - RETURN_FALSE; + zend_argument_value_error(3, "must be one of PGSQL_ASSOC, PGSQL_NUM, or PGSQL_BOTH"); + RETURN_THROWS(); } if ((pg_result = (pgsql_result_handle *)zend_fetch_resource(Z_RES_P(result), "PostgreSQL result", le_result)) == NULL) { @@ -1831,7 +1848,7 @@ static void php_pgsql_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, zend_long result_ pgsql_result = pg_result->result; if (!row_is_null) { - if (row < 0 || row >= PQntuples(pgsql_result)) { + if (row >= PQntuples(pgsql_result)) { php_error_docref(NULL, E_WARNING, "Unable to jump to row " ZEND_LONG_FMT " on PostgreSQL result index " ZEND_LONG_FMT, row, Z_LVAL_P(result)); RETURN_FALSE; @@ -1977,8 +1994,8 @@ PHP_FUNCTION(pg_fetch_all) } if (!(result_type & PGSQL_BOTH)) { - php_error_docref(NULL, E_WARNING, "Invalid result type"); - RETURN_FALSE; + zend_argument_value_error(2, "must be one of PGSQL_ASSOC, PGSQL_NUM, or PGSQL_BOTH"); + RETURN_THROWS(); } if ((pg_result = (pgsql_result_handle *)zend_fetch_resource(Z_RES_P(result), "PostgreSQL result", le_result)) == NULL) { @@ -2012,10 +2029,15 @@ PHP_FUNCTION(pg_fetch_all_columns) RETURN_THROWS(); } + if (colno < 0) { + zend_argument_value_error(2, "must be greater than or equal to 0"); + RETURN_THROWS(); + } + pgsql_result = pg_result->result; num_fields = PQnfields(pgsql_result); - if (colno >= (zend_long)num_fields || colno < 0) { + if (colno >= (zend_long)num_fields) { php_error_docref(NULL, E_WARNING, "Invalid column number '" ZEND_LONG_FMT "'", colno); RETURN_FALSE; } @@ -2101,7 +2123,11 @@ static void php_pgsql_data_info(INTERNAL_FUNCTION_PARAMETERS, int entry_type) RETURN_FALSE; } } else { - if (row < 0 || row >= PQntuples(pgsql_result)) { + if (row < 0) { + zend_argument_value_error(2, "must be greater than or equal to 0"); + RETURN_THROWS(); + } + if (row >= PQntuples(pgsql_result)) { php_error_docref(NULL, E_WARNING, "Unable to jump to row " ZEND_LONG_FMT " on PostgreSQL result index " ZEND_LONG_FMT, row, Z_LVAL_P(result)); RETURN_FALSE; @@ -2116,7 +2142,10 @@ static void php_pgsql_data_info(INTERNAL_FUNCTION_PARAMETERS, int entry_type) RETURN_FALSE; } } else { - if (field_offset < 0 || field_offset >= PQnfields(pgsql_result)) { + if (field_offset < 0) { + zend_argument_value_error(argc, "must be greater than or equal to 0"); + } + if (field_offset >= PQnfields(pgsql_result)) { php_error_docref(NULL, E_WARNING, "Bad column offset specified"); RETURN_FALSE; } @@ -2316,7 +2345,7 @@ PHP_FUNCTION(pg_lo_create) default: php_error_docref(NULL, E_NOTICE, "Invalid OID value passed"); RETURN_FALSE; - } + } if ((pgsql_oid = lo_create(pgsql, wanted_oid)) == InvalidOid) { php_error_docref(NULL, E_WARNING, "Unable to create PostgreSQL large object"); RETURN_FALSE; @@ -2603,13 +2632,13 @@ PHP_FUNCTION(pg_lo_write) } if (argc > 2) { - if (z_len > (zend_long)str_len) { - php_error_docref(NULL, E_WARNING, "Cannot write more than buffer size %zu. Tried to write " ZEND_LONG_FMT, str_len, z_len); - RETURN_FALSE; - } if (z_len < 0) { - php_error_docref(NULL, E_WARNING, "Buffer size must be larger than 0, but " ZEND_LONG_FMT " was specified", z_len); - RETURN_FALSE; + zend_argument_value_error(3, "must be greater than or equal to 0"); + RETURN_THROWS(); + } + if (z_len > (zend_long)str_len) { + zend_argument_value_error(3, "must be less than or equal to the length of argument #2 ($buf)"); + RETURN_THROWS(); } len = z_len; } @@ -2711,15 +2740,15 @@ PHP_FUNCTION(pg_lo_import) default: php_error_docref(NULL, E_NOTICE, "Invalid OID value passed"); RETURN_FALSE; - } + } - returned_oid = lo_import_with_oid(pgsql, file_in, wanted_oid); + returned_oid = lo_import_with_oid(pgsql, file_in, wanted_oid); - if (returned_oid == InvalidOid) { - RETURN_FALSE; - } + if (returned_oid == InvalidOid) { + RETURN_FALSE; + } - PGSQL_RETURN_OID(returned_oid); + PGSQL_RETURN_OID(returned_oid); } returned_oid = lo_import(pgsql, file_in); @@ -2817,8 +2846,8 @@ PHP_FUNCTION(pg_lo_seek) RETURN_THROWS(); } if (whence != SEEK_SET && whence != SEEK_CUR && whence != SEEK_END) { - php_error_docref(NULL, E_WARNING, "Invalid whence parameter"); - return; + zend_argument_value_error(3, "must be one of PGSQL_SEEK_SET, PGSQL_SEEK_CUR, or PGSQL_SEEK_END"); + RETURN_THROWS(); } if ((pgsql = (pgLofp *)zend_fetch_resource(Z_RES_P(pgsql_id), "PostgreSQL large object", le_lofp)) == NULL) { @@ -4020,10 +4049,9 @@ PHP_FUNCTION(pg_result_status) } else if (result_type == PGSQL_STATUS_STRING) { RETURN_STRING(PQcmdStatus(pgsql_result)); - } - else { - php_error_docref(NULL, E_WARNING, "Optional 2nd parameter should be PGSQL_STATUS_LONG or PGSQL_STATUS_STRING"); - RETURN_FALSE; + } else { + zend_argument_value_error(2, "must be either PGSQL_STATUS_LONG or PGSQL_STATUS_STRING"); + RETURN_THROWS(); } } /* }}} */ @@ -4045,8 +4073,8 @@ PHP_FUNCTION(pg_get_notify) } if (!(result_type & PGSQL_BOTH)) { - php_error_docref(NULL, E_WARNING, "Invalid result type"); - RETURN_FALSE; + zend_argument_value_error(2, "must be one of PGSQL_ASSOC, PGSQL_NUM, or PGSQL_BOTH"); + RETURN_THROWS(); } PQconsumeInput(pgsql); @@ -4233,6 +4261,7 @@ PHP_FUNCTION(pg_flush) /* }}} */ /* {{{ php_pgsql_meta_data + * table_name must not be empty * TODO: Add meta_data cache for better performance */ PHP_PGSQL_API int php_pgsql_meta_data(PGconn *pg_link, const char *table_name, zval *meta, zend_bool extended) @@ -4245,10 +4274,7 @@ PHP_PGSQL_API int php_pgsql_meta_data(PGconn *pg_link, const char *table_name, z int i, num_rows; zval elem; - if (!*table_name) { - php_error_docref(NULL, E_WARNING, "The table name must be specified"); - return FAILURE; - } + ZEND_ASSERT(*table_name); src = estrdup(table_name); tmp_name = php_strtok_r(src, ".", &tmp_name2); @@ -4364,6 +4390,12 @@ PHP_FUNCTION(pg_meta_data) RETURN_THROWS(); } + /* php_pgsql_meta_data() asserts that table_name is not empty */ + if (table_name_len == 0) { + zend_argument_value_error(2, "cannot be empty"); + RETURN_THROWS(); + } + array_init(return_value); if (php_pgsql_meta_data(pgsql, table_name, return_value, extended) == FAILURE) { zend_array_destroy(Z_ARR_P(return_value)); /* destroy array */ @@ -4467,7 +4499,7 @@ static php_pgsql_data_type php_pgsql_get_data_type(const char *type_name, size_t static int php_pgsql_convert_match(const char *str, size_t str_len, const char *regex , size_t regex_len, int icase) { pcre2_code *re; - PCRE2_SIZE err_offset; + PCRE2_SIZE err_offset; int res, errnumber; uint32_t options = PCRE2_NO_AUTO_CAPTURE; size_t i; @@ -4564,14 +4596,13 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con int err = 0, skip_field; php_pgsql_data_type data_type; - assert(pg_link != NULL); - assert(Z_TYPE_P(values) == IS_ARRAY); - assert(Z_TYPE_P(result) == IS_ARRAY); - assert(!(opt & ~PGSQL_CONV_OPTS)); - - if (!table_name) { - return FAILURE; - } + ZEND_ASSERT(pg_link != NULL); + ZEND_ASSERT(Z_TYPE_P(values) == IS_ARRAY); + ZEND_ASSERT(Z_TYPE_P(result) == IS_ARRAY); + ZEND_ASSERT(!(opt & ~PGSQL_CONV_OPTS)); + ZEND_ASSERT(table_name); + /* Table name cannot be empty for php_pgsql_meta_data() */ + ZEND_ASSERT(*table_name); array_init(&meta); /* table_name is escaped by php_pgsql_meta_data */ @@ -5222,13 +5253,16 @@ PHP_FUNCTION(pg_convert) "rsa|l", &pgsql_link, &table_name, &table_name_len, &values, &option) == FAILURE) { RETURN_THROWS(); } - if (option & ~PGSQL_CONV_OPTS) { - php_error_docref(NULL, E_WARNING, "Invalid option is specified"); - RETURN_FALSE; + + if (table_name_len == 0) { + zend_argument_value_error(2, "cannot be empty"); + RETURN_THROWS(); } - if (!table_name_len) { - php_error_docref(NULL, E_NOTICE, "Table name is invalid"); - RETURN_FALSE; + + if (option & ~PGSQL_CONV_OPTS) { + zend_argument_value_error(4, "must be a valid bit mask of PGSQL_CONV_IGNORE_DEFAULT, " + "PGSQL_CONV_FORCE_NULL, and PGSQL_CONV_IGNORE_NOT_NULL"); + RETURN_THROWS(); } if ((pg_link = (PGconn *)zend_fetch_resource2(Z_RES_P(pgsql_link), "PostgreSQL link", le_link, le_plink)) == NULL) { @@ -5433,9 +5467,16 @@ PHP_FUNCTION(pg_insert) &pgsql_link, &table, &table_len, &values, &option) == FAILURE) { RETURN_THROWS(); } + + if (table_len == 0) { + zend_argument_value_error(2, "cannot be empty"); + RETURN_THROWS(); + } + if (option & ~(PGSQL_CONV_OPTS|PGSQL_DML_NO_CONV|PGSQL_DML_EXEC|PGSQL_DML_ASYNC|PGSQL_DML_STRING|PGSQL_DML_ESCAPE)) { - php_error_docref(NULL, E_WARNING, "Invalid option is specified"); - RETURN_FALSE; + zend_argument_value_error(4, "must be a valid bit mask of PGSQL_CONV_FORCE_NULL, PGSQL_DML_NO_CONV, " + "PGSQL_DML_ESCAPE, PGSQL_DML_EXEC, PGSQL_DML_ASYNC, and PGSQL_DML_STRING"); + RETURN_THROWS(); } if ((pg_link = (PGconn *)zend_fetch_resource2(Z_RES_P(pgsql_link), "PostgreSQL link", le_link, le_plink)) == NULL) { @@ -5643,9 +5684,16 @@ PHP_FUNCTION(pg_update) &pgsql_link, &table, &table_len, &values, &ids, &option) == FAILURE) { RETURN_THROWS(); } + + if (table_len == 0) { + zend_argument_value_error(2, "cannot be empty"); + RETURN_THROWS(); + } + if (option & ~(PGSQL_CONV_OPTS|PGSQL_DML_NO_CONV|PGSQL_DML_EXEC|PGSQL_DML_STRING|PGSQL_DML_ESCAPE)) { - php_error_docref(NULL, E_WARNING, "Invalid option is specified"); - RETURN_FALSE; + zend_argument_value_error(5, "must be a valid bit mask of PGSQL_CONV_FORCE_NULL, PGSQL_DML_NO_CONV, " + "PGSQL_DML_ESCAPE, PGSQL_DML_EXEC, PGSQL_DML_ASYNC, and PGSQL_DML_STRING"); + RETURN_THROWS(); } if ((pg_link = (PGconn *)zend_fetch_resource2(Z_RES_P(pgsql_link), "PostgreSQL link", le_link, le_plink)) == NULL) { @@ -5733,9 +5781,16 @@ PHP_FUNCTION(pg_delete) &pgsql_link, &table, &table_len, &ids, &option) == FAILURE) { RETURN_THROWS(); } + + if (table_len == 0) { + zend_argument_value_error(2, "cannot be empty"); + RETURN_THROWS(); + } + if (option & ~(PGSQL_CONV_FORCE_NULL|PGSQL_DML_NO_CONV|PGSQL_DML_EXEC|PGSQL_DML_STRING|PGSQL_DML_ESCAPE)) { - php_error_docref(NULL, E_WARNING, "Invalid option is specified"); - RETURN_FALSE; + zend_argument_value_error(4, "must be a valid bit mask of PGSQL_CONV_FORCE_NULL, PGSQL_DML_NO_CONV, " + "PGSQL_DML_ESCAPE, PGSQL_DML_EXEC, PGSQL_DML_ASYNC, and PGSQL_DML_STRING"); + RETURN_THROWS(); } if ((pg_link = (PGconn *)zend_fetch_resource2(Z_RES_P(pgsql_link), "PostgreSQL link", le_link, le_plink)) == NULL) { @@ -5865,20 +5920,26 @@ PHP_FUNCTION(pg_select) long result_type = PGSQL_ASSOC; PGconn *pg_link; zend_string *sql = NULL; - int argc = ZEND_NUM_ARGS(); - // TODO: result_type is unused by zpp! - if (zend_parse_parameters(argc, "rsa|l", + /* TODO Document result_type param on php.net (apparently it was added in PHP 7.1) */ + if (zend_parse_parameters(ZEND_NUM_ARGS(), "rsa|ll", &pgsql_link, &table, &table_len, &ids, &option, &result_type) == FAILURE) { RETURN_THROWS(); } + + if (table_len == 0) { + zend_argument_value_error(2, "cannot be empty"); + RETURN_THROWS(); + } + if (option & ~(PGSQL_CONV_FORCE_NULL|PGSQL_DML_NO_CONV|PGSQL_DML_EXEC|PGSQL_DML_ASYNC|PGSQL_DML_STRING|PGSQL_DML_ESCAPE)) { - php_error_docref(NULL, E_WARNING, "Invalid option is specified"); - RETURN_FALSE; + zend_argument_value_error(4, "must be a valid bit mask of PGSQL_CONV_FORCE_NULL, PGSQL_DML_NO_CONV, " + "PGSQL_DML_ESCAPE, PGSQL_DML_EXEC, PGSQL_DML_ASYNC, and PGSQL_DML_STRING"); + RETURN_THROWS(); } if (!(result_type & PGSQL_BOTH)) { - php_error_docref(NULL, E_WARNING, "Invalid result type"); - RETURN_FALSE; + zend_argument_value_error(5, "must be one of PGSQL_ASSOC, PGSQL_NUM, or PGSQL_BOTH"); + RETURN_THROWS(); } if ((pg_link = (PGconn *)zend_fetch_resource2(Z_RES_P(pgsql_link), "PostgreSQL link", le_link, le_plink)) == NULL) { diff --git a/ext/pgsql/pgsql.stub.php b/ext/pgsql/pgsql.stub.php index 5537b8ff6f83b..3d8ce3a701468 100644 --- a/ext/pgsql/pgsql.stub.php +++ b/ext/pgsql/pgsql.stub.php @@ -449,7 +449,7 @@ function pg_send_execute($connection, string $query, array $params): int|bool {} function pg_get_result($connection) {} /** @param resource $result */ -function pg_result_status($result, int $result_type = PGSQL_STATUS_LONG): string|int|false {} +function pg_result_status($result, int $result_type = PGSQL_STATUS_LONG): string|int {} /** @param resource $result */ function pg_get_notify($result, int $result_type = PGSQL_ASSOC): array|false {} @@ -488,4 +488,4 @@ function pg_update($connection, string $table_name, array $values, array $ids, i function pg_delete($connection, string $table_name, array $ids, int $options = 0): string|bool {} /** @param resource $connection */ -function pg_select($connection, string $table_name, array $ids, int $options = 0): array|string|false {} +function pg_select($connection, string $table_name, array $ids, int $options = 0, int $result_type = PGSQL_ASSOC): array|string|false {} diff --git a/ext/pgsql/pgsql_arginfo.h b/ext/pgsql/pgsql_arginfo.h index cfbdc18c2b43b..0c9234acdc5c5 100644 --- a/ext/pgsql/pgsql_arginfo.h +++ b/ext/pgsql/pgsql_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 38d1c57d8bf23dcd17d4f775cdf4c2df61087331 */ + * Stub hash: 90dd576049fe13617343fe689000b94b20f47655 */ ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_connect, 0, 0, 1) ZEND_ARG_TYPE_INFO(0, connection_string, IS_STRING, 0) @@ -380,7 +380,7 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_pg_get_result, 0, 0, 1) ZEND_ARG_INFO(0, connection) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pg_result_status, 0, 1, MAY_BE_STRING|MAY_BE_LONG|MAY_BE_FALSE) +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pg_result_status, 0, 1, MAY_BE_STRING|MAY_BE_LONG) ZEND_ARG_INFO(0, result) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, result_type, IS_LONG, 0, "PGSQL_STATUS_LONG") ZEND_END_ARG_INFO() @@ -437,6 +437,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_pg_select, 0, 3, MAY_BE_ARRAY|MA ZEND_ARG_TYPE_INFO(0, table_name, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, ids, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, options, IS_LONG, 0, "0") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, result_type, IS_LONG, 0, "PGSQL_ASSOC") ZEND_END_ARG_INFO() diff --git a/ext/pgsql/tests/09notice.phpt b/ext/pgsql/tests/09notice.phpt index 11c80481f6dda..2b4df446d8f05 100644 --- a/ext/pgsql/tests/09notice.phpt +++ b/ext/pgsql/tests/09notice.phpt @@ -42,7 +42,11 @@ var_dump(pg_last_notice($db, PGSQL_NOTICE_LAST)); var_dump(pg_last_notice($db, PGSQL_NOTICE_ALL)); // Invalid option -var_dump(pg_last_notice($db, 99)); +try { + var_dump(pg_last_notice($db, 99)); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} ?> --EXPECTF-- resource(%d) of type (pgsql result) @@ -68,6 +72,4 @@ bool(true) string(0) "" array(0) { } - -Warning: pg_last_notice(): Invalid option specified (99) in %s%e09notice.php on line %d -bool(false) +pg_last_notice(): Argument #2 ($option) must be one of PGSQL_NOTICE_LAST, PGSQL_NOTICE_ALL, or PGSQL_NOTICE_CLEAR diff --git a/ext/pgsql/tests/bug60244.phpt b/ext/pgsql/tests/bug60244.phpt index 94568b6031305..4d2f4cbcd773b 100644 --- a/ext/pgsql/tests/bug60244.phpt +++ b/ext/pgsql/tests/bug60244.phpt @@ -12,10 +12,26 @@ include 'config.inc'; $db = pg_connect($conn_str); $result = pg_query("select 'a' union select 'b'"); -var_dump(pg_fetch_array($result, -1)); -var_dump(pg_fetch_assoc($result, -1)); -var_dump(pg_fetch_object($result, -1)); -var_dump(pg_fetch_row($result, -1)); +try { + var_dump(pg_fetch_array($result, -1)); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} +try { + var_dump(pg_fetch_assoc($result, -1)); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} +try { + var_dump(pg_fetch_object($result, -1)); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} +try { + var_dump(pg_fetch_row($result, -1)); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} var_dump(pg_fetch_array($result, 0)); var_dump(pg_fetch_assoc($result, 0)); @@ -25,18 +41,11 @@ var_dump(pg_fetch_row($result, 0)); pg_close($db); ?> ---EXPECTF-- -Warning: pg_fetch_array(): The row parameter must be greater or equal to zero in %sbug60244.php on line %d -bool(false) - -Warning: pg_fetch_assoc(): The row parameter must be greater or equal to zero in %sbug60244.php on line %d -bool(false) - -Warning: pg_fetch_object(): The row parameter must be greater or equal to zero in %sbug60244.php on line %d -bool(false) - -Warning: pg_fetch_row(): The row parameter must be greater or equal to zero in %sbug60244.php on line %d -bool(false) +--EXPECT-- +pg_fetch_array(): Argument #2 ($row_number) must be greater than or equal to 0 +pg_fetch_assoc(): Argument #2 ($row_number) must be greater than or equal to 0 +pg_fetch_object(): Argument #2 ($row_number) must be greater than or equal to 0 +pg_fetch_row(): Argument #2 ($row_number) must be greater than or equal to 0 array(2) { [0]=> string(1) "a" diff --git a/ext/pgsql/tests/pg_insert_002.phpt b/ext/pgsql/tests/pg_insert_002.phpt index bb84a00d0dd2c..0aa6395cfa0cf 100644 --- a/ext/pgsql/tests/pg_insert_002.phpt +++ b/ext/pgsql/tests/pg_insert_002.phpt @@ -10,13 +10,16 @@ include('config.inc'); $conn = pg_connect($conn_str); foreach (array('', '.', '..') as $table) { - var_dump(pg_insert($conn, $table, array('id' => 1, 'id2' => 1))); + try { + var_dump(pg_insert($conn, $table, array('id' => 1, 'id2' => 1))); + } catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; + } } ?> Done --EXPECTF-- -Warning: pg_insert(): The table name must be specified in %s on line %d -bool(false) +pg_insert(): Argument #2 ($table_name) cannot be empty Warning: pg_insert(): The table name must be specified in %s on line %d bool(false) diff --git a/ext/pgsql/tests/pg_select_001.phpt b/ext/pgsql/tests/pg_select_001.phpt index 9bcf130dd8389..803cf1fbbfc5e 100644 --- a/ext/pgsql/tests/pg_select_001.phpt +++ b/ext/pgsql/tests/pg_select_001.phpt @@ -31,6 +31,8 @@ var_dump(pg_select($conn, 'phptests.bar', array('id' => 1))); /* Existent column */ var_dump(pg_select($conn, 'phptests.bar', array('id4' => 4))); +/* Use a different result type */ +var_dump(pg_select($conn, 'phptests.bar', array('id4' => 4), 0, PGSQL_NUM)); pg_query('DROP TABLE phptests.foo'); pg_query('DROP TABLE phptests.bar'); @@ -61,3 +63,12 @@ array(1) { string(1) "5" } } +array(1) { + [0]=> + array(2) { + [0]=> + string(1) "4" + [1]=> + string(1) "5" + } +} diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index 403c91c3e4506..292e1901e4da9 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -6084,20 +6084,20 @@ static zend_bool is_ignorable_reference(HashTable *ht, zval *ref) { ZEND_METHOD(ReflectionReference, fromArrayElement) { HashTable *ht; - zval *key, *item; + zval *item; + zend_string *string_key = NULL; + zend_long int_key = 0; reflection_object *intern; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "hz", &ht, &key) == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_START(2, 2) + Z_PARAM_ARRAY_HT(ht) + Z_PARAM_STR_OR_LONG(string_key, int_key) + ZEND_PARSE_PARAMETERS_END(); - if (Z_TYPE_P(key) == IS_LONG) { - item = zend_hash_index_find(ht, Z_LVAL_P(key)); - } else if (Z_TYPE_P(key) == IS_STRING) { - item = zend_symtable_find(ht, Z_STR_P(key)); + if (string_key) { + item = zend_hash_find(ht, string_key); } else { - zend_argument_type_error(2, "must be of type string|int, %s given", zend_zval_type_name(key)); - RETURN_THROWS(); + item = zend_hash_index_find(ht, int_key); } if (!item) { diff --git a/ext/reflection/php_reflection.stub.php b/ext/reflection/php_reflection.stub.php index d1ba2cf6249ec..1f4bbb5e8608d 100644 --- a/ext/reflection/php_reflection.stub.php +++ b/ext/reflection/php_reflection.stub.php @@ -643,8 +643,7 @@ public function getCopyright() {} final class ReflectionReference { - /** @param int|string $key */ - public static function fromArrayElement(array $array, $key): ?ReflectionReference {} + public static function fromArrayElement(array $array, int|string $key): ?ReflectionReference {} public function getId(): string {} diff --git a/ext/reflection/php_reflection_arginfo.h b/ext/reflection/php_reflection_arginfo.h index aab74783c8012..d28770ccaa3ca 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: d698afd338e4bf7c782f0edddfcbe95859eef477 */ + * Stub hash: c2bd96bf9b5ca866860f8f3c04937c9fff5c3afa */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Reflection_getModifierNames, 0, 0, 1) ZEND_ARG_TYPE_INFO(0, modifiers, IS_LONG, 0) @@ -467,7 +467,7 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_ReflectionReference_fromArrayElement, 0, 2, ReflectionReference, 1) ZEND_ARG_TYPE_INFO(0, array, IS_ARRAY, 0) - ZEND_ARG_INFO(0, key) + ZEND_ARG_TYPE_MASK(0, key, MAY_BE_LONG|MAY_BE_STRING, NULL) ZEND_END_ARG_INFO() #define arginfo_class_ReflectionReference_getId arginfo_class_ReflectionFunction___toString diff --git a/ext/reflection/tests/ReflectionParameter_canBePassedByValue.phpt b/ext/reflection/tests/ReflectionParameter_canBePassedByValue.phpt index c7f823e423db0..28214681e820b 100644 --- a/ext/reflection/tests/ReflectionParameter_canBePassedByValue.phpt +++ b/ext/reflection/tests/ReflectionParameter_canBePassedByValue.phpt @@ -51,7 +51,7 @@ Name: array Is passed by reference: yes Can be passed by value: no -Name: sort_flags +Name: flags Is passed by reference: no Can be passed by value: yes diff --git a/ext/reflection/tests/ReflectionReference_errors.phpt b/ext/reflection/tests/ReflectionReference_errors.phpt index 6d7ca3ae3dc2f..c9d75d0467a5a 100644 --- a/ext/reflection/tests/ReflectionReference_errors.phpt +++ b/ext/reflection/tests/ReflectionReference_errors.phpt @@ -16,7 +16,7 @@ try { } try { - ReflectionReference::fromArrayElement([], 1.5); + ReflectionReference::fromArrayElement([], []); } catch (TypeError $e) { echo $e->getMessage(), "\n"; } @@ -42,7 +42,7 @@ var_dump(unserialize('O:19:"ReflectionReference":0:{}')); --EXPECTF-- Call to private ReflectionReference::__construct() from global scope ReflectionReference::fromArrayElement(): Argument #1 ($array) must be of type array, stdClass given -ReflectionReference::fromArrayElement(): Argument #2 ($key) must be of type string|int, float given +ReflectionReference::fromArrayElement(): Argument #2 ($key) must be of type string|int, array given Array key not found Serialization of 'ReflectionReference' is not allowed diff --git a/ext/session/session.c b/ext/session/session.c index 4f12e447baa33..79b82f90f786f 100644 --- a/ext/session/session.c +++ b/ext/session/session.c @@ -1674,7 +1674,8 @@ PHPAPI void session_adapt_url(const char *url, size_t url_len, char **new_url, s Set session cookie parameters */ PHP_FUNCTION(session_set_cookie_params) { - zval *lifetime_or_options = NULL; + HashTable *options_ht; + zend_long lifetime_long; zend_string *lifetime = NULL, *path = NULL, *domain = NULL, *samesite = NULL; zend_bool secure = 0, secure_null = 1; zend_bool httponly = 0, httponly_null = 1; @@ -1687,12 +1688,12 @@ PHP_FUNCTION(session_set_cookie_params) } ZEND_PARSE_PARAMETERS_START(1, 5) - Z_PARAM_ZVAL(lifetime_or_options) + Z_PARAM_ARRAY_HT_OR_LONG(options_ht, lifetime_long) Z_PARAM_OPTIONAL - Z_PARAM_STR(path) - Z_PARAM_STR(domain) - Z_PARAM_BOOL_EX(secure, secure_null, 1, 0) - Z_PARAM_BOOL_EX(httponly, httponly_null, 1, 0) + Z_PARAM_STR_OR_NULL(path) + Z_PARAM_STR_OR_NULL(domain) + Z_PARAM_BOOL_OR_NULL(secure, secure_null) + Z_PARAM_BOOL_OR_NULL(httponly, httponly_null) ZEND_PARSE_PARAMETERS_END(); if (PS(session_status) == php_session_active) { @@ -1705,20 +1706,31 @@ PHP_FUNCTION(session_set_cookie_params) RETURN_FALSE; } - if (Z_TYPE_P(lifetime_or_options) == IS_ARRAY) { + if (options_ht) { zend_string *key; zval *value; if (path) { - path = NULL; - domain = NULL; - secure_null = 1; - httponly_null = 1; - php_error_docref(NULL, E_WARNING, "Cannot pass arguments after the options array"); - RETURN_FALSE; + zend_argument_value_error(2, "must be null when argument #1 ($lifetime_or_options) is an array"); + RETURN_THROWS(); + } + + if (domain) { + zend_argument_value_error(3, "must be null when argument #1 ($lifetime_or_options) is an array"); + RETURN_THROWS(); + } + + if (!secure_null) { + zend_argument_value_error(4, "must be null when argument #1 ($lifetime_or_options) is an array"); + RETURN_THROWS(); + } + + if (!httponly_null) { + zend_argument_value_error(5, "must be null when argument #1 ($lifetime_or_options) is an array"); + RETURN_THROWS(); } - ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(lifetime_or_options), key, value) { + ZEND_HASH_FOREACH_STR_KEY_VAL(options_ht, key, value) { if (key) { ZVAL_DEREF(value); if(!strcasecmp("lifetime", ZSTR_VAL(key))) { @@ -1754,7 +1766,7 @@ PHP_FUNCTION(session_set_cookie_params) RETURN_THROWS(); } } else { - lifetime = zval_get_string(lifetime_or_options); + lifetime = zend_long_to_str(lifetime_long); } /* Exception during string conversion */ diff --git a/ext/session/session.stub.php b/ext/session/session.stub.php index b8f9f33eba628..36a0b983b9f1c 100644 --- a/ext/session/session.stub.php +++ b/ext/session/session.stub.php @@ -49,8 +49,7 @@ function session_cache_limiter(?string $cache_limiter = null): string|false {} function session_cache_expire(?int $new_cache_expire = null): int|false {} -/** @param int|array $lifetime_or_options */ -function session_set_cookie_params($lifetime_or_options, string $path = UNKNOWN, string $domain = "", ?bool $secure = null, ?bool $httponly = null): bool {} +function session_set_cookie_params(array|int $lifetime_or_options, ?string $path = null, ?string $domain = null, ?bool $secure = null, ?bool $httponly = null): bool {} function session_start(array $options = []): bool {} diff --git a/ext/session/session_arginfo.h b/ext/session/session_arginfo.h index c47dee63154fe..f29a0df86b8e2 100644 --- a/ext/session/session_arginfo.h +++ b/ext/session/session_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 22b829d3cdd092c393c924f323cd19bea1517579 */ + * Stub hash: 9bdf602c14822b13553a5214a415e312c21cd30c */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_session_name, 0, 0, MAY_BE_STRING|MAY_BE_FALSE) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, name, IS_STRING, 1, "null") @@ -78,9 +78,9 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_session_cache_expire, 0, 0, MAY_ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_session_set_cookie_params, 0, 1, _IS_BOOL, 0) - ZEND_ARG_INFO(0, lifetime_or_options) - ZEND_ARG_TYPE_INFO(0, path, IS_STRING, 0) - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, domain, IS_STRING, 0, "\"\"") + ZEND_ARG_TYPE_MASK(0, lifetime_or_options, MAY_BE_ARRAY|MAY_BE_LONG, NULL) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, path, IS_STRING, 1, "null") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, domain, IS_STRING, 1, "null") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, secure, _IS_BOOL, 1, "null") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, httponly, _IS_BOOL, 1, "null") ZEND_END_ARG_INFO() diff --git a/ext/session/tests/session_set_cookie_params_variation7.phpt b/ext/session/tests/session_set_cookie_params_variation7.phpt index 25feabf1fd29c..cdc56554e38ad 100644 --- a/ext/session/tests/session_set_cookie_params_variation7.phpt +++ b/ext/session/tests/session_set_cookie_params_variation7.phpt @@ -40,7 +40,13 @@ var_dump(session_set_cookie_params(["lifetime" => 42])); var_dump(ini_get("session.cookie_lifetime")); var_dump(ini_get("session.cookie_path")); -var_dump(session_set_cookie_params(["path" => "newpath/"], "arg after options array")); + +try { + session_set_cookie_params(["path" => "newpath/"], "arg after options array"); +} catch (ValueError $exception) { + echo $exception->getMessage() . "\n"; +} + var_dump(ini_get("session.cookie_path")); echo "Done"; @@ -63,8 +69,6 @@ string(1) "0" bool(true) string(2) "42" string(1) "/" - -Warning: session_set_cookie_params(): Cannot pass arguments after the options array in %s on line %d -bool(false) +session_set_cookie_params(): Argument #2 ($path) must be null when argument #1 ($lifetime_or_options) is an array string(1) "/" Done diff --git a/ext/snmp/snmp.c b/ext/snmp/snmp.c index b0ad6cf47e854..5eb8d0b33870d 100644 --- a/ext/snmp/snmp.c +++ b/ext/snmp/snmp.c @@ -659,7 +659,6 @@ 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, zend_string *type_str, HashTable *type_ht, zend_string *value_str, HashTable *value_ht @@ -674,25 +673,33 @@ static int php_snmp_parse_oid( objid_query->vars = (snmpobjarg *)emalloc(sizeof(snmpobjarg)); objid_query->vars[objid_query->count].oid = ZSTR_VAL(oid_str); if (st & SNMP_CMD_SET) { - 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 = ZSTR_VAL(type_str); - objid_query->vars[objid_query->count].type = *pptr; - 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"); + if (type_ht) { + zend_type_error("Type must be of type string when object ID is a string"); + efree(objid_query->vars); + return FALSE; + } + if (value_ht) { + zend_type_error("Value must be of type string when object ID is a string"); efree(objid_query->vars); return FALSE; } + + /* Both type and value must be valid strings */ + ZEND_ASSERT(type_str && value_str); + + if (ZSTR_LEN(type_str) != 1) { + zend_value_error("Type must be a single character"); + efree(objid_query->vars); + return FALSE; + } + pptr = ZSTR_VAL(type_str); + objid_query->vars[objid_query->count].type = *pptr; + objid_query->vars[objid_query->count].value = ZSTR_VAL(value_str); } objid_query->count++; } else if (oid_ht) { /* we got objid array */ if (zend_hash_num_elements(oid_ht) == 0) { - php_error_docref(NULL, E_WARNING, "Got empty OID array"); + zend_value_error("Array of object IDs cannot be empty"); return FALSE; } objid_query->vars = (snmpobjarg *)safe_emalloc(sizeof(snmpobjarg), zend_hash_num_elements(oid_ht), 0); @@ -715,7 +722,7 @@ static int php_snmp_parse_oid( 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)); + zend_value_error("Type must be a single character"); efree(objid_query->vars); return FALSE; } @@ -916,6 +923,7 @@ static int netsnmp_session_set_sec_level(struct snmp_session *s, char *level) } else if (!strcasecmp(level, "authPriv") || !strcasecmp(level, "ap")) { s->securityLevel = SNMP_SEC_LEVEL_AUTHPRIV; } else { + zend_value_error("Security level must be one of \"noAuthNoPriv\", \"authNoPriv\", or \"authPriv\""); return (-1); } return (0); @@ -933,7 +941,7 @@ static int netsnmp_session_set_auth_protocol(struct snmp_session *s, char *prot) s->securityAuthProto = usmHMACSHA1AuthProtocol; s->securityAuthProtoLen = USM_AUTH_PROTO_SHA_LEN; } else { - php_error_docref(NULL, E_WARNING, "Unknown authentication protocol '%s'", prot); + zend_value_error("Authentication protocol must be either MD5 or SHA"); return (-1); } return (0); @@ -953,7 +961,11 @@ static int netsnmp_session_set_sec_protocol(struct snmp_session *s, char *prot) s->securityPrivProtoLen = USM_PRIV_PROTO_AES_LEN; #endif } else { - php_error_docref(NULL, E_WARNING, "Unknown security protocol '%s'", prot); +#ifdef HAVE_AES + zend_value_error("Security protocol must be one of DES, AES128, or AES"); +#else + zend_value_error("Security protocol must be DES"); +#endif return (-1); } return (0); @@ -987,7 +999,7 @@ static int netsnmp_session_gen_sec_key(struct snmp_session *s, char *pass) (u_char *)pass, strlen(pass), s->securityPrivKey, &(s->securityPrivKeyLen)))) { php_error_docref(NULL, E_WARNING, "Error generating a key for privacy pass phrase '%s': %s", pass, snmp_api_errstring(snmp_errno)); - return (-2); + return (-1); } return (0); } @@ -1001,6 +1013,7 @@ static int netsnmp_session_set_contextEngineID(struct snmp_session *s, char * co u_char *ebuf = (u_char *) emalloc(ebuf_len); if (!snmp_hex_to_binary(&ebuf, &ebuf_len, &eout_len, 1, contextEngineID)) { + // TODO Promote to Error? php_error_docref(NULL, E_WARNING, "Bad engine ID value '%s'", contextEngineID); efree(ebuf); return (-1); @@ -1023,7 +1036,7 @@ static int netsnmp_session_set_security(struct snmp_session *session, char *sec_ /* Setting the security level. */ if (netsnmp_session_set_sec_level(session, sec_level)) { - php_error_docref(NULL, E_WARNING, "Invalid security level '%s'", sec_level); + /* ValueError already generated, just bail out */ return (-1); } @@ -1031,7 +1044,7 @@ static int netsnmp_session_set_security(struct snmp_session *session, char *sec_ /* Setting the authentication protocol. */ if (netsnmp_session_set_auth_protocol(session, auth_protocol)) { - /* Warning message sent already, just bail out */ + /* ValueError already generated, just bail out */ return (-1); } @@ -1044,7 +1057,7 @@ static int netsnmp_session_set_security(struct snmp_session *session, char *sec_ if (session->securityLevel == SNMP_SEC_LEVEL_AUTHPRIV) { /* Setting the security protocol. */ if (netsnmp_session_set_sec_protocol(session, priv_protocol)) { - /* Warning message sent already, just bail out */ + /* ValueError already generated, just bail out */ return (-1); } @@ -1220,9 +1233,9 @@ static void php_snmp(INTERNAL_FUNCTION_PARAMETERS, int st, int version) snmp_object = Z_SNMP_P(object); session = snmp_object->session; if (!session) { - php_error_docref(NULL, E_WARNING, "Invalid or uninitialized SNMP object"); + zend_throw_error(NULL, "Invalid or uninitialized SNMP object"); efree(objid_query.vars); - RETURN_FALSE; + RETURN_THROWS(); } if (snmp_object->max_oids > 0) { @@ -1351,11 +1364,9 @@ PHP_FUNCTION(snmp_set_oid_output_format) case NETSNMP_OID_OUTPUT_NONE: netsnmp_ds_set_int(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_OID_OUTPUT_FORMAT, a1); RETURN_TRUE; - break; default: - php_error_docref(NULL, E_WARNING, "Unknown SNMP output print format '%d'", (int) a1); - RETURN_FALSE; - break; + zend_argument_value_error(1, "must be an SNMP_OID_OUTPUT_* constant"); + RETURN_THROWS(); } } /* }}} */ @@ -1443,8 +1454,8 @@ PHP_FUNCTION(snmp_set_valueretrieval) SNMP_G(valueretrieval) = method; RETURN_TRUE; } else { - php_error_docref(NULL, E_WARNING, "Unknown SNMP value retrieval method '" ZEND_LONG_FMT "'", method); - RETURN_FALSE; + zend_argument_value_error(1, "must be a bitmask of SNMP_VALUE_LIBRARY, SNMP_VALUE_PLAIN, and SNMP_VALUE_OBJECT"); + RETURN_THROWS(); } } /* }}} */ @@ -1827,7 +1838,7 @@ PHP_SNMP_LONG_PROPERTY_READER_FUNCTION(exceptions_enabled) /* {{{ */ static int php_snmp_write_info(php_snmp_object *snmp_object, zval *newval) { - php_error_docref(NULL, E_WARNING, "info property is read-only"); + zend_throw_error(NULL, "SNMP::$info property is read-only"); return FAILURE; } /* }}} */ @@ -1835,40 +1846,38 @@ static int php_snmp_write_info(php_snmp_object *snmp_object, zval *newval) /* {{{ */ static int php_snmp_write_max_oids(php_snmp_object *snmp_object, zval *newval) { - int ret = SUCCESS; zend_long lval; if (Z_TYPE_P(newval) == IS_NULL) { snmp_object->max_oids = 0; - return ret; + return SUCCESS; } lval = zval_get_long(newval); - if (lval > 0) { - snmp_object->max_oids = lval; - } else { - php_error_docref(NULL, E_WARNING, "max_oids should be positive integer or NULL, got " ZEND_LONG_FMT, lval); + if (lval <= 0) { + zend_value_error("max_oids must be greater than 0 or null"); + return FAILURE; } + snmp_object->max_oids = lval; - return ret; + return SUCCESS; } /* }}} */ /* {{{ */ static int php_snmp_write_valueretrieval(php_snmp_object *snmp_object, zval *newval) { - int ret = SUCCESS; zend_long lval = zval_get_long(newval); if (lval >= 0 && lval <= (SNMP_VALUE_LIBRARY|SNMP_VALUE_PLAIN|SNMP_VALUE_OBJECT)) { snmp_object->valueretrieval = lval; } else { - php_error_docref(NULL, E_WARNING, "Unknown SNMP value retrieval method '" ZEND_LONG_FMT "'", lval); - ret = FAILURE; + zend_value_error("SNMP retrieval method must be a bitmask of SNMP_VALUE_LIBRARY, SNMP_VALUE_PLAIN, and SNMP_VALUE_OBJECT"); + return FAILURE; } - return ret; + return SUCCESS; } /* }}} */ @@ -1892,7 +1901,6 @@ PHP_SNMP_BOOL_PROPERTY_WRITER_FUNCTION(oid_increasing_check) /* {{{ */ static int php_snmp_write_oid_output_format(php_snmp_object *snmp_object, zval *newval) { - int ret = SUCCESS; zend_long lval = zval_get_long(newval); switch(lval) { @@ -1903,14 +1911,11 @@ static int php_snmp_write_oid_output_format(php_snmp_object *snmp_object, zval * case NETSNMP_OID_OUTPUT_UCD: case NETSNMP_OID_OUTPUT_NONE: snmp_object->oid_output_format = lval; - break; + return SUCCESS; default: - php_error_docref(NULL, E_WARNING, "Unknown SNMP output print format '" ZEND_LONG_FMT "'", lval); - ret = FAILURE; - break; + zend_value_error("SNMP output print format must be an SNMP_OID_OUTPUT_* constant"); + return FAILURE; } - - return ret; } /* }}} */ diff --git a/ext/snmp/tests/snmp-object-error.phpt b/ext/snmp/tests/snmp-object-error.phpt index a1268e4b4c7c0..b170f9a08323b 100644 --- a/ext/snmp/tests/snmp-object-error.phpt +++ b/ext/snmp/tests/snmp-object-error.phpt @@ -54,18 +54,35 @@ var_dump($session->close()); echo "Open normal session\n"; $session = new SNMP(SNMP::VERSION_3, $hostname, $user_noauth, $timeout, $retries); -$session->valueretrieval = 67; -var_dump($session->valueretrieval); +try { + $session->valueretrieval = 67; + var_dump($session->valueretrieval); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} echo "Closing session\n"; var_dump($session->close()); -var_dump($session->get('.1.3.6.1.2.1.1.1.0')); -var_dump($session->close()); + +try { + var_dump($session->get('.1.3.6.1.2.1.1.1.0')); + var_dump($session->close()); +} catch (\Error $e) { + echo $e->getMessage() . \PHP_EOL; +} $session = new SNMP(SNMP::VERSION_2c, $hostname, $community, $timeout, $retries); var_dump($session->max_oids); -$session->max_oids = "ttt"; -$session->max_oids = 0; +try { + $session->max_oids = "ttt"; +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} +try { + $session->max_oids = 0; +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} var_dump($session->max_oids); ?> --EXPECTF-- @@ -81,18 +98,11 @@ int(32) string(46) "Invalid object identifier: .1.3.6.1.2.1.1.1..0" bool(true) Open normal session - -Warning: main(): Unknown SNMP value retrieval method '67' in %s on line %d -int(%d) +SNMP retrieval method must be a bitmask of SNMP_VALUE_LIBRARY, SNMP_VALUE_PLAIN, and SNMP_VALUE_OBJECT Closing session bool(true) - -Warning: SNMP::get(): Invalid or uninitialized SNMP object in %s on line %d -bool(false) -bool(true) +Invalid or uninitialized SNMP object NULL - -Warning: main(): max_oids should be positive integer or NULL, got 0 in %s on line %d - -Warning: main(): max_oids should be positive integer or NULL, got 0 in %s on line %d +max_oids must be greater than 0 or null +max_oids must be greater than 0 or null NULL diff --git a/ext/snmp/tests/snmp-object-properties.phpt b/ext/snmp/tests/snmp-object-properties.phpt index aa1bbdec2f1ed..47c6dc663870c 100644 --- a/ext/snmp/tests/snmp-object-properties.phpt +++ b/ext/snmp/tests/snmp-object-properties.phpt @@ -54,13 +54,24 @@ $param = 'there is no such parameter'; var_dump($session->$param); var_dump(property_exists($session, $param)); -$session->valueretrieval = 67; -var_dump($session->valueretrieval); -$session->oid_output_format = 78; -var_dump($session->oid_output_format); - -$session->info = array("blah" => 2); -var_dump($session->info); +try { + $session->valueretrieval = 67; + var_dump($session->valueretrieval); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} +try { + $session->oid_output_format = 78; + var_dump($session->oid_output_format); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} +try { + $session->info = array("blah" => 2); + var_dump($session->info); +} catch (\Error $e) { + echo $e->getMessage() . \PHP_EOL; +} $session->max_oids = NULL; var_dump($session->max_oids); @@ -179,20 +190,7 @@ Error handling Warning: Undefined property: SNMP::$there is no such parameter in %s on line %d NULL bool(false) - -Warning: main(): Unknown SNMP value retrieval method '67' in %s on line %d -int(1) - -Warning: main(): Unknown SNMP output print format '78' in %s on line %d -int(3) - -Warning: main(): info property is read-only in %s on line %d -array(3) { - ["hostname"]=> - string(%d) "%s" - ["timeout"]=> - int(%i) - ["retries"]=> - int(%d) -} +SNMP retrieval method must be a bitmask of SNMP_VALUE_LIBRARY, SNMP_VALUE_PLAIN, and SNMP_VALUE_OBJECT +SNMP output print format must be an SNMP_OID_OUTPUT_* constant +SNMP::$info property is read-only NULL diff --git a/ext/snmp/tests/snmp-object-setSecurity_error.phpt b/ext/snmp/tests/snmp-object-setSecurity_error.phpt index 819642d9572d9..b0bf03bd3d5e2 100644 --- a/ext/snmp/tests/snmp-object-setSecurity_error.phpt +++ b/ext/snmp/tests/snmp-object-setSecurity_error.phpt @@ -18,12 +18,37 @@ $session = new SNMP(SNMP::VERSION_3, $hostname, $user_noauth, $timeout, $retries $session->setSecurity('noAuthNoPriv'); #echo "Checking error handling\n"; + +try { var_dump($session->setSecurity('')); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} +try { var_dump($session->setSecurity('bugusPriv')); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} +try { var_dump($session->setSecurity('authNoPriv', 'TTT')); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} + var_dump($session->setSecurity('authNoPriv', 'MD5', '')); var_dump($session->setSecurity('authNoPriv', 'MD5', 'te')); -var_dump($session->setSecurity('authPriv', 'MD5', $auth_pass, 'BBB')); + +try { + var_dump(snmp3_get($hostname, $community, 'authPriv', 'MD5', $auth_pass, 'BBB', '', '.1.3.6.1.2.1.1.1.0')); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} +try { + var_dump($session->setSecurity('authPriv', 'MD5', $auth_pass, 'BBB')); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} + var_dump($session->setSecurity('authPriv', 'MD5', $auth_pass, 'AES', '')); var_dump($session->setSecurity('authPriv', 'MD5', $auth_pass, 'AES', 'ty')); var_dump($session->setSecurity('authPriv', 'MD5', $auth_pass, 'AES', 'test12345', 'context', 'dsa')); @@ -32,23 +57,17 @@ var_dump($session->close()); ?> --EXPECTF-- -Warning: SNMP::setSecurity(): Invalid security level '' in %s on line %d -bool(false) - -Warning: SNMP::setSecurity(): Invalid security level 'bugusPriv' in %s on line %d -bool(false) - -Warning: SNMP::setSecurity(): Unknown authentication protocol 'TTT' in %s on line %d -bool(false) +Security level must be one of "noAuthNoPriv", "authNoPriv", or "authPriv" +Security level must be one of "noAuthNoPriv", "authNoPriv", or "authPriv" +Authentication protocol must be either MD5 or SHA Warning: SNMP::setSecurity(): Error generating a key for authentication pass phrase '': Generic error (The supplied password length is too short.) in %s on line %d bool(false) Warning: SNMP::setSecurity(): Error generating a key for authentication pass phrase 'te': Generic error (The supplied password length is too short.) in %s on line %d bool(false) - -Warning: SNMP::setSecurity(): Unknown security protocol 'BBB' in %s on line %d -bool(false) +Security protocol must be one of DES, AES128, or AES +Security protocol must be one of DES, AES128, or AES Warning: SNMP::setSecurity(): Error generating a key for privacy pass phrase '': Generic error (The supplied password length is too short.) in %s on line %d bool(false) diff --git a/ext/snmp/tests/snmp2_get.phpt b/ext/snmp/tests/snmp2_get.phpt index 05892d1e6b714..92d52d8f0fc2f 100644 --- a/ext/snmp/tests/snmp2_get.phpt +++ b/ext/snmp/tests/snmp2_get.phpt @@ -16,7 +16,11 @@ snmp_set_valueretrieval(SNMP_VALUE_PLAIN); echo "Checking error handling\n"; echo "Empty OID array\n"; -var_dump(snmp2_get($hostname, $community, array(), $timeout, $retries)); +try { + var_dump(snmp2_get($hostname, $community, array(), $timeout, $retries)); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} echo "Checking working\n"; echo "Single OID\n"; @@ -47,9 +51,7 @@ var_dump(snmp2_get($hostname, $community, array('.1.3.6.1.2.1.1.1.0', '.1.3.6.1. --EXPECTF-- Checking error handling Empty OID array - -Warning: snmp2_get(): Got empty OID array in %s on line %d -bool(false) +Array of object IDs cannot be empty Checking working Single OID string(%d) "%s" diff --git a/ext/snmp/tests/snmp2_set.phpt b/ext/snmp/tests/snmp2_set.phpt index 01c66d96f5315..ea0581184e0ad 100644 --- a/ext/snmp/tests/snmp2_set.phpt +++ b/ext/snmp/tests/snmp2_set.phpt @@ -16,8 +16,12 @@ snmp_set_valueretrieval(SNMP_VALUE_PLAIN); echo "Check error handing\n"; echo "No type & no value (timeout & retries instead)\n"; -$z = snmp2_set($hostname, $communityWrite, 'SNMPv2-MIB::sysLocation.0', $timeout, $retries); -var_dump($z); +try { + $z = snmp2_set($hostname, $communityWrite, 'SNMPv2-MIB::sysLocation.0', $timeout, $retries); + var_dump($z); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} echo "No value (timeout instead), retries instead of timeout\n"; $z = snmp2_set($hostname, $communityWrite, 'SNMPv2-MIB::sysLocation.0', 'q', $timeout, $retries); @@ -39,6 +43,7 @@ echo "Single OID\n"; $z = snmp2_set($hostname, $communityWrite, $oid1, 's', $newvalue1, $timeout, $retries); var_dump($z); var_dump((snmpget($hostname, $communityWrite, $oid1, $timeout, $retries) === $newvalue1)); + $z = snmp2_set($hostname, $communityWrite, $oid1, 's', $oldvalue1, $timeout, $retries); var_dump($z); var_dump((snmpget($hostname, $communityWrite, $oid1, $timeout, $retries) === $oldvalue1)); @@ -48,6 +53,10 @@ $z = snmp2_set($hostname, $communityWrite, array($oid1, $oid2), array('s','s'), var_dump($z); var_dump((snmpget($hostname, $communityWrite, $oid1, $timeout, $retries) === $newvalue1)); var_dump((snmpget($hostname, $communityWrite, $oid2, $timeout, $retries) === $newvalue2)); + +$z = snmp2_set($hostname, $communityWrite, '.1.3.6.777.888.999.444.0', 's', 'bbb', $timeout, $retries); +var_dump($z); + $z = snmp2_set($hostname, $communityWrite, array($oid1, $oid2), array('s','s'), array($oldvalue1, $oldvalue2), $timeout, $retries); var_dump($z); var_dump((snmpget($hostname, $communityWrite, $oid1, $timeout, $retries) === $oldvalue1)); @@ -58,44 +67,61 @@ $z = snmp2_set($hostname, $communityWrite, array($oid1, $oid2), 's', $newvalue1, var_dump($z); var_dump((snmpget($hostname, $communityWrite, $oid1, $timeout, $retries) === $newvalue1)); var_dump((snmpget($hostname, $communityWrite, $oid2, $timeout, $retries) === $newvalue1)); + $z = snmp2_set($hostname, $communityWrite, array($oid1, $oid2), array('s','s'), array($oldvalue1, $oldvalue2), $timeout, $retries); var_dump($z); var_dump((snmpget($hostname, $communityWrite, $oid1, $timeout, $retries) === $oldvalue1)); -var_dump((snmpget($hostname, $communityWrite, $oid2, $timeout, $retries) === $oldvalue2)); +var_dump((snmpget($hostname, $communityWrite, $oid2, $timeout, $retries) === $oldvalue2 )); echo "Multiple OID, single type, multiple value\n"; $z = snmp2_set($hostname, $communityWrite, array($oid1, $oid2), 's', array($newvalue1, $newvalue2), $timeout, $retries); var_dump($z); var_dump((snmpget($hostname, $communityWrite, $oid1, $timeout, $retries) === $newvalue1)); var_dump((snmpget($hostname, $communityWrite, $oid2, $timeout, $retries) === $newvalue2)); + $z = snmp2_set($hostname, $communityWrite, array($oid1, $oid2), array('s','s'), array($oldvalue1, $oldvalue2), $timeout, $retries); var_dump($z); var_dump((snmpget($hostname, $communityWrite, $oid1, $timeout, $retries) === $oldvalue1)); var_dump((snmpget($hostname, $communityWrite, $oid2, $timeout, $retries) === $oldvalue2)); - echo "More error handing\n"; echo "Single OID, single type in array, single value\n"; -$z = snmp2_set($hostname, $communityWrite, $oid1, array('s'), $newvalue1, $timeout, $retries); -var_dump($z); +try { + $z = snmp2_set($hostname, $communityWrite, $oid1, array('s'), $newvalue1, $timeout, $retries); + var_dump($z); +} catch (\TypeError $e) { + echo $e->getMessage() . \PHP_EOL; +} var_dump((snmpget($hostname, $communityWrite, $oid1, $timeout, $retries) === $oldvalue1)); var_dump((snmpget($hostname, $communityWrite, $oid2, $timeout, $retries) === $oldvalue2)); echo "Single OID, single type, single value in array\n"; -$z = snmp2_set($hostname, $communityWrite, $oid1, 's', array($newvalue1), $timeout, $retries); -var_dump($z); +try { + $z = snmp2_set($hostname, $communityWrite, $oid1, 's', array($newvalue1), $timeout, $retries); + var_dump($z); +} catch (\TypeError $e) { + echo $e->getMessage() . \PHP_EOL; +} var_dump((snmpget($hostname, $communityWrite, $oid1, $timeout, $retries) === $oldvalue1)); var_dump((snmpget($hostname, $communityWrite, $oid2, $timeout, $retries) === $oldvalue2)); echo "Multiple OID, 1st wrong type\n"; -$z = snmp2_set($hostname, $communityWrite, array($oid1, $oid2), array('sw','s'), array($newvalue1, $newvalue2), $timeout, $retries); -var_dump($z); +try { + $z = snmp2_set($hostname, $communityWrite, array($oid1, $oid2), array('sw','s'), array($newvalue1, $newvalue2), $timeout, $retries); + var_dump($z); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} var_dump((snmpget($hostname, $communityWrite, $oid1, $timeout, $retries) === $oldvalue1)); var_dump((snmpget($hostname, $communityWrite, $oid2, $timeout, $retries) === $oldvalue2)); echo "Multiple OID, 2nd wrong type\n"; -$z = snmp2_set($hostname, $communityWrite, array($oid1, $oid2), array('s','sb'), array($newvalue1, $newvalue2), $timeout, $retries); -var_dump($z); +try { + $z = snmp2_set($hostname, $communityWrite, array($oid1, $oid2), array('s','sb'), array($newvalue1, $newvalue2), $timeout, $retries); + var_dump($z); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} var_dump((snmpget($hostname, $communityWrite, $oid1, $timeout, $retries) === $oldvalue1)); var_dump((snmpget($hostname, $communityWrite, $oid2, $timeout, $retries) === $oldvalue2)); @@ -139,9 +165,7 @@ var_dump((snmpget($hostname, $communityWrite, $oid2, $timeout, $retries) === $ol --EXPECTF-- Check error handing No type & no value (timeout & retries instead) - -Warning: snmp2_set(): Bogus type '-1', should be single char, got 2 in %s on line %d -bool(false) +Type must be a single character No value (timeout instead), retries instead of timeout Warning: snmp2_set(): Could not add variable: OID='%s' type='q' value='%i': Bad variable type ("q") in %s on line %d @@ -160,6 +184,9 @@ Multiple OID bool(true) bool(true) bool(true) + +Warning: snmp2_set(): Error in packet at '%s': notWritable (That object does not support modification) in %s on line %d +bool(false) bool(true) bool(true) bool(true) @@ -179,27 +206,19 @@ bool(true) bool(true) More error handing Single OID, single type in array, single value - -Warning: snmp2_set(): Single objid and multiple type or values are not supported in %s on line %d -bool(false) +Type must be of type string when object ID is a string bool(true) bool(true) Single OID, single type, single value in array - -Warning: snmp2_set(): Single objid and multiple type or values are not supported in %s on line %d -bool(false) +Value must be of type string when object ID is a string bool(true) bool(true) Multiple OID, 1st wrong type - -Warning: snmp2_set(): '%s': bogus type 'sw', should be single char, got 2 in %s on line %d -bool(false) +Type must be a single character bool(true) bool(true) Multiple OID, 2nd wrong type - -Warning: snmp2_set(): '%s': bogus type 'sb', should be single char, got 2 in %s on line %d -bool(false) +Type must be a single character bool(true) bool(true) Multiple OID, single type in array, multiple value diff --git a/ext/snmp/tests/snmp3-error.phpt b/ext/snmp/tests/snmp3-error.phpt index cbebf69f62829..7c07d13fa957f 100644 --- a/ext/snmp/tests/snmp3-error.phpt +++ b/ext/snmp/tests/snmp3-error.phpt @@ -16,40 +16,56 @@ echo "Checking error handling\n"; // string auth_passphrase, string priv_protocol, string priv_passphrase, // string object_id [, int timeout [, int retries]]); -var_dump(snmp3_get($hostname, $community, '', '', '', '', '', '.1.3.6.1.2.1.1.1.0')); -var_dump(snmp3_get($hostname, $community, 'bugusPriv', '', '', '', '', '.1.3.6.1.2.1.1.1.0')); -var_dump(snmp3_get($hostname, $community, 'authNoPriv', 'TTT', '', '', '', '.1.3.6.1.2.1.1.1.0')); +try { + var_dump(snmp3_get($hostname, $community, '', '', '', '', '', '.1.3.6.1.2.1.1.1.0')); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} +try { + var_dump(snmp3_get($hostname, $community, 'bugusPriv', '', '', '', '', '.1.3.6.1.2.1.1.1.0')); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} +try { + var_dump(snmp3_get($hostname, $community, 'authNoPriv', 'TTT', '', '', '', '.1.3.6.1.2.1.1.1.0')); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} + var_dump(snmp3_get($hostname, $community, 'authNoPriv', 'MD5', '', '', '', '.1.3.6.1.2.1.1.1.0')); var_dump(snmp3_get($hostname, $community, 'authNoPriv', 'MD5', 'te', '', '', '.1.3.6.1.2.1.1.1.0')); -var_dump(snmp3_get($hostname, $community, 'authPriv', 'MD5', $auth_pass, 'BBB', '', '.1.3.6.1.2.1.1.1.0')); + +try { + var_dump(snmp3_get($hostname, $community, 'authPriv', 'MD5', $auth_pass, 'BBB', '', '.1.3.6.1.2.1.1.1.0')); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} + var_dump(snmp3_get($hostname, $community, 'authPriv', 'MD5', $auth_pass, 'AES', '', '.1.3.6.1.2.1.1.1.0')); var_dump(snmp3_get($hostname, $community, 'authPriv', 'MD5', $auth_pass, 'AES', 'ty', '.1.3.6.1.2.1.1.1.0')); var_dump(snmp3_get($hostname, 'somebogususer', 'authPriv', 'MD5', $auth_pass, 'AES', $priv_pass, '.1.3.6.1.2.1.1.1.0', $timeout, $retries)); var_dump(snmp3_set($hostname, $rwuser, 'authPriv', 'MD5', $auth_pass, 'AES', $priv_pass, '.1.3.6.777...7.5.3', 's', 'ttt', $timeout, $retries)); -var_dump(snmp3_set($hostname, $rwuser, 'authPriv', 'MD5', $auth_pass, 'AES', $priv_pass, '.1.3.6.777.7.5.3', array('s'), 'yyy', $timeout, $retries)); + +try { + var_dump(snmp3_set($hostname, $rwuser, 'authPriv', 'MD5', $auth_pass, 'AES', $priv_pass, '.1.3.6.777.7.5.3', array('s'), 'yyy', $timeout, $retries)); +} catch (\TypeError $e) { + echo $e->getMessage() . \PHP_EOL; +} ?> --EXPECTF-- Checking error handling - -Warning: snmp3_get(): Invalid security level '' in %s on line %d -bool(false) - -Warning: snmp3_get(): Invalid security level 'bugusPriv' in %s on line %d -bool(false) - -Warning: snmp3_get(): Unknown authentication protocol 'TTT' in %s on line %d -bool(false) +Security level must be one of "noAuthNoPriv", "authNoPriv", or "authPriv" +Security level must be one of "noAuthNoPriv", "authNoPriv", or "authPriv" +Authentication protocol must be either MD5 or SHA Warning: snmp3_get(): Error generating a key for authentication pass phrase '': Generic error (The supplied password length is too short.) in %s on line %d bool(false) Warning: snmp3_get(): Error generating a key for authentication pass phrase 'te': Generic error (The supplied password length is too short.) in %s on line %d bool(false) - -Warning: snmp3_get(): Unknown security protocol 'BBB' in %s on line %d -bool(false) +Security protocol must be one of DES, AES128, or AES Warning: snmp3_get(): Error generating a key for privacy pass phrase '': Generic error (The supplied password length is too short.) in %s on line %d bool(false) @@ -62,6 +78,4 @@ bool(false) Warning: snmp3_set(): Invalid object identifier: .1.3.6.777...7.5.3 in %s on line %d bool(false) - -Warning: snmp3_set(): Single objid and multiple type or values are not supported in %s on line %d -bool(false) +Type must be of type string when object ID is a string diff --git a/ext/snmp/tests/snmp_get_valueretrieval.phpt b/ext/snmp/tests/snmp_get_valueretrieval.phpt index 5d2242c1cd6f4..11358135b0b56 100644 --- a/ext/snmp/tests/snmp_get_valueretrieval.phpt +++ b/ext/snmp/tests/snmp_get_valueretrieval.phpt @@ -11,7 +11,11 @@ require_once(__DIR__.'/skipif.inc'); require_once(__DIR__.'/snmp_include.inc'); echo "Checking error handling\n"; -var_dump(snmp_set_valueretrieval(67)); +try { + var_dump(snmp_set_valueretrieval(67)); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} echo "Checking working\n"; var_dump(snmp_get_valueretrieval()); @@ -29,9 +33,7 @@ var_dump(snmp_get_valueretrieval() === (SNMP_VALUE_LIBRARY|SNMP_VALUE_OBJECT)); ?> --EXPECTF-- Checking error handling - -Warning: snmp_set_valueretrieval(): Unknown SNMP value retrieval method '67' in %s on line %d -bool(false) +snmp_set_valueretrieval(): Argument #1 ($method) must be a bitmask of SNMP_VALUE_LIBRARY, SNMP_VALUE_PLAIN, and SNMP_VALUE_OBJECT Checking working int(%d) bool(true) diff --git a/ext/snmp/tests/snmp_set_oid_output_format.phpt b/ext/snmp/tests/snmp_set_oid_output_format.phpt index 3ad5f164589f8..9cc28b3c6df10 100644 --- a/ext/snmp/tests/snmp_set_oid_output_format.phpt +++ b/ext/snmp/tests/snmp_set_oid_output_format.phpt @@ -12,17 +12,19 @@ if (!function_exists('snmp_set_oid_output_format')) die('skip This function is o require_once(__DIR__.'/snmp_include.inc'); echo "Checking error handling\n"; -var_dump(snmp_set_oid_output_format(123)); +try { + var_dump(snmp_set_oid_output_format(123)); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} echo "Checking working\n"; var_dump(snmp_set_oid_output_format(SNMP_OID_OUTPUT_FULL)); var_dump(snmp_set_oid_output_format(SNMP_OID_OUTPUT_NUMERIC)); ?> ---EXPECTF-- +--EXPECT-- Checking error handling - -Warning: snmp_set_oid_output_format(): Unknown SNMP output print format '123' in %s on line %d -bool(false) +snmp_set_oid_output_format(): Argument #1 ($oid_format) must be an SNMP_OID_OUTPUT_* constant Checking working bool(true) bool(true) diff --git a/ext/snmp/tests/snmpset.phpt b/ext/snmp/tests/snmpset.phpt index a870ab1ca6bce..f6320d3c29b9e 100644 --- a/ext/snmp/tests/snmpset.phpt +++ b/ext/snmp/tests/snmpset.phpt @@ -16,8 +16,12 @@ snmp_set_valueretrieval(SNMP_VALUE_PLAIN); echo "Check error handing\n"; echo "No type & no value (timeout & retries instead)\n"; -$z = snmpset($hostname, $communityWrite, 'SNMPv2-MIB::sysLocation.0', $timeout, $retries); -var_dump($z); +try { + $z = snmpset($hostname, $communityWrite, 'SNMPv2-MIB::sysLocation.0', $timeout, $retries); + var_dump($z); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} echo "No value (timeout instead), retries instead of timeout\n"; $z = snmpset($hostname, $communityWrite, 'SNMPv2-MIB::sysLocation.0', 'q', $timeout, $retries); @@ -76,26 +80,42 @@ var_dump((snmpget($hostname, $communityWrite, $oid2, $timeout, $retries) === $ol echo "More error handing\n"; echo "Single OID, single type in array, single value\n"; -$z = snmpset($hostname, $communityWrite, $oid1, array('s'), $newvalue1, $timeout, $retries); -var_dump($z); +try { + $z = snmpset($hostname, $communityWrite, $oid1, array('s'), $newvalue1, $timeout, $retries); + var_dump($z); +} catch (\TypeError $e) { + echo $e->getMessage() . \PHP_EOL; +} var_dump((snmpget($hostname, $communityWrite, $oid1, $timeout, $retries) === $oldvalue1)); var_dump((snmpget($hostname, $communityWrite, $oid2, $timeout, $retries) === $oldvalue2)); echo "Single OID, single type, single value in array\n"; -$z = snmpset($hostname, $communityWrite, $oid1, 's', array($newvalue1), $timeout, $retries); -var_dump($z); +try { + $z = snmpset($hostname, $communityWrite, $oid1, 's', array($newvalue1), $timeout, $retries); + var_dump($z); +} catch (\TypeError $e) { + echo $e->getMessage() . \PHP_EOL; +} var_dump((snmpget($hostname, $communityWrite, $oid1, $timeout, $retries) === $oldvalue1)); var_dump((snmpget($hostname, $communityWrite, $oid2, $timeout, $retries) === $oldvalue2)); echo "Multiple OID, 1st wrong type\n"; -$z = snmpset($hostname, $communityWrite, array($oid1, $oid2), array('sw','s'), array($newvalue1, $newvalue2), $timeout, $retries); -var_dump($z); +try { + $z = snmpset($hostname, $communityWrite, array($oid1, $oid2), array('sw','s'), array($newvalue1, $newvalue2), $timeout, $retries); + var_dump($z); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} var_dump((snmpget($hostname, $communityWrite, $oid1, $timeout, $retries) === $oldvalue1)); var_dump((snmpget($hostname, $communityWrite, $oid2, $timeout, $retries) === $oldvalue2)); echo "Multiple OID, 2nd wrong type\n"; -$z = snmpset($hostname, $communityWrite, array($oid1, $oid2), array('s','sb'), array($newvalue1, $newvalue2), $timeout, $retries); -var_dump($z); +try { + $z = snmpset($hostname, $communityWrite, array($oid1, $oid2), array('s','sb'), array($newvalue1, $newvalue2), $timeout, $retries); + var_dump($z); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} var_dump((snmpget($hostname, $communityWrite, $oid1, $timeout, $retries) === $oldvalue1)); var_dump((snmpget($hostname, $communityWrite, $oid2, $timeout, $retries) === $oldvalue2)); @@ -139,9 +159,7 @@ var_dump((snmpget($hostname, $communityWrite, $oid2, $timeout, $retries) === $ol --EXPECTF-- Check error handing No type & no value (timeout & retries instead) - -Warning: snmpset(): Bogus type '-1', should be single char, got 2 in %s on line %d -bool(false) +Type must be a single character No value (timeout instead), retries instead of timeout Warning: snmpset(): Could not add variable: OID='%s' type='q' value='%i': Bad variable type ("q") in %s on line %d @@ -179,27 +197,19 @@ bool(true) bool(true) More error handing Single OID, single type in array, single value - -Warning: snmpset(): Single objid and multiple type or values are not supported in %s on line %d -bool(false) +Type must be of type string when object ID is a string bool(true) bool(true) Single OID, single type, single value in array - -Warning: snmpset(): Single objid and multiple type or values are not supported in %s on line %d -bool(false) +Value must be of type string when object ID is a string bool(true) bool(true) Multiple OID, 1st wrong type - -Warning: snmpset(): '%s': bogus type 'sw', should be single char, got 2 in %s on line %d -bool(false) +Type must be a single character bool(true) bool(true) Multiple OID, 2nd wrong type - -Warning: snmpset(): '%s': bogus type 'sb', should be single char, got 2 in %s on line %d -bool(false) +Type must be a single character bool(true) bool(true) Multiple OID, single type in array, multiple value diff --git a/ext/sodium/libsodium.c b/ext/sodium/libsodium.c index 18f7d3db1ddd1..bbe88ba206c12 100644 --- a/ext/sodium/libsodium.c +++ b/ext/sodium/libsodium.c @@ -3067,7 +3067,7 @@ PHP_FUNCTION(sodium_unpad) RETURN_THROWS(); } if (padded_len < blocksize) { - zend_argument_error(sodium_exception_ce, 1, "must not be shorter than the block size"); + zend_argument_error(sodium_exception_ce, 1, "must be at least as long as the block size"); RETURN_THROWS(); } diff --git a/ext/spl/spl_array.c b/ext/spl/spl_array.c index ce468267d089a..fb23939ca24c8 100644 --- a/ext/spl/spl_array.c +++ b/ext/spl/spl_array.c @@ -1144,7 +1144,7 @@ zend_object_iterator *spl_array_get_iterator(zend_class_entry *ce, zval *object, spl_array_object *array_object = Z_SPLARRAY_P(object); if (by_ref && (array_object->ar_flags & SPL_ARRAY_OVERLOADED_CURRENT)) { - zend_throw_exception(spl_ce_RuntimeException, "An iterator cannot be used with foreach by reference", 0); + zend_throw_error(NULL, "An iterator cannot be used with foreach by reference"); return NULL; } diff --git a/ext/spl/spl_directory.c b/ext/spl/spl_directory.c index 72fb1cbe8f575..cc5e4b7ac4849 100644 --- a/ext/spl/spl_directory.c +++ b/ext/spl/spl_directory.c @@ -52,10 +52,9 @@ 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"); \ + zend_throw_error(NULL, "Object not initialized"); \ RETURN_THROWS(); \ } @@ -209,7 +208,7 @@ static inline int spl_filesystem_object_get_file_name(spl_filesystem_object *int case SPL_FS_INFO: case SPL_FS_FILE: if (!intern->file_name) { - zend_throw_exception_ex(spl_ce_RuntimeException, 0, "Object not initialized"); + zend_throw_error(NULL, "Object not initialized"); return FAILURE; } break; @@ -721,19 +720,19 @@ void spl_filesystem_object_construct(INTERNAL_FUNCTION_PARAMETERS, zend_long cto flags |= SPL_FILE_DIR_UNIXPATHS; } if (parsed == FAILURE) { - return; + RETURN_THROWS(); } - if (!len) { - zend_throw_exception_ex(spl_ce_RuntimeException, 0, "Directory name must not be empty."); - return; + if (len == 0) { + zend_argument_value_error(1, "cannot be empty"); + RETURN_THROWS(); } intern = Z_SPLFILESYSTEM_P(ZEND_THIS); if (intern->_path) { /* object is already initialized */ zend_throw_error(NULL, "Directory object is already initialized"); - return; + RETURN_THROWS(); } intern->flags = flags; @@ -1393,9 +1392,7 @@ PHP_METHOD(SplFileInfo, __debugInfo) /* {{{ */ PHP_METHOD(SplFileInfo, _bad_state_ex) { - zend_throw_exception_ex(spl_ce_LogicException, 0, - "The parent constructor was not called: the object is in an " - "invalid state "); + zend_throw_error(NULL, "The parent constructor was not called: the object is in an invalid state"); } /* }}} */ @@ -1612,7 +1609,7 @@ zend_object_iterator *spl_filesystem_dir_get_iterator(zend_class_entry *ce, zval spl_filesystem_object *dir_object; if (by_ref) { - zend_throw_exception(spl_ce_RuntimeException, "An iterator cannot be used with foreach by reference", 0); + zend_throw_error(NULL, "An iterator cannot be used with foreach by reference"); return NULL; } dir_object = Z_SPLFILESYSTEM_P(object); @@ -1819,7 +1816,7 @@ zend_object_iterator *spl_filesystem_tree_get_iterator(zend_class_entry *ce, zva spl_filesystem_object *dir_object; if (by_ref) { - zend_throw_exception(spl_ce_RuntimeException, "An iterator cannot be used with foreach by reference", 0); + zend_throw_error(NULL, "An iterator cannot be used with foreach by reference"); return NULL; } dir_object = Z_SPLFILESYSTEM_P(object); @@ -2021,7 +2018,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) { - zend_throw_exception_ex(spl_ce_RuntimeException, 0, "Object not initialized"); + zend_throw_error(NULL, "Object not initialized"); return; } if (-1 == php_stream_rewind(intern->u.file.stream)) { @@ -2280,7 +2277,7 @@ PHP_METHOD(SplFileObject, setMaxLineLen) } if (max_len < 0) { - zend_throw_exception_ex(spl_ce_DomainException, 0, "Maximum line length must be greater than or equal zero"); + zend_argument_value_error(1, "must be greater than or equal to 0"); RETURN_THROWS(); } @@ -2727,7 +2724,7 @@ PHP_METHOD(SplFileObject, seek) 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); + zend_argument_value_error(1, "must be greater than or equal to 0"); RETURN_THROWS(); } diff --git a/ext/spl/spl_dllist.c b/ext/spl/spl_dllist.c index eb01c09d80fc7..c576104139315 100644 --- a/ext/spl/spl_dllist.c +++ b/ext/spl/spl_dllist.c @@ -1308,7 +1308,7 @@ zend_object_iterator *spl_dllist_get_iterator(zend_class_entry *ce, zval *object spl_dllist_object *dllist_object = Z_SPLDLLIST_P(object); if (by_ref) { - zend_throw_exception(spl_ce_RuntimeException, "An iterator cannot be used with foreach by reference", 0); + zend_throw_error(NULL, "An iterator cannot be used with foreach by reference"); return NULL; } diff --git a/ext/spl/spl_fixedarray.c b/ext/spl/spl_fixedarray.c index 558514eec1e50..915e55f17cc6c 100644 --- a/ext/spl/spl_fixedarray.c +++ b/ext/spl/spl_fixedarray.c @@ -529,7 +529,7 @@ PHP_METHOD(SplFixedArray, __construct) } if (size < 0) { - zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0, "array size cannot be less than zero"); + zend_argument_value_error(1, "must be greater than or equal to 0"); RETURN_THROWS(); } @@ -704,7 +704,7 @@ PHP_METHOD(SplFixedArray, setSize) } if (size < 0) { - zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0, "array size cannot be less than zero"); + zend_argument_value_error(1, "must be greater than or equal to 0"); RETURN_THROWS(); } @@ -955,7 +955,7 @@ zend_object_iterator *spl_fixedarray_get_iterator(zend_class_entry *ce, zval *ob spl_fixedarray_it *iterator; if (by_ref) { - zend_throw_exception(spl_ce_RuntimeException, "An iterator cannot be used with foreach by reference", 0); + zend_throw_error(NULL, "An iterator cannot be used with foreach by reference"); return NULL; } diff --git a/ext/spl/spl_heap.c b/ext/spl/spl_heap.c index 0beea11da0780..ba1b0fd68160f 100644 --- a/ext/spl/spl_heap.c +++ b/ext/spl/spl_heap.c @@ -1066,7 +1066,7 @@ zend_object_iterator *spl_heap_get_iterator(zend_class_entry *ce, zval *object, spl_heap_object *heap_object = Z_SPLHEAP_P(object); if (by_ref) { - zend_throw_exception(spl_ce_RuntimeException, "An iterator cannot be used with foreach by reference", 0); + zend_throw_error(NULL, "An iterator cannot be used with foreach by reference"); return NULL; } @@ -1091,7 +1091,7 @@ zend_object_iterator *spl_pqueue_get_iterator(zend_class_entry *ce, zval *object spl_heap_object *heap_object = Z_SPLHEAP_P(object); if (by_ref) { - zend_throw_exception(spl_ce_RuntimeException, "An iterator cannot be used with foreach by reference", 0); + zend_throw_error(NULL, "An iterator cannot be used with foreach by reference"); return NULL; } diff --git a/ext/spl/spl_iterators.c b/ext/spl/spl_iterators.c index d245cc356731b..731f7f7b6e866 100644 --- a/ext/spl/spl_iterators.c +++ b/ext/spl/spl_iterators.c @@ -125,8 +125,7 @@ static inline spl_recursive_it_object *spl_recursive_it_from_obj(zend_object *ob do { \ spl_dual_it_object *it = Z_SPLDUAL_IT_P(objzval); \ if (it->dit_type == DIT_Unknown) { \ - zend_throw_exception_ex(spl_ce_LogicException, 0, \ - "The object is in an invalid state as the parent constructor was not called"); \ + zend_throw_error(NULL, "The object is in an invalid state as the parent constructor was not called"); \ RETURN_THROWS(); \ } \ (var) = it; \ @@ -135,8 +134,7 @@ static inline spl_recursive_it_object *spl_recursive_it_from_obj(zend_object *ob #define SPL_FETCH_SUB_ELEMENT(var, object, element) \ do { \ if(!(object)->iterators) { \ - zend_throw_exception_ex(spl_ce_LogicException, 0, \ - "The object is in an invalid state as the parent constructor was not called"); \ + zend_throw_error(NULL, "The object is in an invalid state as the parent constructor was not called"); \ return; \ } \ (var) = (object)->iterators[(object)->level].element; \ @@ -145,8 +143,7 @@ static inline spl_recursive_it_object *spl_recursive_it_from_obj(zend_object *ob #define SPL_FETCH_SUB_ELEMENT_ADDR(var, object, element) \ do { \ if(!(object)->iterators) { \ - zend_throw_exception_ex(spl_ce_LogicException, 0, \ - "The object is in an invalid state as the parent constructor was not called"); \ + zend_throw_error(NULL, "The object is in an invalid state as the parent constructor was not called"); \ RETURN_THROWS(); \ } \ (var) = &(object)->iterators[(object)->level].element; \ @@ -448,7 +445,7 @@ static zend_object_iterator *spl_recursive_it_get_iterator(zend_class_entry *ce, spl_recursive_it_object *object; if (by_ref) { - zend_throw_exception(spl_ce_RuntimeException, "An iterator cannot be used with foreach by reference", 0); + zend_throw_error(NULL, "An iterator cannot be used with foreach by reference"); return NULL; } iterator = emalloc(sizeof(spl_recursive_it_iterator)); @@ -698,8 +695,7 @@ PHP_METHOD(RecursiveIteratorIterator, getSubIterator) } if(!object->iterators) { - zend_throw_exception_ex(spl_ce_LogicException, 0, - "The object is in an invalid state as the parent constructor was not called"); + zend_throw_error(NULL, "The object is in an invalid state as the parent constructor was not called"); RETURN_THROWS(); } @@ -829,7 +825,7 @@ PHP_METHOD(RecursiveIteratorIterator, setMaxDepth) RETURN_THROWS(); } if (max_depth < -1) { - zend_throw_exception(spl_ce_OutOfRangeException, "Parameter max_depth must be >= -1", 0); + zend_argument_value_error(1, "must be greater than or equal to -1"); RETURN_THROWS(); } else if (max_depth > INT_MAX) { max_depth = INT_MAX; @@ -1041,7 +1037,7 @@ PHP_METHOD(RecursiveTreeIterator, setPrefixPart) } if (0 > part || part > 5) { - zend_throw_exception_ex(spl_ce_OutOfRangeException, 0, "Use RecursiveTreeIterator::PREFIX_* constant"); + zend_argument_value_error(1, "must be a RecursiveTreeIterator::PREFIX_* constant"); RETURN_THROWS(); } @@ -1059,8 +1055,7 @@ PHP_METHOD(RecursiveTreeIterator, getPrefix) } if(!object->iterators) { - zend_throw_exception_ex(spl_ce_LogicException, 0, - "The object is in an invalid state as the parent constructor was not called"); + zend_throw_error(NULL, "The object is in an invalid state as the parent constructor was not called"); RETURN_THROWS(); } @@ -1092,8 +1087,7 @@ PHP_METHOD(RecursiveTreeIterator, getEntry) } if(!object->iterators) { - zend_throw_exception_ex(spl_ce_LogicException, 0, - "The object is in an invalid state as the parent constructor was not called"); + zend_throw_error(NULL, "The object is in an invalid state as the parent constructor was not called"); RETURN_THROWS(); } @@ -1110,8 +1104,7 @@ PHP_METHOD(RecursiveTreeIterator, getPostfix) } if(!object->iterators) { - zend_throw_exception_ex(spl_ce_LogicException, 0, - "The object is in an invalid state as the parent constructor was not called"); + zend_throw_error(NULL, "The object is in an invalid state as the parent constructor was not called"); RETURN_THROWS(); } @@ -1131,8 +1124,7 @@ PHP_METHOD(RecursiveTreeIterator, current) } if(!object->iterators) { - zend_throw_exception_ex(spl_ce_LogicException, 0, - "The object is in an invalid state as the parent constructor was not called"); + zend_throw_error(NULL, "The object is in an invalid state as the parent constructor was not called"); RETURN_THROWS(); } @@ -1254,6 +1246,7 @@ static zend_function *spl_dual_it_get_method(zend_object **object, zend_string * #define SPL_CHECK_CTOR(intern, classname) \ if (intern->dit_type == DIT_Unknown) { \ + /* TODO Normal Error? */ \ zend_throw_exception_ex(spl_ce_BadMethodCallException, 0, "Classes derived from %s must call %s::__construct()", \ ZSTR_VAL((spl_ce_##classname)->name), ZSTR_VAL((spl_ce_##classname)->name)); \ RETURN_THROWS(); \ @@ -1298,11 +1291,11 @@ static spl_dual_it_object* spl_dual_it_construct(INTERNAL_FUNCTION_PARAMETERS, z return NULL; } if (intern->u.limit.offset < 0) { - zend_throw_exception(spl_ce_OutOfRangeException, "Parameter offset must be >= 0", 0); + zend_argument_value_error(2, "must be greater than or equal to 0"); return NULL; } - if (intern->u.limit.count < 0 && intern->u.limit.count != -1) { - zend_throw_exception(spl_ce_OutOfRangeException, "Parameter count must either be -1 or a value greater than or equal 0", 0); + if (intern->u.limit.count < -1) { + zend_argument_value_error(3, "must be greater than or equal to -1"); return NULL; } break; @@ -1314,7 +1307,9 @@ static spl_dual_it_object* spl_dual_it_construct(INTERNAL_FUNCTION_PARAMETERS, z return NULL; } if (spl_cit_check_flags(flags) != SUCCESS) { - zend_throw_exception(spl_ce_InvalidArgumentException, "Flags must contain only one of CALL_TOSTRING, TOSTRING_USE_KEY, TOSTRING_USE_CURRENT, TOSTRING_USE_INNER", 0); + zend_argument_value_error(2, "must contain only one of CachingIterator::CALL_TOSTRING, " + "CachingIterator::TOSTRING_USE_KEY, CachingIterator::TOSTRING_USE_CURRENT, " + "or CachingIterator::TOSTRING_USE_INNER"); return NULL; } intern->u.caching.flags |= flags & CIT_PUBLIC; @@ -1382,7 +1377,8 @@ static spl_dual_it_object* spl_dual_it_construct(INTERNAL_FUNCTION_PARAMETERS, z return NULL; } if (mode < 0 || mode >= REGIT_MODE_MAX) { - zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0, "Illegal mode " ZEND_LONG_FMT, mode); + zend_argument_value_error(3, "must be RegexIterator::MATCH, RegexIterator::GET_MATCH, " + "RegexIterator::ALL_MATCHES, RegexIterator::SPLIT, or RegexIterator::REPLACE"); return NULL; } @@ -1929,7 +1925,8 @@ PHP_METHOD(RegexIterator, setMode) } if (mode < 0 || mode >= REGIT_MODE_MAX) { - zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0, "Illegal mode " ZEND_LONG_FMT, mode); + zend_argument_value_error(1, "must be RegexIterator::MATCH, RegexIterator::GET_MATCH, " + "RegexIterator::ALL_MATCHES, RegexIterator::SPLIT, or RegexIterator::REPLACE"); RETURN_THROWS(); } @@ -2584,7 +2581,9 @@ PHP_METHOD(CachingIterator, setFlags) SPL_FETCH_AND_CHECK_DUAL_IT(intern, ZEND_THIS); if (spl_cit_check_flags(flags) != SUCCESS) { - zend_throw_exception(spl_ce_InvalidArgumentException , "Flags must contain only one of CALL_TOSTRING, TOSTRING_USE_KEY, TOSTRING_USE_CURRENT, TOSTRING_USE_INNER", 0); + zend_argument_value_error(1, "must contain only one of CachingIterator::CALL_TOSTRING, " + "CachingIterator::TOSTRING_USE_KEY, CachingIterator::TOSTRING_USE_CURRENT, " + "or CachingIterator::TOSTRING_USE_INNER"); RETURN_THROWS(); } if ((intern->u.caching.flags & CIT_CALL_TOSTRING) != 0 && (flags & CIT_CALL_TOSTRING) == 0) { diff --git a/ext/spl/tests/DirectoryIterator_by_reference.phpt b/ext/spl/tests/DirectoryIterator_by_reference.phpt index 0f28262190b33..a6af6569c9f09 100644 --- a/ext/spl/tests/DirectoryIterator_by_reference.phpt +++ b/ext/spl/tests/DirectoryIterator_by_reference.phpt @@ -11,7 +11,7 @@ foreach( $it as &$file ) { } ?> --EXPECTF-- -Fatal error: Uncaught RuntimeException: An iterator cannot be used with foreach by reference in %s:%d +Fatal error: Uncaught Error: An iterator cannot be used with foreach by reference in %s:%d Stack trace: #0 {main} thrown in %s on line %d diff --git a/ext/spl/tests/DirectoryIterator_empty_constructor.phpt b/ext/spl/tests/DirectoryIterator_empty_constructor.phpt index cf96425892603..a2ae3f065c13e 100644 --- a/ext/spl/tests/DirectoryIterator_empty_constructor.phpt +++ b/ext/spl/tests/DirectoryIterator_empty_constructor.phpt @@ -5,11 +5,11 @@ Havard Eide #PHPTestFest2009 Norway 2009-06-09 \o/ --FILE-- getMessage() . \PHP_EOL; +} ?> ---EXPECTF-- -Fatal error: Uncaught RuntimeException: Directory name must not be empty. in %s:%d -Stack trace: -#0 %s(%d): DirectoryIterator->__construct('') -#1 {main} - thrown in %s on line %d +--EXPECT-- +DirectoryIterator::__construct(): Argument #1 ($path) cannot be empty diff --git a/ext/spl/tests/SPLDoublyLinkedList_iterate_by_reference.phpt b/ext/spl/tests/SPLDoublyLinkedList_iterate_by_reference.phpt index 8c3aad3ef7dba..769136c4064fa 100644 --- a/ext/spl/tests/SPLDoublyLinkedList_iterate_by_reference.phpt +++ b/ext/spl/tests/SPLDoublyLinkedList_iterate_by_reference.phpt @@ -17,7 +17,7 @@ try { $value *= $value; echo $value, PHP_EOL; } -} catch (Exception $e) { +} catch (\Error $e) { echo $e->getMessage(), PHP_EOL; } diff --git a/ext/spl/tests/SplFileObject_seek_error_001.phpt b/ext/spl/tests/SplFileObject_seek_error_001.phpt index acebb66f41569..30ad772958555 100644 --- a/ext/spl/tests/SplFileObject_seek_error_001.phpt +++ b/ext/spl/tests/SplFileObject_seek_error_001.phpt @@ -5,9 +5,9 @@ SplFileObject::seek function - test parameters $obj = new SplFileObject(__FILE__); try { $obj->seek(-1); -} catch (LogicException $e) { +} catch (\ValueError $e) { echo($e->getMessage()); } ?> ---EXPECTF-- -Can't seek file %s to negative line -1 +--EXPECT-- +SplFileObject::seek(): Argument #1 ($line_pos) must be greater than or equal to 0 diff --git a/ext/spl/tests/arrayObject_asort_basic1.phpt b/ext/spl/tests/arrayObject_asort_basic1.phpt index 6834febeeeeaf..555b215ccedce 100644 --- a/ext/spl/tests/arrayObject_asort_basic1.phpt +++ b/ext/spl/tests/arrayObject_asort_basic1.phpt @@ -36,7 +36,7 @@ object(ArrayObject)#%d (1) { int(4) } } -asort(): Argument #2 ($sort_flags) must be of type int, string given +asort(): Argument #2 ($flags) must be of type int, string given object(ArrayObject)#%d (1) { ["storage":"ArrayObject":private]=> array(3) { diff --git a/ext/spl/tests/arrayObject_ksort_basic1.phpt b/ext/spl/tests/arrayObject_ksort_basic1.phpt index 0c0bea5373a79..d853e3c017bc3 100644 --- a/ext/spl/tests/arrayObject_ksort_basic1.phpt +++ b/ext/spl/tests/arrayObject_ksort_basic1.phpt @@ -35,7 +35,7 @@ object(ArrayObject)#%d (1) { int(3) } } -ksort(): Argument #2 ($sort_flags) must be of type int, string given +ksort(): Argument #2 ($flags) must be of type int, string given object(ArrayObject)#2 (1) { ["storage":"ArrayObject":private]=> array(4) { diff --git a/ext/spl/tests/array_019.phpt b/ext/spl/tests/array_019.phpt index 2a86e70589381..7d1239c0bdc4f 100644 --- a/ext/spl/tests/array_019.phpt +++ b/ext/spl/tests/array_019.phpt @@ -26,7 +26,7 @@ int(2) int(3) int(4) -Fatal error: Uncaught RuntimeException: An iterator cannot be used with foreach by reference in %s:%d +Fatal error: Uncaught Error: An iterator cannot be used with foreach by reference in %s:%d Stack trace: #0 {main} thrown in %s on line %d diff --git a/ext/spl/tests/bug51119.phpt b/ext/spl/tests/bug51119.phpt index aba523dc62955..2f3348a2c4931 100644 --- a/ext/spl/tests/bug51119.phpt +++ b/ext/spl/tests/bug51119.phpt @@ -6,22 +6,15 @@ SPL: LimitIterator zero is valid offset $array = array('a', 'b', 'c'); $arrayIterator = new ArrayIterator($array); -try { - $limitIterator = new LimitIterator($arrayIterator, 0); - foreach ($limitIterator as $item) { +$limitIterator = new LimitIterator($arrayIterator, 0); +foreach ($limitIterator as $item) { echo $item . "\n"; - } -} catch (OutOfRangeException $e){ - print $e->getMessage() . "\n"; } try { - $limitIterator = new LimitIterator($arrayIterator, -1); - foreach ($limitIterator as $item) { - echo $item . "\n"; - } -} catch (OutOfRangeException $e){ - print $e->getMessage() . "\n"; + $limitIterator = new LimitIterator($arrayIterator, -1); +} catch (\ValueError $e){ + print $e->getMessage() . "\n"; } ?> @@ -29,4 +22,4 @@ try { a b c -Parameter offset must be >= 0 +LimitIterator::__construct(): Argument #2 ($offset) must be greater than or equal to 0 diff --git a/ext/spl/tests/bug54281.phpt b/ext/spl/tests/bug54281.phpt index 5d214d9b18b3a..a2dbcd74476f0 100644 --- a/ext/spl/tests/bug54281.phpt +++ b/ext/spl/tests/bug54281.phpt @@ -12,7 +12,7 @@ foreach($it as $k=>$v) { } ?> --EXPECTF-- -Fatal error: Uncaught LogicException: The object is in an invalid state as the parent constructor was not called in %s:%d +Fatal error: Uncaught Error: The object is in an invalid state as the parent constructor was not called in %s:%d Stack trace: #0 %s%ebug54281.php(8): RecursiveIteratorIterator->rewind() #1 {main} diff --git a/ext/spl/tests/bug54384.phpt b/ext/spl/tests/bug54384.phpt index aa2d6fdb93b8a..fa02e372f524d 100644 --- a/ext/spl/tests/bug54384.phpt +++ b/ext/spl/tests/bug54384.phpt @@ -7,8 +7,8 @@ function test($f) { try { $f(); echo "ran normally (unexpected)\n\n"; - } catch (LogicException $e) { - echo "exception (expected)\n"; + } catch (\Error $e) { + echo "Error (expected)\n"; } } @@ -154,18 +154,18 @@ echo $a,"\n"; } ); ?> --EXPECT-- -IteratorIterator... exception (expected) -FilterIterator... exception (expected) -RecursiveFilterIterator... exception (expected) -ParentIterator... exception (expected) -LimitIterator... exception (expected) -CachingIterator... exception (expected) -RecursiveCachingIterator... exception (expected) -NoRewindIterator... exception (expected) -RegexIterator... exception (expected) -RecursiveRegexIterator... exception (expected) -GlobIterator... exception (expected) -SplFileObject... exception (expected) -SplTempFileObject... exception (expected) -AppendIterator... exception (expected) -InfiniteIterator... exception (expected) +IteratorIterator... Error (expected) +FilterIterator... Error (expected) +RecursiveFilterIterator... Error (expected) +ParentIterator... Error (expected) +LimitIterator... Error (expected) +CachingIterator... Error (expected) +RecursiveCachingIterator... Error (expected) +NoRewindIterator... Error (expected) +RegexIterator... Error (expected) +RecursiveRegexIterator... Error (expected) +GlobIterator... Error (expected) +SplFileObject... Error (expected) +SplTempFileObject... Error (expected) +AppendIterator... Error (expected) +InfiniteIterator... Error (expected) diff --git a/ext/spl/tests/bug55701.phpt b/ext/spl/tests/bug55701.phpt index 737ebf2184b52..69b9eb0abb384 100644 --- a/ext/spl/tests/bug55701.phpt +++ b/ext/spl/tests/bug55701.phpt @@ -15,7 +15,7 @@ function testBaseClass($f) { } catch (RuntimeException $e) { // Throwing a RuntimeException is the correct behaviour for some methods echo "ran normally (expected)\n"; - } catch (LogicException $e) { + } catch (\Error $e) { // Throwing a LogicException is not correct echo "threw LogicException (unexpected)\n"; } @@ -27,8 +27,8 @@ function testChildClass($f) { try { $f(); echo "didn't throw (unexpected)\n"; - } catch (LogicException $e) { - echo "threw LogicException (expected)\n"; + } catch (\Error $e) { + echo "threw Error (expected)\n"; } catch (Exception $e) { echo "threw other exception (unexpected)\n"; } @@ -330,6 +330,6 @@ non-empty GlobIterator... ran normally (expected) ======================= test there are no regressions ======================= SplFileObject existent file... ran normally (expected) SplFileObject non-existent file... ran normally (expected) -extends GlobIterator... threw LogicException (expected) -extends SplFileObject... threw LogicException (expected) -extends SplTempFileObject... threw LogicException (expected) +extends GlobIterator... threw Error (expected) +extends SplFileObject... threw Error (expected) +extends SplTempFileObject... threw Error (expected) diff --git a/ext/spl/tests/bug79710.phpt b/ext/spl/tests/bug79710.phpt index a5c065fd67ba6..8bfaddb0f8c88 100644 --- a/ext/spl/tests/bug79710.phpt +++ b/ext/spl/tests/bug79710.phpt @@ -32,7 +32,7 @@ Run::main(); ?> --EXPECTF-- -Fatal error: Uncaught RuntimeException: Object not initialized in %s:%d +Fatal error: Uncaught Error: Object not initialized in %s:%d Stack trace: #0 %s(%d): SplFileObject->flock(2) #1 [internal function]: Target->__destruct() diff --git a/ext/spl/tests/fileobject_setmaxlinelen_error001.phpt b/ext/spl/tests/fileobject_setmaxlinelen_error001.phpt index 6bfdfdcf50994..5a4229616a322 100644 --- a/ext/spl/tests/fileobject_setmaxlinelen_error001.phpt +++ b/ext/spl/tests/fileobject_setmaxlinelen_error001.phpt @@ -8,10 +8,10 @@ $s = new SplFileObject( __FILE__ ); try { $s->setMaxLineLen(-1); } -catch (DomainException $e) { - echo 'DomainException thrown'; +catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; } ?> --EXPECT-- -DomainException thrown +SplFileObject::setMaxLineLen(): Argument #1 ($max_len) must be greater than or equal to 0 diff --git a/ext/spl/tests/fixedarray_021.phpt b/ext/spl/tests/fixedarray_021.phpt index db4962ef481be..376985fd5d28f 100644 --- a/ext/spl/tests/fixedarray_021.phpt +++ b/ext/spl/tests/fixedarray_021.phpt @@ -12,16 +12,16 @@ var_dump($a->count()); /* negative init value */ try { $b = new SplFixedArray(-10); -} catch (Exception $e) { - var_dump($e->getMessage()); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; } /* resize and negative value */ $b = new SplFixedArray(); try { $b->setSize(-5); -} catch (Exception $e) { - var_dump($e->getMessage()); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; } /* calling __construct() twice */ @@ -46,7 +46,7 @@ try { foreach ($e as $k=>&$v) { var_dump($v); } -} catch (Exception $e) { +} catch (\Error $e) { var_dump($e->getMessage()); } @@ -63,8 +63,8 @@ var_dump(empty($a["3"])); --EXPECTF-- int(0) int(0) -string(35) "array size cannot be less than zero" -string(35) "array size cannot be less than zero" +SplFixedArray::__construct(): Argument #1 ($size) must be greater than or equal to 0 +SplFixedArray::setSize(): Argument #1 ($size) must be greater than or equal to 0 NULL int(0) int(0) diff --git a/ext/spl/tests/heap_009.phpt b/ext/spl/tests/heap_009.phpt index 39d0a19f4be66..833d079b253b5 100644 --- a/ext/spl/tests/heap_009.phpt +++ b/ext/spl/tests/heap_009.phpt @@ -11,7 +11,7 @@ function testForException( $heap ) { foreach( $heap as &$item ); } - catch( RuntimeException $e ) + catch( \Error $e ) { echo $e->getMessage(),"\n"; } diff --git a/ext/spl/tests/iterator_028.phpt b/ext/spl/tests/iterator_028.phpt index 5d681ccac05ef..0b8253d25b382 100644 --- a/ext/spl/tests/iterator_028.phpt +++ b/ext/spl/tests/iterator_028.phpt @@ -39,14 +39,11 @@ foreach($it as $v) echo $it->getDepth() . ": $v\n"; echo "===-1===\n"; $it->setMaxDepth(-1); var_dump($it->getMaxDepth()); -try -{ - $it->setMaxDepth(4); +$it->setMaxDepth(4); +try { $it->setMaxDepth(-2); -} -catch(Exception $e) -{ - var_dump($e->getMessage()); +} catch(\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; } var_dump($it->getMaxDepth()); ?> @@ -105,5 +102,5 @@ int(0) 0: 4 ===-1=== bool(false) -string(33) "Parameter max_depth must be >= -1" +RecursiveIteratorIterator::setMaxDepth(): Argument #1 ($max_depth) must be greater than or equal to -1 int(4) diff --git a/ext/spl/tests/iterator_031.phpt b/ext/spl/tests/iterator_031.phpt index 247e13bfff08a..d1aed21ac0692 100644 --- a/ext/spl/tests/iterator_031.phpt +++ b/ext/spl/tests/iterator_031.phpt @@ -56,7 +56,7 @@ try { $ap->append($it); } -catch(LogicException $e) +catch(\Error $e) { echo $e->getMessage() . "\n"; } diff --git a/ext/spl/tests/iterator_037.phpt b/ext/spl/tests/iterator_037.phpt index 1792b1cb66faa..baa15f36847d3 100644 --- a/ext/spl/tests/iterator_037.phpt +++ b/ext/spl/tests/iterator_037.phpt @@ -7,26 +7,20 @@ function test($ar, $flags) { echo "===$flags===\n"; $it = new CachingIterator($ar, 0); - try - { + try { $it->setFlags($flags); - } - catch (Exception $e) - { + } catch (\ValueError $e) { echo 'Exception: ' . $e->getMessage() . "\n"; var_dump($it->getFlags()); return; } var_dump($it->getFlags()); - try - { + try { foreach($it as $v) { var_dump((string)$it); } - } - catch (Exception $e) - { + } catch (Exception $e) { echo 'Exception: ' . $e->getMessage() . "\n"; } } @@ -110,19 +104,19 @@ string(3) "0:1" string(3) "1:2" string(3) "2:3" ===3=== -Exception: Flags must contain only one of CALL_TOSTRING, TOSTRING_USE_KEY, TOSTRING_USE_CURRENT, TOSTRING_USE_INNER +Exception: CachingIterator::setFlags(): Argument #1 ($flags) must contain only one of CachingIterator::CALL_TOSTRING, CachingIterator::TOSTRING_USE_KEY, CachingIterator::TOSTRING_USE_CURRENT, or CachingIterator::TOSTRING_USE_INNER int(0) ===5=== -Exception: Flags must contain only one of CALL_TOSTRING, TOSTRING_USE_KEY, TOSTRING_USE_CURRENT, TOSTRING_USE_INNER +Exception: CachingIterator::setFlags(): Argument #1 ($flags) must contain only one of CachingIterator::CALL_TOSTRING, CachingIterator::TOSTRING_USE_KEY, CachingIterator::TOSTRING_USE_CURRENT, or CachingIterator::TOSTRING_USE_INNER int(0) ===9=== -Exception: Flags must contain only one of CALL_TOSTRING, TOSTRING_USE_KEY, TOSTRING_USE_CURRENT, TOSTRING_USE_INNER +Exception: CachingIterator::setFlags(): Argument #1 ($flags) must contain only one of CachingIterator::CALL_TOSTRING, CachingIterator::TOSTRING_USE_KEY, CachingIterator::TOSTRING_USE_CURRENT, or CachingIterator::TOSTRING_USE_INNER int(0) ===6=== -Exception: Flags must contain only one of CALL_TOSTRING, TOSTRING_USE_KEY, TOSTRING_USE_CURRENT, TOSTRING_USE_INNER +Exception: CachingIterator::setFlags(): Argument #1 ($flags) must contain only one of CachingIterator::CALL_TOSTRING, CachingIterator::TOSTRING_USE_KEY, CachingIterator::TOSTRING_USE_CURRENT, or CachingIterator::TOSTRING_USE_INNER int(0) ===10=== -Exception: Flags must contain only one of CALL_TOSTRING, TOSTRING_USE_KEY, TOSTRING_USE_CURRENT, TOSTRING_USE_INNER +Exception: CachingIterator::setFlags(): Argument #1 ($flags) must contain only one of CachingIterator::CALL_TOSTRING, CachingIterator::TOSTRING_USE_KEY, CachingIterator::TOSTRING_USE_CURRENT, or CachingIterator::TOSTRING_USE_INNER int(0) ===X=== Exception: Unsetting flag CALL_TO_STRING is not possible diff --git a/ext/spl/tests/iterator_069.phpt b/ext/spl/tests/iterator_069.phpt index 975fbe2f8e194..b9ee3f4b820d9 100644 --- a/ext/spl/tests/iterator_069.phpt +++ b/ext/spl/tests/iterator_069.phpt @@ -14,7 +14,7 @@ foreach ($recItIt as &$val) echo "$val\n"; ?> --EXPECTF-- -Fatal error: Uncaught RuntimeException: An iterator cannot be used with foreach by reference in %s:%d +Fatal error: Uncaught Error: An iterator cannot be used with foreach by reference in %s:%d Stack trace: #0 {main} thrown in %s on line %d diff --git a/ext/spl/tests/recursive_tree_iterator_008.phpt b/ext/spl/tests/recursive_tree_iterator_008.phpt index fbdc3a5cb1790..2dd531882463e 100644 --- a/ext/spl/tests/recursive_tree_iterator_008.phpt +++ b/ext/spl/tests/recursive_tree_iterator_008.phpt @@ -20,14 +20,13 @@ foreach($it as $k => $v) { } try { $it->setPrefixPart(-1, ""); - $it->setPrefixPart(6, ""); -} catch (OutOfRangeException $e) { - echo "OutOfRangeException thrown\n"; +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; } try { $it->setPrefixPart(6, ""); -} catch (OutOfRangeException $e) { - echo "OutOfRangeException thrown\n"; +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; } ?> --EXPECT-- @@ -35,5 +34,5 @@ try { [0] => 0145b [c] => 045Array [0] => 0245d -OutOfRangeException thrown -OutOfRangeException thrown +RecursiveTreeIterator::setPrefixPart(): Argument #1 ($part) must be a RecursiveTreeIterator::PREFIX_* constant +RecursiveTreeIterator::setPrefixPart(): Argument #1 ($part) must be a RecursiveTreeIterator::PREFIX_* constant diff --git a/ext/spl/tests/regexIterator_setMode_error.phpt b/ext/spl/tests/regexIterator_setMode_error.phpt index 3b0eaf1d66c1e..10df255f4a012 100644 --- a/ext/spl/tests/regexIterator_setMode_error.phpt +++ b/ext/spl/tests/regexIterator_setMode_error.phpt @@ -12,13 +12,13 @@ var_dump($regexIterator->getMode()); try { $regexIterator->setMode(7); -} catch (InvalidArgumentException $e) { - var_dump($e->getMessage()); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; var_dump($e->getCode()); } ?> --EXPECT-- int(0) -string(14) "Illegal mode 7" +RegexIterator::setMode(): Argument #1 ($mode) must be RegexIterator::MATCH, RegexIterator::GET_MATCH, RegexIterator::ALL_MATCHES, RegexIterator::SPLIT, or RegexIterator::REPLACE int(0) diff --git a/ext/spl/tests/spl_caching_iterator_constructor_flags.phpt b/ext/spl/tests/spl_caching_iterator_constructor_flags.phpt index 29bae9469d6f3..0d107d206f4af 100644 --- a/ext/spl/tests/spl_caching_iterator_constructor_flags.phpt +++ b/ext/spl/tests/spl_caching_iterator_constructor_flags.phpt @@ -8,16 +8,18 @@ TestFest London May 2009 //line 681 ... $array = array(array(7,8,9),1,2,3,array(4,5,6)); $arrayIterator = new ArrayIterator($array); +new CachingIterator($arrayIterator, 0); /* TODO Should this throw? */ +new CachingIterator($arrayIterator, CachingIterator::CALL_TOSTRING); +new CachingIterator($arrayIterator, CachingIterator::TOSTRING_USE_KEY); +new CachingIterator($arrayIterator, CachingIterator::TOSTRING_USE_CURRENT); +new CachingIterator($arrayIterator, CachingIterator::TOSTRING_USE_INNER); try { -$test = new CachingIterator($arrayIterator, 0); -$test = new CachingIterator($arrayIterator, 1); -$test = new CachingIterator($arrayIterator, 2); -$test = new CachingIterator($arrayIterator, 3); // this throws an exception -} catch (InvalidArgumentException $e){ + $test = new CachingIterator($arrayIterator, 3); // this throws an exception +} catch (\ValueError $e){ print $e->getMessage() . "\n"; } ?> --EXPECT-- -Flags must contain only one of CALL_TOSTRING, TOSTRING_USE_KEY, TOSTRING_USE_CURRENT, TOSTRING_USE_INNER +CachingIterator::__construct(): Argument #2 ($flags) must contain only one of CachingIterator::CALL_TOSTRING, CachingIterator::TOSTRING_USE_KEY, CachingIterator::TOSTRING_USE_CURRENT, or CachingIterator::TOSTRING_USE_INNER diff --git a/ext/spl/tests/spl_limit_iterator_check_limits.phpt b/ext/spl/tests/spl_limit_iterator_check_limits.phpt index 83b99b5c85894..91604abb3da44 100644 --- a/ext/spl/tests/spl_limit_iterator_check_limits.phpt +++ b/ext/spl/tests/spl_limit_iterator_check_limits.phpt @@ -10,26 +10,19 @@ $arrayIterator = new ArrayIterator($array); try { $limitIterator = new LimitIterator($arrayIterator, -1); -} catch (OutOfRangeException $e){ +} catch (\ValueError $e){ print $e->getMessage(). "\n"; } - try { $limitIterator = new LimitIterator($arrayIterator, 0, -2); -} catch (OutOfRangeException $e){ - print $e->getMessage() . "\n"; -} - -try { - $limitIterator = new LimitIterator($arrayIterator, 0, -1); -} catch (OutOfRangeException $e){ +} catch (\ValueError $e){ print $e->getMessage() . "\n"; } - +$limitIterator = new LimitIterator($arrayIterator, 0, -1); ?> --EXPECT-- -Parameter offset must be >= 0 -Parameter count must either be -1 or a value greater than or equal 0 +LimitIterator::__construct(): Argument #2 ($offset) must be greater than or equal to 0 +LimitIterator::__construct(): Argument #3 ($count) must be greater than or equal to -1 diff --git a/ext/sqlite3/sqlite3.c b/ext/sqlite3/sqlite3.c index b06f723b4caf6..464df5ae21aa5 100644 --- a/ext/sqlite3/sqlite3.c +++ b/ext/sqlite3/sqlite3.c @@ -63,14 +63,14 @@ static void php_sqlite3_error(php_sqlite3_db_object *db_obj, char *format, ...) #define SQLITE3_CHECK_INITIALIZED(db_obj, member, class_name) \ if (!(db_obj) || !(member)) { \ - php_sqlite3_error(db_obj, "The " #class_name " object has not been correctly initialised"); \ - RETURN_FALSE; \ + zend_throw_error(NULL, "The " #class_name " object has not been correctly initialised or is already closed"); \ + RETURN_THROWS(); \ } #define SQLITE3_CHECK_INITIALIZED_STMT(member, class_name) \ if (!(member)) { \ - php_error_docref(NULL, E_WARNING, "The " #class_name " object has not been correctly initialised"); \ - RETURN_FALSE; \ + zend_throw_error(NULL, "The " #class_name " object has not been correctly initialised or is already closed"); \ + RETURN_THROWS(); \ } /* {{{ PHP_INI */ diff --git a/ext/sqlite3/tests/bug66550.phpt b/ext/sqlite3/tests/bug66550.phpt index de7aae1493943..244f358a5f094 100644 --- a/ext/sqlite3/tests/bug66550.phpt +++ b/ext/sqlite3/tests/bug66550.phpt @@ -15,7 +15,11 @@ $stmt = $db->prepare('SELECT bar FROM foo WHERE id=:id'); // Close the database connection and free the internal sqlite3_stmt object $db->close(); // Access the sqlite3_stmt object via the php_sqlite3_stmt container -$stmt->reset(); +try { + $stmt->reset(); +} catch (\Error $e) { + echo $e->getMessage() . \PHP_EOL; +} ?> ---EXPECTF-- -Warning: SQLite3Stmt::reset(): The SQLite3 object has not been correctly initialised in %s +--EXPECT-- +The SQLite3 object has not been correctly initialised or is already closed diff --git a/ext/sqlite3/tests/sqlite3_12_unfinalized_stmt_cleanup.phpt b/ext/sqlite3/tests/sqlite3_12_unfinalized_stmt_cleanup.phpt index e3e67f1ff453d..34af57128ab56 100644 --- a/ext/sqlite3/tests/sqlite3_12_unfinalized_stmt_cleanup.phpt +++ b/ext/sqlite3/tests/sqlite3_12_unfinalized_stmt_cleanup.phpt @@ -27,7 +27,11 @@ while ($result = $results->fetchArray(SQLITE3_NUM)) echo "Closing database\n"; var_dump($db->close()); echo "Check db was closed\n"; -var_dump($results->numColumns()); +try { + var_dump($results->numColumns()); +} catch (\Error $e) { + echo $e->getMessage() . \PHP_EOL; +} echo "Done\n"; ?> --EXPECTF-- @@ -46,7 +50,5 @@ array(2) { Closing database bool(true) Check db was closed - -Warning: SQLite3Result::numColumns(): The SQLite3Result object has not been correctly initialised in %s on line %d -bool(false) +The SQLite3Result object has not been correctly initialised or is already closed Done diff --git a/ext/sqlite3/tests/sqlite3_15_open_error.phpt b/ext/sqlite3/tests/sqlite3_15_open_error.phpt index 0c3e9537db2da..817affa78461a 100644 --- a/ext/sqlite3/tests/sqlite3_15_open_error.phpt +++ b/ext/sqlite3/tests/sqlite3_15_open_error.phpt @@ -6,6 +6,9 @@ if(substr(PHP_OS, 0, 3) == 'WIN' ) { die('skip non windows test'); } require_once(__DIR__ . '/skipif.inc'); +if (!function_exists('posix_geteui')) { + die('SKIP posix_geteuid() not defined so cannot check if run as root'); +} if (posix_geteuid() == 0) { die('SKIP Cannot run test as root.'); } diff --git a/ext/standard/array.c b/ext/standard/array.c index cb5e6e7dee6f1..bd2823a4076ca 100644 --- a/ext/standard/array.c +++ b/ext/standard/array.c @@ -716,10 +716,7 @@ PHPAPI zend_long php_count_recursive(HashTable *ht) /* {{{ */ } } ZEND_HASH_FOREACH_END(); - if (!(GC_FLAGS(ht) & GC_IMMUTABLE)) { - GC_UNPROTECT_RECURSION(ht); - } - + GC_TRY_UNPROTECT_RECURSION(ht); return cnt; } /* }}} */ @@ -965,22 +962,6 @@ static int php_array_user_compare(Bucket *a, Bucket *b) /* {{{ */ } /* }}} */ -/* check if comparison function is valid */ -#define PHP_ARRAY_CMP_FUNC_CHECK(func_name) \ - if (!zend_is_callable(*func_name, 0, NULL)) { \ - php_error_docref(NULL, E_WARNING, "Invalid comparison function"); \ - BG(user_compare_fci) = old_user_compare_fci; \ - BG(user_compare_fci_cache) = old_user_compare_fci_cache; \ - RETURN_FALSE; \ - } \ - - /* Clear FCI cache otherwise : for example the same or other array with - * (partly) the same key values has been sorted with uasort() or - * other sorting function the comparison is cached, however the name - * of the function for comparison is not respected. see bug #28739 AND #33295 - * - * Following defines will assist in backup / restore values. */ - #define PHP_ARRAY_CMP_FUNC_VARS \ zend_fcall_info old_user_compare_fci; \ zend_fcall_info_cache old_user_compare_fci_cache \ @@ -2570,7 +2551,7 @@ static void php_compact_var(HashTable *eg_active_symbol_table, zval *return_valu zend_hash_update(Z_ARRVAL_P(return_value), Z_STR_P(entry), &data); } } else { - php_error_docref(NULL, E_NOTICE, "Undefined variable $%s", ZSTR_VAL(Z_STR_P(entry))); + php_error_docref(NULL, E_WARNING, "Undefined variable $%s", ZSTR_VAL(Z_STR_P(entry))); } } else if (Z_TYPE_P(entry) == IS_ARRAY) { if (Z_REFCOUNTED_P(entry)) { @@ -3644,12 +3625,12 @@ PHPAPI int php_array_merge_recursive(HashTable *dest, HashTable *src) /* {{{ */ src_zval = &tmp; } if (Z_TYPE_P(src_zval) == IS_ARRAY) { - if (thash && !(GC_FLAGS(thash) & GC_IMMUTABLE)) { - GC_PROTECT_RECURSION(thash); + if (thash) { + GC_TRY_PROTECT_RECURSION(thash); } ret = php_array_merge_recursive(Z_ARRVAL_P(dest_zval), Z_ARRVAL_P(src_zval)); - if (thash && !(GC_FLAGS(thash) & GC_IMMUTABLE)) { - GC_UNPROTECT_RECURSION(thash); + if (thash) { + GC_TRY_UNPROTECT_RECURSION(thash); } if (!ret) { return 0; diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c index 922bcab330baa..d0c8805fe461a 100755 --- a/ext/standard/basic_functions.c +++ b/ext/standard/basic_functions.c @@ -1310,7 +1310,7 @@ PHP_FUNCTION(time_sleep_until) target_ns = (uint64_t) (target_secs * ns_per_sec); current_ns = ((uint64_t) tm.tv_sec) * ns_per_sec + ((uint64_t) tm.tv_usec) * 1000; if (target_ns < current_ns) { - php_error_docref(NULL, E_WARNING, "Sleep until to time is less than current time"); + php_error_docref(NULL, E_WARNING, "Argument #1 ($timestamp) must be greater than or equal to the current time"); RETURN_FALSE; } @@ -1468,9 +1468,8 @@ PHPAPI int _php_error_log_ex(int opt_err, const char *message, size_t message_le break; case 2: /*send to an address */ - php_error_docref(NULL, E_WARNING, "TCP/IP option not available!"); + zend_value_error("TCP/IP option is not available for error logging"); return FAILURE; - break; case 3: /*save to a file */ stream = php_stream_open_wrapper(opt, "a", IGNORE_URL_WIN | REPORT_ERRORS, NULL); @@ -1684,10 +1683,9 @@ static int user_shutdown_function_call(zval *zv) /* {{{ */ zval retval; if (!zend_is_callable(&shutdown_function_entry->arguments[0], 0, NULL)) { - zend_string *function_name - = zend_get_callable_name(&shutdown_function_entry->arguments[0]); - php_error(E_WARNING, "(Registered shutdown functions) Unable to call %s() - function does not exist", ZSTR_VAL(function_name)); - zend_string_release_ex(function_name, 0); + zend_string *function_name = zend_get_callable_name(&shutdown_function_entry->arguments[0]); + zend_throw_error(NULL, "Registered shutdown function %s() cannot be called, function does not exist", ZSTR_VAL(function_name)); + zend_string_release(function_name); return 0; } @@ -1719,21 +1717,10 @@ static void user_tick_function_call(user_tick_function_entry *tick_fe) /* {{{ */ tick_fe->arguments + 1 ) == SUCCESS) { zval_ptr_dtor(&retval); - } else { - zval *obj, *method; - - if (Z_TYPE_P(function) == IS_STRING) { - php_error_docref(NULL, E_WARNING, "Unable to call %s() - function does not exist", Z_STRVAL_P(function)); - } else if ( Z_TYPE_P(function) == IS_ARRAY - && (obj = zend_hash_index_find(Z_ARRVAL_P(function), 0)) != NULL - && (method = zend_hash_index_find(Z_ARRVAL_P(function), 1)) != NULL - && Z_TYPE_P(obj) == IS_OBJECT - && Z_TYPE_P(method) == IS_STRING) { - php_error_docref(NULL, E_WARNING, "Unable to call %s::%s() - function does not exist", ZSTR_VAL(Z_OBJCE_P(obj)->name), Z_STRVAL_P(method)); - } else { - php_error_docref(NULL, E_WARNING, "Unable to call tick function"); - } + zend_string *function_name = zend_get_callable_name(function); + zend_throw_error(NULL, "Registered tick function %s() cannot be called, function does not exist", ZSTR_VAL(function_name)); + zend_string_release(function_name); } tick_fe->calling = 0; @@ -1764,7 +1751,7 @@ static int user_tick_function_compare(user_tick_function_entry * tick_fe1, user_ } if (ret && tick_fe1->calling) { - php_error_docref(NULL, E_WARNING, "Unable to delete tick function executed at the moment"); + zend_throw_error(NULL, "Registered tick function cannot be unregistered while it is being executed"); return 0; } return ret; @@ -1818,23 +1805,22 @@ PHP_FUNCTION(register_shutdown_function) /* Prevent entering of anything but valid callback (syntax check only!) */ if (!zend_is_callable(&shutdown_function_entry.arguments[0], 0, NULL)) { - zend_string *callback_name - = zend_get_callable_name(&shutdown_function_entry.arguments[0]); - php_error_docref(NULL, E_WARNING, "Invalid shutdown callback '%s' passed", ZSTR_VAL(callback_name)); + zend_string *callback_name = zend_get_callable_name(&shutdown_function_entry.arguments[0]); + zend_argument_type_error(1, "must be a valid callback, function \"%s\" not found or invalid function name", ZSTR_VAL(callback_name)); efree(shutdown_function_entry.arguments); - zend_string_release_ex(callback_name, 0); - RETVAL_FALSE; - } else { - if (!BG(user_shutdown_function_names)) { - ALLOC_HASHTABLE(BG(user_shutdown_function_names)); - zend_hash_init(BG(user_shutdown_function_names), 0, NULL, user_shutdown_function_dtor, 0); - } + zend_string_release(callback_name); + RETURN_THROWS(); + } - for (i = 0; i < shutdown_function_entry.arg_count; i++) { - Z_TRY_ADDREF(shutdown_function_entry.arguments[i]); - } - zend_hash_next_index_insert_mem(BG(user_shutdown_function_names), &shutdown_function_entry, sizeof(php_shutdown_function_entry)); + if (!BG(user_shutdown_function_names)) { + ALLOC_HASHTABLE(BG(user_shutdown_function_names)); + zend_hash_init(BG(user_shutdown_function_names), 0, NULL, user_shutdown_function_dtor, 0); + } + + for (i = 0; i < shutdown_function_entry.arg_count; i++) { + Z_TRY_ADDREF(shutdown_function_entry.arguments[i]); } + zend_hash_next_index_insert_mem(BG(user_shutdown_function_names), &shutdown_function_entry, sizeof(php_shutdown_function_entry)); } /* }}} */ @@ -2057,7 +2043,7 @@ PHP_FUNCTION(ini_get_all) if (extname) { if ((module = zend_hash_str_find_ptr(&module_registry, extname, extname_len)) == NULL) { - php_error_docref(NULL, E_WARNING, "Unable to find extension '%s'", extname); + php_error_docref(NULL, E_WARNING, "Extension \"%s\" cannot be found", extname); RETURN_FALSE; } module_number = module->module_number; @@ -2542,7 +2528,7 @@ PHP_FUNCTION(move_uploaded_file) if (successful) { zend_hash_str_del(SG(rfc1867_uploaded_files), path, path_len); } else { - php_error_docref(NULL, E_WARNING, "Unable to move '%s' to '%s'", path, new_path); + php_error_docref(NULL, E_WARNING, "Unable to move \"%s\" to \"%s\"", path, new_path); } RETURN_BOOL(successful); diff --git a/ext/standard/basic_functions.stub.php b/ext/standard/basic_functions.stub.php index 92406e22befc4..0b771fbd49189 100755 --- a/ext/standard/basic_functions.stub.php +++ b/ext/standard/basic_functions.stub.php @@ -57,11 +57,11 @@ function stream_wrapper_restore(string $protocol): bool {} /* array.c */ -function array_push(array &$stack, mixed ...$args): int {} +function array_push(array &$stack, mixed ...$values): int {} -function krsort(array &$array, int $sort_flags = SORT_REGULAR): bool {} +function krsort(array &$array, int $flags = SORT_REGULAR): bool {} -function ksort(array &$array, int $sort_flags = SORT_REGULAR): bool {} +function ksort(array &$array, int $flags = SORT_REGULAR): bool {} /** @param Countable|array $var */ function count($var, int $mode = COUNT_NORMAL): int {} @@ -76,19 +76,19 @@ function natsort(array &$array): bool {} function natcasesort(array &$array): bool {} -function asort(array &$array, int $sort_flags = SORT_REGULAR): bool {} +function asort(array &$array, int $flags = SORT_REGULAR): bool {} -function arsort(array &$array, int $sort_flags = SORT_REGULAR): bool {} +function arsort(array &$array, int $flags = SORT_REGULAR): bool {} -function sort(array &$array, int $sort_flags = SORT_REGULAR): bool {} +function sort(array &$array, int $flags = SORT_REGULAR): bool {} -function rsort(array &$array, int $sort_flags = SORT_REGULAR): bool {} +function rsort(array &$array, int $flags = SORT_REGULAR): bool {} -function usort(array &$array, callable $cmp_function): bool {} +function usort(array &$array, callable $callback): bool {} -function uasort(array &$array, callable $cmp_function): bool {} +function uasort(array &$array, callable $callback): bool {} -function uksort(array &$array, callable $cmp_function): bool {} +function uksort(array &$array, callable $callback): bool {} function end(array|object &$arg): mixed {} @@ -109,9 +109,9 @@ function min(mixed $arg, mixed ...$args): mixed {} function max(mixed $arg, mixed ...$args): mixed {} -function array_walk(array|object &$input, callable $funcname, mixed $userdata = UNKNOWN): bool {} +function array_walk(array|object &$input, callable $callback, mixed $argument = UNKNOWN): bool {} -function array_walk_recursive(array|object &$input, callable $funcname, mixed $userdata = UNKNOWN): bool {} +function array_walk_recursive(array|object &$input, callable $callback, mixed $argument = UNKNOWN): bool {} function in_array(mixed $needle, array $haystack, bool $strict = false): bool {} @@ -126,9 +126,9 @@ function extract(array &$array, int $extract_type = EXTR_OVERWRITE, string $pref */ function compact($var_name, ...$var_names): array {} -function array_fill(int $start_key, int $num, mixed $val): array {} +function array_fill(int $start_key, int $count, mixed $value): array {} -function array_fill_keys(array $keys, mixed $val): array {} +function array_fill_keys(array $keys, mixed $value): array {} /** * @param string|int|float $low @@ -142,9 +142,9 @@ function array_pop(array &$stack): mixed {} function array_shift(array &$stack): mixed {} -function array_unshift(array &$stack, mixed ...$vars): int {} +function array_unshift(array &$stack, mixed ...$values): int {} -function array_splice(array &$array, int $offset, ?int $length = null, mixed $replacement = []): array {} +function array_splice(array &$array, int $offset, ?int $length = null, mixed $replacements = []): array {} function array_slice(array $array, int $offset, ?int $length = null, bool $preserve_keys = false): array {} @@ -152,11 +152,11 @@ function array_merge(array ...$arrays): array {} function array_merge_recursive(array ...$arrays): array {} -function array_replace(array $array1, array ...$arrays): array {} +function array_replace(array $array, array ...$replacements): array {} -function array_replace_recursive(array $array1, array ...$arrays): array {} +function array_replace_recursive(array $array, array ...$replacements): array {} -function array_keys(array $array, mixed $search_value = UNKNOWN, bool $strict = false): array {} +function array_keys(array $array, mixed $filter_value = UNKNOWN, bool $strict = false): array {} function array_key_first(array $array): int|string|null {} @@ -238,16 +238,16 @@ function array_reduce(array $array, callable $callback, mixed $initial = null): function array_filter(array $array, ?callable $callback = null, int $use_keys = 0): array {} -function array_map(?callable $callback, array $array1, array ...$arrays): array {} +function array_map(?callable $callback, array $array, array ...$arrays): array {} /** @param string|int $key */ -function array_key_exists($key, array $search): bool {} +function array_key_exists($key, array $array): bool {} /** * @param string|int $key * @alias array_key_exists */ -function key_exists($key, array $search): bool {} +function key_exists($key, array $array): bool {} function array_chunk(array $array, int $size, bool $preserve_keys = false): array {} @@ -502,11 +502,9 @@ function header(string $string, bool $replace = true, int $http_response_code = 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 {} +function setrawcookie(string $name, string $value = '', array|int $expires_or_options = 0, string $path = '', string $domain = '', bool $secure = false, bool $httponly = false): bool {} -/** @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 setcookie(string $name, string $value = '', array|int $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 {} @@ -612,11 +610,7 @@ function chunk_split(string $str, int $chunklen = 76, string $ending = "\r\n"): function substr(string $str, int $start, ?int $length = null): string|false {} -/** - * @param array|int $start - * @param array|int|null $length - */ -function substr_replace(array|string $str, string|array $replace, $start, $length = null): string|array|false {} +function substr_replace(array|string $str, array|string $replace, array|int $start, array|int|null $length = null): string|array|false {} function quotemeta(string $str): string {} @@ -678,7 +672,7 @@ function localeconv(): array {} function strnatcasecmp(string $s1, string $s2): int {} -function substr_count(string $haystack, string $needle, int $offset = 0, ?int $length = null): int|false {} +function substr_count(string $haystack, string $needle, int $offset = 0, ?int $length = null): int {} function str_pad(string $input, int $pad_length, string $pad_string = " ", int $pad_type = STR_PAD_RIGHT): string {} @@ -1151,7 +1145,7 @@ function password_get_info(string $hash): ?array {} function password_hash(string $password, string|int|null $algo, array $options = []): string {} -function password_needs_rehash(string $hash, string|int $algo, array $options = []): bool {} +function password_needs_rehash(string $hash, string|int|null $algo, array $options = []): bool {} function password_verify(string $password, string $hash): bool {} @@ -1349,7 +1343,7 @@ function stream_get_wrappers(): array|false {} function stream_get_transports(): array|false {} -/** @param mixed $stream */ +/** @param resource|string $stream */ function stream_is_local($stream): bool {} /** @param resource $stream */ diff --git a/ext/standard/basic_functions_arginfo.h b/ext/standard/basic_functions_arginfo.h old mode 100755 new mode 100644 index fe4c07518cdac..e27c934c0371f --- 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: 251fc9f272492ab76c4a1a1dabcd768269cf1bde */ + * Stub hash: 0224dc521c4a8bd49fbcfd26cddb01a2e571cf74 */ 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) @@ -71,12 +71,12 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_push, 0, 1, IS_LONG, 0) ZEND_ARG_TYPE_INFO(1, stack, IS_ARRAY, 0) - ZEND_ARG_VARIADIC_TYPE_INFO(0, args, IS_MIXED, 0) + ZEND_ARG_VARIADIC_TYPE_INFO(0, values, IS_MIXED, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_krsort, 0, 1, _IS_BOOL, 0) ZEND_ARG_TYPE_INFO(1, array, IS_ARRAY, 0) - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, sort_flags, IS_LONG, 0, "SORT_REGULAR") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, flags, IS_LONG, 0, "SORT_REGULAR") ZEND_END_ARG_INFO() #define arginfo_ksort arginfo_krsort @@ -104,7 +104,7 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_usort, 0, 2, _IS_BOOL, 0) ZEND_ARG_TYPE_INFO(1, array, IS_ARRAY, 0) - ZEND_ARG_TYPE_INFO(0, cmp_function, IS_CALLABLE, 0) + ZEND_ARG_TYPE_INFO(0, callback, IS_CALLABLE, 0) ZEND_END_ARG_INFO() #define arginfo_uasort arginfo_usort @@ -140,8 +140,8 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_walk, 0, 2, _IS_BOOL, 0) ZEND_ARG_TYPE_MASK(1, input, MAY_BE_ARRAY|MAY_BE_OBJECT, NULL) - ZEND_ARG_TYPE_INFO(0, funcname, IS_CALLABLE, 0) - ZEND_ARG_TYPE_INFO(0, userdata, IS_MIXED, 0) + ZEND_ARG_TYPE_INFO(0, callback, IS_CALLABLE, 0) + ZEND_ARG_TYPE_INFO(0, argument, IS_MIXED, 0) ZEND_END_ARG_INFO() #define arginfo_array_walk_recursive arginfo_array_walk @@ -171,13 +171,13 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_fill, 0, 3, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO(0, start_key, IS_LONG, 0) - ZEND_ARG_TYPE_INFO(0, num, IS_LONG, 0) - ZEND_ARG_TYPE_INFO(0, val, IS_MIXED, 0) + ZEND_ARG_TYPE_INFO(0, count, IS_LONG, 0) + ZEND_ARG_TYPE_INFO(0, value, IS_MIXED, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_fill_keys, 0, 2, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO(0, keys, IS_ARRAY, 0) - ZEND_ARG_TYPE_INFO(0, val, IS_MIXED, 0) + ZEND_ARG_TYPE_INFO(0, value, IS_MIXED, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_range, 0, 2, IS_ARRAY, 0) @@ -194,16 +194,13 @@ ZEND_END_ARG_INFO() #define arginfo_array_shift arginfo_array_pop -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_unshift, 0, 1, IS_LONG, 0) - ZEND_ARG_TYPE_INFO(1, stack, IS_ARRAY, 0) - ZEND_ARG_VARIADIC_TYPE_INFO(0, vars, IS_MIXED, 0) -ZEND_END_ARG_INFO() +#define arginfo_array_unshift arginfo_array_push ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_splice, 0, 2, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO(1, array, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO(0, offset, IS_LONG, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, length, IS_LONG, 1, "null") - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, replacement, IS_MIXED, 0, "[]") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, replacements, IS_MIXED, 0, "[]") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_slice, 0, 2, IS_ARRAY, 0) @@ -220,15 +217,15 @@ ZEND_END_ARG_INFO() #define arginfo_array_merge_recursive arginfo_array_merge ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_replace, 0, 1, IS_ARRAY, 0) - ZEND_ARG_TYPE_INFO(0, array1, IS_ARRAY, 0) - ZEND_ARG_VARIADIC_TYPE_INFO(0, arrays, IS_ARRAY, 0) + ZEND_ARG_TYPE_INFO(0, array, IS_ARRAY, 0) + ZEND_ARG_VARIADIC_TYPE_INFO(0, replacements, IS_ARRAY, 0) ZEND_END_ARG_INFO() #define arginfo_array_replace_recursive arginfo_array_replace ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_keys, 0, 1, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO(0, array, IS_ARRAY, 0) - ZEND_ARG_TYPE_INFO(0, search_value, IS_MIXED, 0) + ZEND_ARG_TYPE_INFO(0, filter_value, IS_MIXED, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, strict, _IS_BOOL, 0, "false") ZEND_END_ARG_INFO() @@ -341,13 +338,13 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_map, 0, 2, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO(0, callback, IS_CALLABLE, 1) - ZEND_ARG_TYPE_INFO(0, array1, IS_ARRAY, 0) + ZEND_ARG_TYPE_INFO(0, array, IS_ARRAY, 0) ZEND_ARG_VARIADIC_TYPE_INFO(0, arrays, IS_ARRAY, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_array_key_exists, 0, 2, _IS_BOOL, 0) ZEND_ARG_INFO(0, key) - ZEND_ARG_TYPE_INFO(0, search, IS_ARRAY, 0) + ZEND_ARG_TYPE_INFO(0, array, IS_ARRAY, 0) ZEND_END_ARG_INFO() #define arginfo_key_exists arginfo_array_key_exists @@ -746,7 +743,7 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_setrawcookie, 0, 1, _IS_BOOL, 0) ZEND_ARG_TYPE_INFO(0, name, IS_STRING, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, value, IS_STRING, 0, "\'\'") - ZEND_ARG_INFO_WITH_DEFAULT_VALUE(0, expires_or_options, "0") + ZEND_ARG_TYPE_MASK(0, expires_or_options, MAY_BE_ARRAY|MAY_BE_LONG, "0") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, path, IS_STRING, 0, "\'\'") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, domain, IS_STRING, 0, "\'\'") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, secure, _IS_BOOL, 0, "false") @@ -935,9 +932,9 @@ 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_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_WITH_DEFAULT_VALUE(0, length, "null") + ZEND_ARG_TYPE_MASK(0, replace, MAY_BE_ARRAY|MAY_BE_STRING, NULL) + ZEND_ARG_TYPE_MASK(0, start, MAY_BE_ARRAY|MAY_BE_LONG, NULL) + ZEND_ARG_TYPE_MASK(0, length, MAY_BE_ARRAY|MAY_BE_LONG|MAY_BE_NULL, "null") ZEND_END_ARG_INFO() #define arginfo_quotemeta arginfo_base64_encode @@ -1045,7 +1042,7 @@ ZEND_END_ARG_INFO() #define arginfo_strnatcasecmp arginfo_strnatcmp -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_substr_count, 0, 2, MAY_BE_LONG|MAY_BE_FALSE) +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_substr_count, 0, 2, IS_LONG, 0) ZEND_ARG_TYPE_INFO(0, haystack, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, needle, IS_STRING, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, offset, IS_LONG, 0, "0") @@ -1773,7 +1770,7 @@ 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_TYPE_MASK(0, algo, MAY_BE_STRING|MAY_BE_LONG, NULL) + 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() diff --git a/ext/standard/browscap.c b/ext/standard/browscap.c index e9ee1b1f0e176..f4e38c5860f06 100644 --- a/ext/standard/browscap.c +++ b/ext/standard/browscap.c @@ -413,7 +413,7 @@ static int browscap_read_file(char *filename, browser_data *browdata, int persis zend_stream_init_fp(&fh, VCWD_FOPEN(filename, "r"), filename); if (!fh.handle.fp) { - zend_error(E_CORE_WARNING, "Cannot open '%s' for reading", filename); + zend_error(E_CORE_WARNING, "Cannot open \"%s\" for reading", filename); return FAILURE; } diff --git a/ext/standard/dl.c b/ext/standard/dl.c index 233103f83d00e..b7e3b3bfeb8ad 100644 --- a/ext/standard/dl.c +++ b/ext/standard/dl.c @@ -54,7 +54,7 @@ PHPAPI PHP_FUNCTION(dl) } if (filename_len >= MAXPATHLEN) { - php_error_docref(NULL, E_WARNING, "File name exceeds the maximum allowed length of %d characters", MAXPATHLEN); + php_error_docref(NULL, E_WARNING, "Filename exceeds the maximum allowed length of %d characters", MAXPATHLEN); RETURN_FALSE; } diff --git a/ext/standard/dns_win32.c b/ext/standard/dns_win32.c index 838a40c94e0ca..afeab23a0892f 100644 --- a/ext/standard/dns_win32.c +++ b/ext/standard/dns_win32.c @@ -124,8 +124,8 @@ PHP_FUNCTION(dns_check_record) else if (!strcasecmp("NAPTR", rectype)) type = DNS_TYPE_NAPTR; else if (!strcasecmp("A6", rectype)) type = DNS_TYPE_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(); } } @@ -373,14 +373,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 '%ld' 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, '%ld' 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/file.c b/ext/standard/file.c index 6f29343d9f34c..224e69ffdd553 100644 --- a/ext/standard/file.c +++ b/ext/standard/file.c @@ -942,14 +942,17 @@ PHP_FUNCTION(popen) mode_len--; } } +#endif /* Musl only partially validates the mode. Manually check it to ensure consistent behavior. */ - if (mode_len != 1 || (*posix_mode != 'r' && *posix_mode != 'w')) { - php_error_docref2(NULL, command, posix_mode, E_WARNING, "Invalid mode"); + if (mode_len > 2 || + (mode_len == 1 && (*posix_mode != 'r' && *posix_mode != 'w')) || + (mode_len == 2 && (memcmp(posix_mode, "rb", 2) && memcmp(posix_mode, "wb", 2))) + ) { + zend_argument_value_error(2, "must be one of \"r\", \"rb\", \"w\", or \"wb\""); efree(posix_mode); - RETURN_FALSE; + RETURN_THROWS(); } -#endif fp = VCWD_POPEN(command, posix_mode); if (!fp) { @@ -1816,7 +1819,7 @@ PHP_FUNCTION(fputcsv) zend_argument_value_error(3, "must be a single character"); RETURN_THROWS(); } else if (delimiter_str_len > 1) { - php_error_docref(NULL, E_NOTICE, "delimiter must be a single character"); + php_error_docref(NULL, E_WARNING, "Argument #3 ($delimiter) must be a single character"); } /* use first character from string */ @@ -1828,7 +1831,7 @@ PHP_FUNCTION(fputcsv) zend_argument_value_error(4, "must be a single character"); RETURN_THROWS(); } else if (enclosure_str_len > 1) { - php_error_docref(NULL, E_NOTICE, "enclosure must be a single character"); + php_error_docref(NULL, E_WARNING, "Argument #4 ($enclosure) must be a single character"); } /* use first character from string */ enclosure = *enclosure_str; @@ -1836,7 +1839,7 @@ PHP_FUNCTION(fputcsv) if (escape_str != NULL) { if (escape_str_len > 1) { - php_error_docref(NULL, E_NOTICE, "escape must be empty or a single character"); + php_error_docref(NULL, E_WARNING, "Argument #5 ($escape) must be empty or a single character"); } if (escape_str_len < 1) { escape_char = PHP_CSV_NO_ESCAPE; @@ -1954,7 +1957,7 @@ PHP_FUNCTION(fgetcsv) zend_argument_value_error(3, "must be a single character"); RETURN_THROWS(); } else if (delimiter_str_len > 1) { - php_error_docref(NULL, E_NOTICE, "delimiter must be a single character"); + php_error_docref(NULL, E_WARNING, "Argument #3 ($delimiter) must be a single character"); } /* use first character from string */ @@ -1966,7 +1969,7 @@ PHP_FUNCTION(fgetcsv) zend_argument_value_error(4, "must be a single character"); RETURN_THROWS(); } else if (enclosure_str_len > 1) { - php_error_docref(NULL, E_NOTICE, "enclosure must be a single character"); + php_error_docref(NULL, E_WARNING, "Argument #4 ($enclosure) must be a single character"); } /* use first character from string */ @@ -1975,7 +1978,7 @@ PHP_FUNCTION(fgetcsv) if (escape_str != NULL) { if (escape_str_len > 1) { - php_error_docref(NULL, E_NOTICE, "escape must be empty or a single character"); + php_error_docref(NULL, E_WARNING, "Argument #5 ($enclosure) must be empty or a single character"); } if (escape_str_len < 1) { diff --git a/ext/standard/ftok.c b/ext/standard/ftok.c index 04830fb6df623..1f17ced7d995e 100644 --- a/ext/standard/ftok.c +++ b/ext/standard/ftok.c @@ -45,8 +45,8 @@ PHP_FUNCTION(ftok) } if (proj_len != 1){ - php_error_docref(NULL, E_WARNING, "Project identifier is invalid"); - RETURN_LONG(-1); + zend_argument_value_error(2, "must be a single character"); + RETURN_THROWS(); } if (php_check_open_basedir(pathname)) { diff --git a/ext/standard/head.c b/ext/standard/head.c index 18cb0c4f62c97..36f64fcb4d8eb 100644 --- a/ext/standard/head.c +++ b/ext/standard/head.c @@ -192,13 +192,13 @@ PHPAPI zend_result php_setcookie(zend_string *name, zend_string *value, time_t e return result; } -static zend_result php_head_parse_cookie_options_array(zval *options, zend_long *expires, zend_string **path, +static zend_result php_head_parse_cookie_options_array(HashTable *options, zend_long *expires, zend_string **path, zend_string **domain, zend_bool *secure, zend_bool *httponly, zend_string **samesite) { zend_string *key; zval *value; - ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(options), key, value) { + ZEND_HASH_FOREACH_STR_KEY_VAL(options, key, value) { if (!key) { zend_value_error("%s(): option array cannot have numeric keys", get_active_function_name()); return FAILURE; @@ -225,36 +225,33 @@ static zend_result php_head_parse_cookie_options_array(zval *options, zend_long static void php_setcookie_common(INTERNAL_FUNCTION_PARAMETERS, bool is_raw) { - /* to handle overloaded function array|int */ - zval *expires_or_options = NULL; - zend_string *name, *value = NULL, *path = NULL, *domain = NULL, *samesite = NULL; + HashTable *options = NULL; zend_long expires = 0; + zend_string *name, *value = NULL, *path = NULL, *domain = NULL, *samesite = NULL; zend_bool secure = 0, httponly = 0; ZEND_PARSE_PARAMETERS_START(1, 7) Z_PARAM_STR(name) Z_PARAM_OPTIONAL Z_PARAM_STR(value) - Z_PARAM_ZVAL(expires_or_options) + Z_PARAM_ARRAY_HT_OR_LONG(options, expires) Z_PARAM_STR(path) Z_PARAM_STR(domain) Z_PARAM_BOOL(secure) Z_PARAM_BOOL(httponly) ZEND_PARSE_PARAMETERS_END(); - if (expires_or_options) { - if (Z_TYPE_P(expires_or_options) == IS_ARRAY) { - if (UNEXPECTED(ZEND_NUM_ARGS() > 3)) { - zend_argument_count_error("%s(): Expects exactly 3 arguments when argument #3 " - "($expires_or_options) is an array", get_active_function_name()); - RETURN_THROWS(); - } - if (FAILURE == php_head_parse_cookie_options_array(expires_or_options, &expires, &path, - &domain, &secure, &httponly, &samesite)) { - goto cleanup; - } - } else { - expires = zval_get_long(expires_or_options); + if (options) { + if (UNEXPECTED(ZEND_NUM_ARGS() > 3)) { + zend_argument_count_error("%s(): Expects exactly 3 arguments when argument #3 " + "($expires_or_options) is an array", get_active_function_name()); + RETURN_THROWS(); + } + + if (FAILURE == php_head_parse_cookie_options_array(options, &expires, &path, + &domain, &secure, &httponly, &samesite) + ) { + goto cleanup; } } @@ -264,7 +261,7 @@ static void php_setcookie_common(INTERNAL_FUNCTION_PARAMETERS, bool is_raw) RETVAL_FALSE; } - if (expires_or_options && Z_TYPE_P(expires_or_options) == IS_ARRAY) { + if (options) { cleanup: if (path) { zend_string_release(path); diff --git a/ext/standard/html.c b/ext/standard/html.c index dfed889875381..463e55c255cb8 100644 --- a/ext/standard/html.c +++ b/ext/standard/html.c @@ -382,7 +382,7 @@ static enum entity_charset determine_charset(const char *charset_hint, zend_bool } if (!quiet) { - php_error_docref(NULL, E_WARNING, "Charset `%s' not supported, assuming utf-8", + php_error_docref(NULL, E_WARNING, "Charset \"%s\" is not supported, assuming UTF-8", charset_hint); } } diff --git a/ext/standard/http.c b/ext/standard/http.c index 3819065894a71..804940fd1a63e 100644 --- a/ext/standard/http.c +++ b/ext/standard/http.c @@ -146,13 +146,9 @@ PHPAPI int php_url_encode_hash_ex(HashTable *ht, smart_str *formstr, *(p++) = 'B'; *p = '\0'; } - if (!(GC_FLAGS(ht) & GC_IMMUTABLE)) { - GC_PROTECT_RECURSION(ht); - } + GC_TRY_PROTECT_RECURSION(ht); php_url_encode_hash_ex(HASH_OF(zdata), formstr, NULL, 0, newprefix, newprefix_len, "%5D", 3, (Z_TYPE_P(zdata) == IS_OBJECT ? zdata : NULL), arg_sep, enc_type); - if (!(GC_FLAGS(ht) & GC_IMMUTABLE)) { - GC_UNPROTECT_RECURSION(ht); - } + GC_TRY_UNPROTECT_RECURSION(ht); efree(newprefix); } else if (Z_TYPE_P(zdata) == IS_NULL || Z_TYPE_P(zdata) == IS_RESOURCE) { /* Skip these types */ diff --git a/ext/standard/mail.c b/ext/standard/mail.c index af7d5f114bcbd..3080a3957bb9c 100644 --- a/ext/standard/mail.c +++ b/ext/standard/mail.c @@ -105,11 +105,11 @@ static void php_mail_build_headers_elem(smart_str *s, zend_string *key, zval *va switch(Z_TYPE_P(val)) { case IS_STRING: if (php_mail_build_headers_check_field_name(key) != SUCCESS) { - php_error_docref(NULL, E_WARNING, "Header field name (%s) contains invalid chars", ZSTR_VAL(key)); + zend_value_error("Header name \"%s\" contains invalid characters", ZSTR_VAL(key)); return; } if (php_mail_build_headers_check_field_value(val) != SUCCESS) { - php_error_docref(NULL, E_WARNING, "Header field value (%s => %s) contains invalid chars or format", ZSTR_VAL(key), Z_STRVAL_P(val)); + zend_value_error("Header \"%s\" has invalid format, or contains invalid characters", ZSTR_VAL(key)); return; } smart_str_append(s, key); @@ -121,7 +121,7 @@ static void php_mail_build_headers_elem(smart_str *s, zend_string *key, zval *va php_mail_build_headers_elems(s, key, val); break; default: - php_error_docref(NULL, E_WARNING, "Headers array elements must be string or array (%s)", ZSTR_VAL(key)); + zend_type_error("Header \"%s\" must be of type array|string, %s given", ZSTR_VAL(key), zend_zval_type_name(val)); } } @@ -133,12 +133,12 @@ static void php_mail_build_headers_elems(smart_str *s, zend_string *key, zval *v ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(val), tmp_key, tmp_val) { if (tmp_key) { - php_error_docref(NULL, E_WARNING, "Multiple header key must be numeric index (%s)", ZSTR_VAL(tmp_key)); - continue; + zend_type_error("Header \"%s\" must only contain numeric keys, \"%s\" found", ZSTR_VAL(key), ZSTR_VAL(tmp_key)); + break; } if (Z_TYPE_P(tmp_val) != IS_STRING) { - php_error_docref(NULL, E_WARNING, "Multiple header values must be string (%s)", ZSTR_VAL(key)); - continue; + zend_type_error("Header \"%s\" must only contain values of type string, %s found", ZSTR_VAL(key), zend_zval_type_name(tmp_val)); + break; } php_mail_build_headers_elem(s, key, tmp_val); } ZEND_HASH_FOREACH_END(); @@ -154,8 +154,8 @@ PHPAPI zend_string *php_mail_build_headers(HashTable *headers) ZEND_HASH_FOREACH_KEY_VAL(headers, idx, key, val) { if (!key) { - php_error_docref(NULL, E_WARNING, "Found numeric header (" ZEND_LONG_FMT ")", idx); - continue; + zend_type_error("Header name cannot be numeric, " ZEND_LONG_FMT " given", idx); + break; } /* https://tools.ietf.org/html/rfc2822#section-3.6 */ switch(ZSTR_LEN(key)) { @@ -189,8 +189,8 @@ PHPAPI zend_string *php_mail_build_headers(HashTable *headers) break; case sizeof("to")-1: /* "to", "cc" */ if (!strncasecmp("to", ZSTR_VAL(key), ZSTR_LEN(key))) { - php_error_docref(NULL, E_WARNING, "Extra header cannot contain 'To' header"); - continue; + zend_value_error("The additional headers cannot contain the \"To\" header"); + break; } if (!strncasecmp("cc", ZSTR_VAL(key), ZSTR_LEN(key))) { PHP_MAIL_BUILD_HEADER_CHECK("cc", s, key, val); @@ -223,14 +223,19 @@ PHPAPI zend_string *php_mail_build_headers(HashTable *headers) break; case sizeof("subject")-1: if (!strncasecmp("subject", ZSTR_VAL(key), ZSTR_LEN(key))) { - php_error_docref(NULL, E_WARNING, "Extra header cannot contain 'Subject' header"); - continue; + zend_value_error("The additional headers cannot contain the \"Subject\" header"); + break; } PHP_MAIL_BUILD_HEADER_DEFAULT(s, key, val); break; default: PHP_MAIL_BUILD_HEADER_DEFAULT(s, key, val); } + + if (EG(exception)) { + smart_str_free(&s); + return NULL; + } } ZEND_HASH_FOREACH_END(); /* Remove the last \r\n */ @@ -271,6 +276,9 @@ PHP_FUNCTION(mail) headers_str = php_trim(headers_str, NULL, 0, 2); } else if (headers_ht) { headers_str = php_mail_build_headers(headers_ht); + if (EG(exception)) { + RETURN_THROWS(); + } } if (to_len > 0) { diff --git a/ext/standard/math.c b/ext/standard/math.c index 4f723be365dfa..c10dea9a3879f 100644 --- a/ext/standard/math.c +++ b/ext/standard/math.c @@ -704,7 +704,7 @@ PHPAPI zend_long _php_math_basetolong(zval *arg, int base) { - php_error_docref(NULL, E_WARNING, "Number '%s' is too big to fit in long", s); + php_error_docref(NULL, E_WARNING, "Number %s is too big to fit in long", s); return ZEND_LONG_MAX; } } @@ -877,8 +877,8 @@ PHPAPI zend_string * _php_math_zvaltobase(zval *arg, int base) /* Don't try to convert +/- infinity */ if (fvalue == ZEND_INFINITY || fvalue == -ZEND_INFINITY) { - php_error_docref(NULL, E_WARNING, "Number too large"); - return ZSTR_EMPTY_ALLOC(); + zend_value_error("An infinite value cannot be converted to base %d", base); + return NULL; } end = ptr = buf + sizeof(buf) - 1; @@ -999,6 +999,10 @@ PHP_FUNCTION(base_convert) _php_math_basetozval(number, (int)frombase, &temp); result = _php_math_zvaltobase(&temp, (int)tobase); + if (!result) { + RETURN_THROWS(); + } + RETVAL_STR(result); } /* }}} */ diff --git a/ext/standard/net.c b/ext/standard/net.c index 9f22c75840200..424dad44f4263 100644 --- a/ext/standard/net.c +++ b/ext/standard/net.c @@ -301,8 +301,7 @@ PHP_FUNCTION(net_get_interfaces) { freeifaddrs(addrs); #else /* Should never happen as we never register the function */ - php_error(E_WARNING, "No support for net_get_interfaces"); - RETURN_FALSE; + ZEND_UNREACHABLE("No support for net_get_interfaces"); #endif } /* }}} */ diff --git a/ext/standard/password.c b/ext/standard/password.c index 687a780d1d556..a19266d21475c 100644 --- a/ext/standard/password.c +++ b/ext/standard/password.c @@ -109,7 +109,7 @@ static zend_string* php_password_make_salt(size_t length) /* {{{ */ static zend_string* php_password_get_salt(zval *unused_, size_t required_salt_len, HashTable *options) { if (options && zend_hash_str_exists(options, "salt", sizeof("salt") - 1)) { - php_error_docref(NULL, E_WARNING, "The 'salt' option is no longer supported. The provided salt has been been ignored"); + php_error_docref(NULL, E_WARNING, "The \"salt\" option has been ignored, since providing a custom salt is no longer supported"); } return php_password_make_salt(required_salt_len); diff --git a/ext/standard/php_mail.h b/ext/standard/php_mail.h index 2a561d55233f5..7e7a758545f1f 100644 --- a/ext/standard/php_mail.h +++ b/ext/standard/php_mail.h @@ -28,12 +28,12 @@ do { \ php_mail_build_headers_elem(&s, key, val); \ } else if (Z_TYPE_P(val) == IS_ARRAY) { \ if (!strncasecmp(target, ZSTR_VAL(key), ZSTR_LEN(key))) { \ - php_error_docref(NULL, E_WARNING, "'%s' header must be at most one header. Array is passed for '%s'", target, target); \ - continue; \ + zend_type_error("Header \"%s\" must be of type string, array given", target); \ + break; \ } \ php_mail_build_headers_elems(&s, key, val); \ } else { \ - php_error_docref(NULL, E_WARNING, "Extra header element '%s' cannot be other than string or array.", ZSTR_VAL(key)); \ + zend_type_error("Header \"%s\" must be of type array|string, %s given", ZSTR_VAL(key), zend_zval_type_name(val)); \ } \ } while(0) @@ -45,7 +45,7 @@ do { \ } else if (Z_TYPE_P(val) == IS_ARRAY) { \ php_mail_build_headers_elems(&s, key, val); \ } else { \ - php_error_docref(NULL, E_WARNING, "Extra header element '%s' cannot be other than string or array.", ZSTR_VAL(key)); \ + zend_type_error("Header \"%s\" must be of type array|string, %s given", ZSTR_VAL(key), zend_zval_type_name(val)); \ } \ } while(0) diff --git a/ext/standard/streamsfuncs.c b/ext/standard/streamsfuncs.c index 50e0a38d9bc6a..8e4c4ff2611a6 100644 --- a/ext/standard/streamsfuncs.c +++ b/ext/standard/streamsfuncs.c @@ -432,8 +432,8 @@ PHP_FUNCTION(stream_get_contents) 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; + zend_argument_value_error(2, "must be greater than or equal to -1"); + RETURN_THROWS(); } php_stream_from_zval(stream, zsrc); @@ -459,7 +459,7 @@ PHP_FUNCTION(stream_get_contents) } if (maxlen > INT_MAX) { - php_error_docref(NULL, E_WARNING, "maxlen truncated from " ZEND_LONG_FMT " to %d bytes", maxlen, INT_MAX); + php_error_docref(NULL, E_WARNING, "Argument #2 ($maxlength) is truncated from " ZEND_LONG_FMT " to %d bytes", maxlen, INT_MAX); maxlen = INT_MAX; } if ((contents = php_stream_copy_to_mem(stream, maxlen, 0))) { diff --git a/ext/standard/string.c b/ext/standard/string.c index 9fd7e5f454377..7e6f05ad71c7c 100644 --- a/ext/standard/string.c +++ b/ext/standard/string.c @@ -2237,8 +2237,11 @@ PHP_FUNCTION(substr_replace) { zend_string *str, *repl_str; HashTable *str_ht, *repl_ht; - zval *from; - zval *len = NULL; + HashTable *from_ht; + zend_long from_long; + HashTable *len_ht = NULL; + zend_long len_long; + zend_bool len_is_null = 1; zend_long l = 0; zend_long f; zend_string *result; @@ -2248,39 +2251,26 @@ PHP_FUNCTION(substr_replace) ZEND_PARSE_PARAMETERS_START(3, 4) Z_PARAM_ARRAY_HT_OR_STR(str_ht, str) Z_PARAM_ARRAY_HT_OR_STR(repl_ht, repl_str) - Z_PARAM_ZVAL(from) + Z_PARAM_ARRAY_HT_OR_LONG(from_ht, from_long) Z_PARAM_OPTIONAL - Z_PARAM_ZVAL_OR_NULL(len) + Z_PARAM_ARRAY_HT_OR_LONG_OR_NULL(len_ht, len_long, len_is_null) ZEND_PARSE_PARAMETERS_END(); - if (Z_TYPE_P(from) != IS_ARRAY) { - convert_to_long_ex(from); - if (EG(exception)) { - RETURN_THROWS(); - } - } - - if (len) { - if (Z_TYPE_P(len) != IS_ARRAY) { - convert_to_long_ex(len); - l = Z_LVAL_P(len); - } - } else { + if (len_is_null) { if (str) { l = ZSTR_LEN(str); } + } else if (!len_ht) { + l = len_long; } if (str) { - if ( - (!len && Z_TYPE_P(from) == IS_ARRAY) || - (len && Z_TYPE_P(from) != Z_TYPE_P(len)) - ) { + if ((len_is_null && from_ht) || (!len_is_null && (from_ht == NULL) != (len_ht == NULL))) { php_error_docref(NULL, E_WARNING, "'start' and 'length' should be of same type - numerical or array "); RETURN_STR_COPY(str); } - 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))) { + if (!len_is_null && from_ht) { + if (zend_hash_num_elements(from_ht) != zend_hash_num_elements(len_ht)) { php_error_docref(NULL, E_WARNING, "'start' and 'length' should have the same number of elements"); RETURN_STR_COPY(str); } @@ -2288,8 +2278,8 @@ PHP_FUNCTION(substr_replace) } if (str) { - if (Z_TYPE_P(from) != IS_ARRAY) { - f = Z_LVAL_P(from); + if (!from_ht) { + f = from_long; /* if "from" position is negative, count start position from the end * of the string @@ -2364,15 +2354,15 @@ PHP_FUNCTION(substr_replace) zend_string *tmp_orig_str; zend_string *orig_str = zval_get_tmp_string(tmp_str, &tmp_orig_str); - if (Z_TYPE_P(from) == IS_ARRAY) { - while (from_idx < Z_ARRVAL_P(from)->nNumUsed) { - tmp_from = &Z_ARRVAL_P(from)->arData[from_idx].val; + if (from_ht) { + while (from_idx < from_ht->nNumUsed) { + tmp_from = &from_ht->arData[from_idx].val; if (Z_TYPE_P(tmp_from) != IS_UNDEF) { break; } from_idx++; } - if (from_idx < Z_ARRVAL_P(from)->nNumUsed) { + if (from_idx < from_ht->nNumUsed) { f = zval_get_long(tmp_from); if (f < 0) { @@ -2388,7 +2378,7 @@ PHP_FUNCTION(substr_replace) f = 0; } } else { - f = Z_LVAL_P(from); + f = from_long; if (f < 0) { f = (zend_long)ZSTR_LEN(orig_str) + f; if (f < 0) { @@ -2399,22 +2389,22 @@ PHP_FUNCTION(substr_replace) } } - 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 (len_ht) { + while (len_idx < len_ht->nNumUsed) { + tmp_len = &len_ht->arData[len_idx].val; if (Z_TYPE_P(tmp_len) != IS_UNDEF) { break; } len_idx++; } - if (len_idx < Z_ARRVAL_P(len)->nNumUsed) { + if (len_idx < len_ht->nNumUsed) { l = zval_get_long(tmp_len); len_idx++; } else { l = ZSTR_LEN(orig_str); } - } else if (len) { - l = Z_LVAL_P(len); + } else if (!len_is_null) { + l = len_long; } else { l = ZSTR_LEN(orig_str); } @@ -5431,7 +5421,7 @@ PHP_FUNCTION(substr_count) ZEND_PARSE_PARAMETERS_END(); if (needle_len == 0) { - zend_argument_value_error(2, "must be a non-empty string"); + zend_argument_value_error(2, "cannot be empty"); RETURN_THROWS(); } @@ -5453,8 +5443,8 @@ PHP_FUNCTION(substr_count) length += (haystack_len - offset); } if (length < 0 || ((size_t)length > (haystack_len - offset))) { - php_error_docref(NULL, E_WARNING, "Invalid length value"); - RETURN_FALSE; + zend_argument_value_error(4, "must be contained in argument #1 ($haystack)"); + RETURN_THROWS(); } endp = p + length; } @@ -5918,8 +5908,8 @@ PHP_FUNCTION(substr_compare) } if ((size_t)offset > ZSTR_LEN(s1)) { - php_error_docref(NULL, E_WARNING, "The start position cannot exceed initial string length"); - RETURN_FALSE; + zend_argument_value_error(3, "must be contained in argument #1 ($main_str)"); + RETURN_THROWS(); } cmp_len = len ? (size_t)len : MAX(ZSTR_LEN(s2), (ZSTR_LEN(s1) - offset)); diff --git a/ext/standard/tests/array/array_fill_error.phpt b/ext/standard/tests/array/array_fill_error.phpt index d769298eab7fa..9b04f7553944e 100644 --- a/ext/standard/tests/array/array_fill_error.phpt +++ b/ext/standard/tests/array/array_fill_error.phpt @@ -18,4 +18,4 @@ try { ?> --EXPECT-- *** Testing array_fill() : error conditions *** -array_fill(): Argument #2 ($num) must be greater than or equal to 0 +array_fill(): Argument #2 ($count) must be greater than or equal to 0 diff --git a/ext/standard/tests/array/array_map_variation10.phpt b/ext/standard/tests/array/array_map_variation10.phpt index e226b7c71d46d..769618e6ec8b9 100644 --- a/ext/standard/tests/array/array_map_variation10.phpt +++ b/ext/standard/tests/array/array_map_variation10.phpt @@ -83,5 +83,5 @@ array(3) { NULL } -- passing NULL as 'array1' -- -array_map(): Argument #2 ($array1) must be of type array, null given +array_map(): Argument #2 ($array) must be of type array, null given Done diff --git a/ext/standard/tests/array/array_walk_recursive_variation8.phpt b/ext/standard/tests/array/array_walk_recursive_variation8.phpt index 8002957e7e4f6..aafa158d6c732 100644 --- a/ext/standard/tests/array/array_walk_recursive_variation8.phpt +++ b/ext/standard/tests/array/array_walk_recursive_variation8.phpt @@ -35,5 +35,5 @@ bool(true) -- With 'min' built-in function -- bool(true) -- With 'echo' language construct -- -array_walk_recursive(): Argument #2 ($funcname) must be a valid callback, function "echo" not found or invalid function name +array_walk_recursive(): Argument #2 ($callback) must be a valid callback, function "echo" not found or invalid function name Done diff --git a/ext/standard/tests/array/array_walk_variation8.phpt b/ext/standard/tests/array/array_walk_variation8.phpt index 2186bb64023b1..a4dae8a7e184b 100644 --- a/ext/standard/tests/array/array_walk_variation8.phpt +++ b/ext/standard/tests/array/array_walk_variation8.phpt @@ -35,5 +35,5 @@ bool(true) -- With 'min' built-in function -- bool(true) -- With 'echo' language construct -- -array_walk(): Argument #2 ($funcname) must be a valid callback, function "echo" not found or invalid function name +array_walk(): Argument #2 ($callback) must be a valid callback, function "echo" not found or invalid function name Done diff --git a/ext/standard/tests/array/bug69198.phpt b/ext/standard/tests/array/bug69198.phpt index 1231c44c936db..ab43df7e5cb6b 100644 --- a/ext/standard/tests/array/bug69198.phpt +++ b/ext/standard/tests/array/bug69198.phpt @@ -9,7 +9,7 @@ $result = compact('willNeverBeDefined'); var_dump($result, empty($result), $result === array(), empty($willNeverBeDefined)); ?> --EXPECTF-- -Notice: compact(): Undefined variable $willNeverBeDefined in %s on line %d +Warning: compact(): Undefined variable $willNeverBeDefined in %s on line %d array(0) { } bool(true) diff --git a/ext/standard/tests/array/bug74345.phpt b/ext/standard/tests/array/bug74345.phpt index cc5520676089a..64942f126e7b0 100644 --- a/ext/standard/tests/array/bug74345.phpt +++ b/ext/standard/tests/array/bug74345.phpt @@ -40,7 +40,7 @@ try { ?> ===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 +array_map(): Argument #2 ($array) must be of type array, null given +array_map(): Argument #2 ($array) must be of type array, null given preg_replace_callback(): Argument #3 ($subject) must be of type array|string, stdClass given ===DONE=== diff --git a/ext/standard/tests/array/compact.phpt b/ext/standard/tests/array/compact.phpt index 8c3ee9a16019f..978120e822cea 100644 --- a/ext/standard/tests/array/compact.phpt +++ b/ext/standard/tests/array/compact.phpt @@ -13,7 +13,7 @@ $result = compact("event", $location_vars); var_dump($result); ?> --EXPECTF-- -Notice: compact(): Undefined variable $c\u0327ity in %s on line %d +Warning: compact(): Undefined variable $c\u0327ity in %s on line %d array(2) { ["event"]=> string(8) "SIGGRAPH" diff --git a/ext/standard/tests/array/compact_basic.phpt b/ext/standard/tests/array/compact_basic.phpt index 5187cb77ebd60..da8844d38b276 100644 --- a/ext/standard/tests/array/compact_basic.phpt +++ b/ext/standard/tests/array/compact_basic.phpt @@ -75,7 +75,7 @@ array(0) { array(0) { } -Notice: compact(): Undefined variable $g in %s on line %d +Warning: compact(): Undefined variable $g in %s on line %d array(0) { } Done diff --git a/ext/standard/tests/array/compact_variation2.phpt b/ext/standard/tests/array/compact_variation2.phpt index a540dd662cfca..2e3661d50b90b 100644 --- a/ext/standard/tests/array/compact_variation2.phpt +++ b/ext/standard/tests/array/compact_variation2.phpt @@ -20,7 +20,7 @@ f(); --EXPECTF-- *** Testing compact() : usage variations - variables outside of current scope *** -Notice: compact(): Undefined variable $a in %s on line %d +Warning: compact(): Undefined variable $a in %s on line %d array(2) { ["b"]=> string(3) "f.b" @@ -28,7 +28,7 @@ array(2) { string(3) "f.c" } -Notice: compact(): Undefined variable $a in %s on line %d +Warning: compact(): Undefined variable $a in %s on line %d array(2) { ["b"]=> string(3) "f.b" diff --git a/ext/standard/tests/file/fgetcsv_variation12.phpt b/ext/standard/tests/file/fgetcsv_variation12.phpt index f1dfc52a27664..34a855c2d11da 100644 --- a/ext/standard/tests/file/fgetcsv_variation12.phpt +++ b/ext/standard/tests/file/fgetcsv_variation12.phpt @@ -88,9 +88,9 @@ echo "Done\n"; -- Testing fgetcsv() with file opened using r mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(13) ""water",fruit" @@ -100,9 +100,9 @@ bool(false) -- Testing fgetcsv() with file opened using rb mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(13) ""water",fruit" @@ -112,9 +112,9 @@ bool(false) -- Testing fgetcsv() with file opened using rt mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(13) ""water",fruit" @@ -124,9 +124,9 @@ bool(false) -- Testing fgetcsv() with file opened using r+ mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(13) ""water",fruit" @@ -136,9 +136,9 @@ bool(false) -- Testing fgetcsv() with file opened using r+b mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(13) ""water",fruit" @@ -148,9 +148,9 @@ bool(false) -- Testing fgetcsv() with file opened using r+t mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(13) ""water",fruit" @@ -160,9 +160,9 @@ bool(false) -- Testing fgetcsv() with file opened using a+ mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(13) ""water",fruit" @@ -172,9 +172,9 @@ bool(false) -- Testing fgetcsv() with file opened using a+b mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(13) ""water",fruit" @@ -184,9 +184,9 @@ bool(false) -- Testing fgetcsv() with file opened using a+t mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(13) ""water",fruit" @@ -196,9 +196,9 @@ bool(false) -- Testing fgetcsv() with file opened using r mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(15) ""water","fruit"" @@ -208,9 +208,9 @@ bool(false) -- Testing fgetcsv() with file opened using rb mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(15) ""water","fruit"" @@ -220,9 +220,9 @@ bool(false) -- Testing fgetcsv() with file opened using rt mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(15) ""water","fruit"" @@ -232,9 +232,9 @@ bool(false) -- Testing fgetcsv() with file opened using r+ mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(15) ""water","fruit"" @@ -244,9 +244,9 @@ bool(false) -- Testing fgetcsv() with file opened using r+b mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(15) ""water","fruit"" @@ -256,9 +256,9 @@ bool(false) -- Testing fgetcsv() with file opened using r+t mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(15) ""water","fruit"" @@ -268,9 +268,9 @@ bool(false) -- Testing fgetcsv() with file opened using a+ mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(15) ""water","fruit"" @@ -280,9 +280,9 @@ bool(false) -- Testing fgetcsv() with file opened using a+b mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(15) ""water","fruit"" @@ -292,9 +292,9 @@ bool(false) -- Testing fgetcsv() with file opened using a+t mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(15) ""water","fruit"" @@ -304,9 +304,9 @@ bool(false) -- Testing fgetcsv() with file opened using r mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(15) "^water^ ^fruit^" @@ -316,9 +316,9 @@ bool(false) -- Testing fgetcsv() with file opened using rb mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(15) "^water^ ^fruit^" @@ -328,9 +328,9 @@ bool(false) -- Testing fgetcsv() with file opened using rt mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(15) "^water^ ^fruit^" @@ -340,9 +340,9 @@ bool(false) -- Testing fgetcsv() with file opened using r+ mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(15) "^water^ ^fruit^" @@ -352,9 +352,9 @@ bool(false) -- Testing fgetcsv() with file opened using r+b mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(15) "^water^ ^fruit^" @@ -364,9 +364,9 @@ bool(false) -- Testing fgetcsv() with file opened using r+t mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(15) "^water^ ^fruit^" @@ -376,9 +376,9 @@ bool(false) -- Testing fgetcsv() with file opened using a+ mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(15) "^water^ ^fruit^" @@ -388,9 +388,9 @@ bool(false) -- Testing fgetcsv() with file opened using a+b mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(15) "^water^ ^fruit^" @@ -400,9 +400,9 @@ bool(false) -- Testing fgetcsv() with file opened using a+t mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(15) "^water^ ^fruit^" @@ -412,9 +412,9 @@ bool(false) -- Testing fgetcsv() with file opened using r mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(15) "&water&:&fruit&" @@ -424,9 +424,9 @@ bool(false) -- Testing fgetcsv() with file opened using rb mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(15) "&water&:&fruit&" @@ -436,9 +436,9 @@ bool(false) -- Testing fgetcsv() with file opened using rt mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(15) "&water&:&fruit&" @@ -448,9 +448,9 @@ bool(false) -- Testing fgetcsv() with file opened using r+ mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(15) "&water&:&fruit&" @@ -460,9 +460,9 @@ bool(false) -- Testing fgetcsv() with file opened using r+b mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(15) "&water&:&fruit&" @@ -472,9 +472,9 @@ bool(false) -- Testing fgetcsv() with file opened using r+t mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(15) "&water&:&fruit&" @@ -484,9 +484,9 @@ bool(false) -- Testing fgetcsv() with file opened using a+ mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(15) "&water&:&fruit&" @@ -496,9 +496,9 @@ bool(false) -- Testing fgetcsv() with file opened using a+b mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(15) "&water&:&fruit&" @@ -508,9 +508,9 @@ bool(false) -- Testing fgetcsv() with file opened using a+t mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(15) "&water&:&fruit&" @@ -520,9 +520,9 @@ bool(false) -- Testing fgetcsv() with file opened using r mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(15) "=water===fruit=" @@ -532,9 +532,9 @@ bool(false) -- Testing fgetcsv() with file opened using rb mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(15) "=water===fruit=" @@ -544,9 +544,9 @@ bool(false) -- Testing fgetcsv() with file opened using rt mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(15) "=water===fruit=" @@ -556,9 +556,9 @@ bool(false) -- Testing fgetcsv() with file opened using r+ mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(15) "=water===fruit=" @@ -568,9 +568,9 @@ bool(false) -- Testing fgetcsv() with file opened using r+b mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(15) "=water===fruit=" @@ -580,9 +580,9 @@ bool(false) -- Testing fgetcsv() with file opened using r+t mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(15) "=water===fruit=" @@ -592,9 +592,9 @@ bool(false) -- Testing fgetcsv() with file opened using a+ mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(15) "=water===fruit=" @@ -604,9 +604,9 @@ bool(false) -- Testing fgetcsv() with file opened using a+b mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(15) "=water===fruit=" @@ -616,9 +616,9 @@ bool(false) -- Testing fgetcsv() with file opened using a+t mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(15) "=water===fruit=" @@ -628,9 +628,9 @@ bool(false) -- Testing fgetcsv() with file opened using r mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(17) "-water--fruit-air" @@ -640,9 +640,9 @@ bool(false) -- Testing fgetcsv() with file opened using rb mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(17) "-water--fruit-air" @@ -652,9 +652,9 @@ bool(false) -- Testing fgetcsv() with file opened using rt mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(17) "-water--fruit-air" @@ -664,9 +664,9 @@ bool(false) -- Testing fgetcsv() with file opened using r+ mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(17) "-water--fruit-air" @@ -676,9 +676,9 @@ bool(false) -- Testing fgetcsv() with file opened using r+b mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(17) "-water--fruit-air" @@ -688,9 +688,9 @@ bool(false) -- Testing fgetcsv() with file opened using r+t mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(17) "-water--fruit-air" @@ -700,9 +700,9 @@ bool(false) -- Testing fgetcsv() with file opened using a+ mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(17) "-water--fruit-air" @@ -712,9 +712,9 @@ bool(false) -- Testing fgetcsv() with file opened using a+b mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(17) "-water--fruit-air" @@ -724,9 +724,9 @@ bool(false) -- Testing fgetcsv() with file opened using a+t mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(17) "-water--fruit-air" @@ -736,9 +736,9 @@ bool(false) -- Testing fgetcsv() with file opened using r mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(21) "-water---fruit---air-" @@ -748,9 +748,9 @@ bool(false) -- Testing fgetcsv() with file opened using rb mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(21) "-water---fruit---air-" @@ -760,9 +760,9 @@ bool(false) -- Testing fgetcsv() with file opened using rt mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(21) "-water---fruit---air-" @@ -772,9 +772,9 @@ bool(false) -- Testing fgetcsv() with file opened using r+ mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(21) "-water---fruit---air-" @@ -784,9 +784,9 @@ bool(false) -- Testing fgetcsv() with file opened using r+b mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(21) "-water---fruit---air-" @@ -796,9 +796,9 @@ bool(false) -- Testing fgetcsv() with file opened using r+t mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(21) "-water---fruit---air-" @@ -808,9 +808,9 @@ bool(false) -- Testing fgetcsv() with file opened using a+ mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(21) "-water---fruit---air-" @@ -820,9 +820,9 @@ bool(false) -- Testing fgetcsv() with file opened using a+b mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(21) "-water---fruit---air-" @@ -832,9 +832,9 @@ bool(false) -- Testing fgetcsv() with file opened using a+t mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(21) "-water---fruit---air-" @@ -844,9 +844,9 @@ bool(false) -- Testing fgetcsv() with file opened using r mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(23) "&""""&:&"&:,:":&,&:,,,," @@ -856,9 +856,9 @@ bool(false) -- Testing fgetcsv() with file opened using rb mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(23) "&""""&:&"&:,:":&,&:,,,," @@ -868,9 +868,9 @@ bool(false) -- Testing fgetcsv() with file opened using rt mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(23) "&""""&:&"&:,:":&,&:,,,," @@ -880,9 +880,9 @@ bool(false) -- Testing fgetcsv() with file opened using r+ mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(23) "&""""&:&"&:,:":&,&:,,,," @@ -892,9 +892,9 @@ bool(false) -- Testing fgetcsv() with file opened using r+b mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(23) "&""""&:&"&:,:":&,&:,,,," @@ -904,9 +904,9 @@ bool(false) -- Testing fgetcsv() with file opened using r+t mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(23) "&""""&:&"&:,:":&,&:,,,," @@ -916,9 +916,9 @@ bool(false) -- Testing fgetcsv() with file opened using a+ mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(23) "&""""&:&"&:,:":&,&:,,,," @@ -928,9 +928,9 @@ bool(false) -- Testing fgetcsv() with file opened using a+b mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(23) "&""""&:&"&:,:":&,&:,,,," @@ -940,9 +940,9 @@ bool(false) -- Testing fgetcsv() with file opened using a+t mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(23) "&""""&:&"&:,:":&,&:,,,," diff --git a/ext/standard/tests/file/fgetcsv_variation19.phpt b/ext/standard/tests/file/fgetcsv_variation19.phpt index dd5aa73567bde..bf692c7be9a25 100644 --- a/ext/standard/tests/file/fgetcsv_variation19.phpt +++ b/ext/standard/tests/file/fgetcsv_variation19.phpt @@ -86,7 +86,7 @@ echo "Done\n"; -- Testing fgetcsv() with file opened using r mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d array(1) { [0]=> string(11) "water,fruit" @@ -96,7 +96,7 @@ bool(false) -- Testing fgetcsv() with file opened using rb mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d array(1) { [0]=> string(11) "water,fruit" @@ -106,7 +106,7 @@ bool(false) -- Testing fgetcsv() with file opened using rt mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d array(1) { [0]=> string(11) "water,fruit" @@ -116,7 +116,7 @@ bool(false) -- Testing fgetcsv() with file opened using r+ mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d array(1) { [0]=> string(11) "water,fruit" @@ -126,7 +126,7 @@ bool(false) -- Testing fgetcsv() with file opened using r+b mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d array(1) { [0]=> string(11) "water,fruit" @@ -136,7 +136,7 @@ bool(false) -- Testing fgetcsv() with file opened using r+t mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d array(1) { [0]=> string(11) "water,fruit" @@ -146,7 +146,7 @@ bool(false) -- Testing fgetcsv() with file opened using a+ mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d array(1) { [0]=> string(11) "water,fruit" @@ -156,7 +156,7 @@ bool(false) -- Testing fgetcsv() with file opened using a+b mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d array(1) { [0]=> string(11) "water,fruit" @@ -166,7 +166,7 @@ bool(false) -- Testing fgetcsv() with file opened using a+t mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d array(1) { [0]=> string(11) "water,fruit" @@ -176,7 +176,7 @@ bool(false) -- Testing fgetcsv() with file opened using w+ mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d array(1) { [0]=> string(11) "water,fruit" @@ -186,7 +186,7 @@ bool(false) -- Testing fgetcsv() with file opened using w+b mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d array(1) { [0]=> string(11) "water,fruit" @@ -196,7 +196,7 @@ bool(false) -- Testing fgetcsv() with file opened using w+t mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d array(1) { [0]=> string(11) "water,fruit" @@ -206,7 +206,7 @@ bool(false) -- Testing fgetcsv() with file opened using x+ mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d array(1) { [0]=> string(11) "water,fruit" @@ -216,7 +216,7 @@ bool(false) -- Testing fgetcsv() with file opened using x+b mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d array(1) { [0]=> string(11) "water,fruit" @@ -226,7 +226,7 @@ bool(false) -- Testing fgetcsv() with file opened using x+t mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d array(1) { [0]=> string(11) "water,fruit" @@ -236,7 +236,7 @@ bool(false) -- Testing fgetcsv() with file opened using r mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d array(1) { [0]=> string(11) "water fruit" @@ -246,7 +246,7 @@ bool(false) -- Testing fgetcsv() with file opened using rb mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d array(1) { [0]=> string(11) "water fruit" @@ -256,7 +256,7 @@ bool(false) -- Testing fgetcsv() with file opened using rt mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d array(1) { [0]=> string(11) "water fruit" @@ -266,7 +266,7 @@ bool(false) -- Testing fgetcsv() with file opened using r+ mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d array(1) { [0]=> string(11) "water fruit" @@ -276,7 +276,7 @@ bool(false) -- Testing fgetcsv() with file opened using r+b mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d array(1) { [0]=> string(11) "water fruit" @@ -286,7 +286,7 @@ bool(false) -- Testing fgetcsv() with file opened using r+t mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d array(1) { [0]=> string(11) "water fruit" @@ -296,7 +296,7 @@ bool(false) -- Testing fgetcsv() with file opened using a+ mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d array(1) { [0]=> string(11) "water fruit" @@ -306,7 +306,7 @@ bool(false) -- Testing fgetcsv() with file opened using a+b mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d array(1) { [0]=> string(11) "water fruit" @@ -316,7 +316,7 @@ bool(false) -- Testing fgetcsv() with file opened using a+t mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d array(1) { [0]=> string(11) "water fruit" @@ -326,7 +326,7 @@ bool(false) -- Testing fgetcsv() with file opened using w+ mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d array(1) { [0]=> string(11) "water fruit" @@ -336,7 +336,7 @@ bool(false) -- Testing fgetcsv() with file opened using w+b mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d array(1) { [0]=> string(11) "water fruit" @@ -346,7 +346,7 @@ bool(false) -- Testing fgetcsv() with file opened using w+t mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d array(1) { [0]=> string(11) "water fruit" @@ -356,7 +356,7 @@ bool(false) -- Testing fgetcsv() with file opened using x+ mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d array(1) { [0]=> string(11) "water fruit" @@ -366,7 +366,7 @@ bool(false) -- Testing fgetcsv() with file opened using x+b mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d array(1) { [0]=> string(11) "water fruit" @@ -376,7 +376,7 @@ bool(false) -- Testing fgetcsv() with file opened using x+t mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d array(1) { [0]=> string(11) "water fruit" @@ -386,7 +386,7 @@ bool(false) -- Testing fgetcsv() with file opened using r mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d array(1) { [0]=> string(13) "water "fruit"" @@ -396,7 +396,7 @@ bool(false) -- Testing fgetcsv() with file opened using rb mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d array(1) { [0]=> string(13) "water "fruit"" @@ -406,7 +406,7 @@ bool(false) -- Testing fgetcsv() with file opened using rt mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d array(1) { [0]=> string(13) "water "fruit"" @@ -416,7 +416,7 @@ bool(false) -- Testing fgetcsv() with file opened using r+ mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d array(1) { [0]=> string(13) "water "fruit"" @@ -426,7 +426,7 @@ bool(false) -- Testing fgetcsv() with file opened using r+b mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d array(1) { [0]=> string(13) "water "fruit"" @@ -436,7 +436,7 @@ bool(false) -- Testing fgetcsv() with file opened using r+t mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d array(1) { [0]=> string(13) "water "fruit"" @@ -446,7 +446,7 @@ bool(false) -- Testing fgetcsv() with file opened using a+ mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d array(1) { [0]=> string(13) "water "fruit"" @@ -456,7 +456,7 @@ bool(false) -- Testing fgetcsv() with file opened using a+b mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d array(1) { [0]=> string(13) "water "fruit"" @@ -466,7 +466,7 @@ bool(false) -- Testing fgetcsv() with file opened using a+t mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d array(1) { [0]=> string(13) "water "fruit"" @@ -476,7 +476,7 @@ bool(false) -- Testing fgetcsv() with file opened using w+ mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d array(1) { [0]=> string(13) "water "fruit"" @@ -486,7 +486,7 @@ bool(false) -- Testing fgetcsv() with file opened using w+b mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d array(1) { [0]=> string(13) "water "fruit"" @@ -496,7 +496,7 @@ bool(false) -- Testing fgetcsv() with file opened using w+t mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d array(1) { [0]=> string(13) "water "fruit"" @@ -506,7 +506,7 @@ bool(false) -- Testing fgetcsv() with file opened using x+ mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d array(1) { [0]=> string(13) "water "fruit"" @@ -516,7 +516,7 @@ bool(false) -- Testing fgetcsv() with file opened using x+b mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d array(1) { [0]=> string(13) "water "fruit"" @@ -526,7 +526,7 @@ bool(false) -- Testing fgetcsv() with file opened using x+t mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d array(1) { [0]=> string(13) "water "fruit"" @@ -536,7 +536,7 @@ bool(false) -- Testing fgetcsv() with file opened using r mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d array(1) { [0]=> string(19) "water\"fruit"\"air"" @@ -546,7 +546,7 @@ bool(false) -- Testing fgetcsv() with file opened using rb mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d array(1) { [0]=> string(19) "water\"fruit"\"air"" @@ -556,7 +556,7 @@ bool(false) -- Testing fgetcsv() with file opened using rt mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d array(1) { [0]=> string(19) "water\"fruit"\"air"" @@ -566,7 +566,7 @@ bool(false) -- Testing fgetcsv() with file opened using r+ mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d array(1) { [0]=> string(19) "water\"fruit"\"air"" @@ -576,7 +576,7 @@ bool(false) -- Testing fgetcsv() with file opened using r+b mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d array(1) { [0]=> string(19) "water\"fruit"\"air"" @@ -586,7 +586,7 @@ bool(false) -- Testing fgetcsv() with file opened using r+t mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d array(1) { [0]=> string(19) "water\"fruit"\"air"" @@ -596,7 +596,7 @@ bool(false) -- Testing fgetcsv() with file opened using a+ mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d array(1) { [0]=> string(19) "water\"fruit"\"air"" @@ -606,7 +606,7 @@ bool(false) -- Testing fgetcsv() with file opened using a+b mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d array(1) { [0]=> string(19) "water\"fruit"\"air"" @@ -616,7 +616,7 @@ bool(false) -- Testing fgetcsv() with file opened using a+t mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d array(1) { [0]=> string(19) "water\"fruit"\"air"" @@ -626,7 +626,7 @@ bool(false) -- Testing fgetcsv() with file opened using w+ mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d array(1) { [0]=> string(19) "water\"fruit"\"air"" @@ -636,7 +636,7 @@ bool(false) -- Testing fgetcsv() with file opened using w+b mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d array(1) { [0]=> string(19) "water\"fruit"\"air"" @@ -646,7 +646,7 @@ bool(false) -- Testing fgetcsv() with file opened using w+t mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d array(1) { [0]=> string(19) "water\"fruit"\"air"" @@ -656,7 +656,7 @@ bool(false) -- Testing fgetcsv() with file opened using x+ mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d array(1) { [0]=> string(19) "water\"fruit"\"air"" @@ -666,7 +666,7 @@ bool(false) -- Testing fgetcsv() with file opened using x+b mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d array(1) { [0]=> string(19) "water\"fruit"\"air"" @@ -676,7 +676,7 @@ bool(false) -- Testing fgetcsv() with file opened using x+t mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d array(1) { [0]=> string(19) "water\"fruit"\"air"" @@ -686,7 +686,7 @@ bool(false) -- Testing fgetcsv() with file opened using r mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d array(1) { [0]=> string(17) "water\"fruit"\"""" @@ -696,7 +696,7 @@ bool(false) -- Testing fgetcsv() with file opened using rb mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d array(1) { [0]=> string(17) "water\"fruit"\"""" @@ -706,7 +706,7 @@ bool(false) -- Testing fgetcsv() with file opened using rt mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d array(1) { [0]=> string(17) "water\"fruit"\"""" @@ -716,7 +716,7 @@ bool(false) -- Testing fgetcsv() with file opened using r+ mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d array(1) { [0]=> string(17) "water\"fruit"\"""" @@ -726,7 +726,7 @@ bool(false) -- Testing fgetcsv() with file opened using r+b mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d array(1) { [0]=> string(17) "water\"fruit"\"""" @@ -736,7 +736,7 @@ bool(false) -- Testing fgetcsv() with file opened using r+t mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d array(1) { [0]=> string(17) "water\"fruit"\"""" @@ -746,7 +746,7 @@ bool(false) -- Testing fgetcsv() with file opened using a+ mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d array(1) { [0]=> string(17) "water\"fruit"\"""" @@ -756,7 +756,7 @@ bool(false) -- Testing fgetcsv() with file opened using a+b mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d array(1) { [0]=> string(17) "water\"fruit"\"""" @@ -766,7 +766,7 @@ bool(false) -- Testing fgetcsv() with file opened using a+t mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d array(1) { [0]=> string(17) "water\"fruit"\"""" @@ -776,7 +776,7 @@ bool(false) -- Testing fgetcsv() with file opened using w+ mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d array(1) { [0]=> string(17) "water\"fruit"\"""" @@ -786,7 +786,7 @@ bool(false) -- Testing fgetcsv() with file opened using w+b mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d array(1) { [0]=> string(17) "water\"fruit"\"""" @@ -796,7 +796,7 @@ bool(false) -- Testing fgetcsv() with file opened using w+t mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d array(1) { [0]=> string(17) "water\"fruit"\"""" @@ -806,7 +806,7 @@ bool(false) -- Testing fgetcsv() with file opened using x+ mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d array(1) { [0]=> string(17) "water\"fruit"\"""" @@ -816,7 +816,7 @@ bool(false) -- Testing fgetcsv() with file opened using x+b mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d array(1) { [0]=> string(17) "water\"fruit"\"""" @@ -826,7 +826,7 @@ bool(false) -- Testing fgetcsv() with file opened using x+t mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d array(1) { [0]=> string(17) "water\"fruit"\"""" diff --git a/ext/standard/tests/file/fgetcsv_variation24.phpt b/ext/standard/tests/file/fgetcsv_variation24.phpt index f99ccd62d8159..1a6ef177523fa 100644 --- a/ext/standard/tests/file/fgetcsv_variation24.phpt +++ b/ext/standard/tests/file/fgetcsv_variation24.phpt @@ -90,9 +90,9 @@ echo "Done\n"; -- Testing fgetcsv() with file opened using w+ mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(13) ""water",fruit" @@ -102,9 +102,9 @@ bool(false) -- Testing fgetcsv() with file opened using w+b mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(13) ""water",fruit" @@ -114,9 +114,9 @@ bool(false) -- Testing fgetcsv() with file opened using w+t mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(13) ""water",fruit" @@ -126,9 +126,9 @@ bool(false) -- Testing fgetcsv() with file opened using x+ mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(13) ""water",fruit" @@ -138,9 +138,9 @@ bool(false) -- Testing fgetcsv() with file opened using x+b mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(13) ""water",fruit" @@ -150,9 +150,9 @@ bool(false) -- Testing fgetcsv() with file opened using x+t mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(13) ""water",fruit" @@ -162,9 +162,9 @@ bool(false) -- Testing fgetcsv() with file opened using w+ mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(15) ""water","fruit"" @@ -174,9 +174,9 @@ bool(false) -- Testing fgetcsv() with file opened using w+b mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(15) ""water","fruit"" @@ -186,9 +186,9 @@ bool(false) -- Testing fgetcsv() with file opened using w+t mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(15) ""water","fruit"" @@ -198,9 +198,9 @@ bool(false) -- Testing fgetcsv() with file opened using x+ mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(15) ""water","fruit"" @@ -210,9 +210,9 @@ bool(false) -- Testing fgetcsv() with file opened using x+b mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(15) ""water","fruit"" @@ -222,9 +222,9 @@ bool(false) -- Testing fgetcsv() with file opened using x+t mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(15) ""water","fruit"" @@ -234,9 +234,9 @@ bool(false) -- Testing fgetcsv() with file opened using w+ mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(15) "^water^ ^fruit^" @@ -246,9 +246,9 @@ bool(false) -- Testing fgetcsv() with file opened using w+b mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(15) "^water^ ^fruit^" @@ -258,9 +258,9 @@ bool(false) -- Testing fgetcsv() with file opened using w+t mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(15) "^water^ ^fruit^" @@ -270,9 +270,9 @@ bool(false) -- Testing fgetcsv() with file opened using x+ mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(15) "^water^ ^fruit^" @@ -282,9 +282,9 @@ bool(false) -- Testing fgetcsv() with file opened using x+b mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(15) "^water^ ^fruit^" @@ -294,9 +294,9 @@ bool(false) -- Testing fgetcsv() with file opened using x+t mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(15) "^water^ ^fruit^" @@ -306,9 +306,9 @@ bool(false) -- Testing fgetcsv() with file opened using w+ mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(15) "&water&:&fruit&" @@ -318,9 +318,9 @@ bool(false) -- Testing fgetcsv() with file opened using w+b mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(15) "&water&:&fruit&" @@ -330,9 +330,9 @@ bool(false) -- Testing fgetcsv() with file opened using w+t mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(15) "&water&:&fruit&" @@ -342,9 +342,9 @@ bool(false) -- Testing fgetcsv() with file opened using x+ mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(15) "&water&:&fruit&" @@ -354,9 +354,9 @@ bool(false) -- Testing fgetcsv() with file opened using x+b mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(15) "&water&:&fruit&" @@ -366,9 +366,9 @@ bool(false) -- Testing fgetcsv() with file opened using x+t mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(15) "&water&:&fruit&" @@ -378,9 +378,9 @@ bool(false) -- Testing fgetcsv() with file opened using w+ mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(15) "=water===fruit=" @@ -390,9 +390,9 @@ bool(false) -- Testing fgetcsv() with file opened using w+b mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(15) "=water===fruit=" @@ -402,9 +402,9 @@ bool(false) -- Testing fgetcsv() with file opened using w+t mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(15) "=water===fruit=" @@ -414,9 +414,9 @@ bool(false) -- Testing fgetcsv() with file opened using x+ mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(15) "=water===fruit=" @@ -426,9 +426,9 @@ bool(false) -- Testing fgetcsv() with file opened using x+b mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(15) "=water===fruit=" @@ -438,9 +438,9 @@ bool(false) -- Testing fgetcsv() with file opened using x+t mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(15) "=water===fruit=" @@ -450,9 +450,9 @@ bool(false) -- Testing fgetcsv() with file opened using w+ mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(17) "-water--fruit-air" @@ -462,9 +462,9 @@ bool(false) -- Testing fgetcsv() with file opened using w+b mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(17) "-water--fruit-air" @@ -474,9 +474,9 @@ bool(false) -- Testing fgetcsv() with file opened using w+t mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(17) "-water--fruit-air" @@ -486,9 +486,9 @@ bool(false) -- Testing fgetcsv() with file opened using x+ mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(17) "-water--fruit-air" @@ -498,9 +498,9 @@ bool(false) -- Testing fgetcsv() with file opened using x+b mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(17) "-water--fruit-air" @@ -510,9 +510,9 @@ bool(false) -- Testing fgetcsv() with file opened using x+t mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(17) "-water--fruit-air" @@ -522,9 +522,9 @@ bool(false) -- Testing fgetcsv() with file opened using w+ mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(21) "-water---fruit---air-" @@ -534,9 +534,9 @@ bool(false) -- Testing fgetcsv() with file opened using w+b mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(21) "-water---fruit---air-" @@ -546,9 +546,9 @@ bool(false) -- Testing fgetcsv() with file opened using w+t mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(21) "-water---fruit---air-" @@ -558,9 +558,9 @@ bool(false) -- Testing fgetcsv() with file opened using x+ mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(21) "-water---fruit---air-" @@ -570,9 +570,9 @@ bool(false) -- Testing fgetcsv() with file opened using x+b mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(21) "-water---fruit---air-" @@ -582,9 +582,9 @@ bool(false) -- Testing fgetcsv() with file opened using x+t mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(21) "-water---fruit---air-" @@ -594,9 +594,9 @@ bool(false) -- Testing fgetcsv() with file opened using w+ mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(23) "&""""&:&"&:,:":&,&:,,,," @@ -606,9 +606,9 @@ bool(false) -- Testing fgetcsv() with file opened using w+b mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(23) "&""""&:&"&:,:":&,&:,,,," @@ -618,9 +618,9 @@ bool(false) -- Testing fgetcsv() with file opened using w+t mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(23) "&""""&:&"&:,:":&,&:,,,," @@ -630,9 +630,9 @@ bool(false) -- Testing fgetcsv() with file opened using x+ mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(23) "&""""&:&"&:,:":&,&:,,,," @@ -642,9 +642,9 @@ bool(false) -- Testing fgetcsv() with file opened using x+b mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(23) "&""""&:&"&:,:":&,&:,,,," @@ -654,9 +654,9 @@ bool(false) -- Testing fgetcsv() with file opened using x+t mode -- -Notice: fgetcsv(): delimiter must be a single character in %s on line %d +Warning: fgetcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fgetcsv(): enclosure must be a single character in %s on line %d +Warning: fgetcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d array(1) { [0]=> string(23) "&""""&:&"&:,:":&,&:,,,," diff --git a/ext/standard/tests/file/fputcsv_variation13.phpt b/ext/standard/tests/file/fputcsv_variation13.phpt index eb2746790bff7..7c1d71093ee7e 100644 --- a/ext/standard/tests/file/fputcsv_variation13.phpt +++ b/ext/standard/tests/file/fputcsv_variation13.phpt @@ -73,7 +73,7 @@ echo "Done\n"; -- file opened in r+ -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(12) int(12) bool(false) @@ -82,7 +82,7 @@ string(12) "water,fruit -- file opened in r+b -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(12) int(12) bool(false) @@ -91,7 +91,7 @@ string(12) "water,fruit -- file opened in r+t -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(12) int(12) bool(false) @@ -100,7 +100,7 @@ string(%d) "water,fruit -- file opened in a+ -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(12) int(12) bool(false) @@ -109,7 +109,7 @@ string(12) "water,fruit -- file opened in a+b -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(12) int(12) bool(false) @@ -118,7 +118,7 @@ string(12) "water,fruit -- file opened in a+t -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(12) int(12) bool(false) @@ -127,7 +127,7 @@ string(%d) "water,fruit -- file opened in w+ -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(12) int(12) bool(false) @@ -136,7 +136,7 @@ string(12) "water,fruit -- file opened in w+b -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(12) int(12) bool(false) @@ -145,7 +145,7 @@ string(12) "water,fruit -- file opened in w+t -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(12) int(12) bool(false) @@ -154,7 +154,7 @@ string(%d) "water,fruit -- file opened in x+ -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(12) int(12) bool(false) @@ -163,7 +163,7 @@ string(12) "water,fruit -- file opened in x+b -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(12) int(12) bool(false) @@ -172,7 +172,7 @@ string(12) "water,fruit -- file opened in x+t -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(12) int(12) bool(false) @@ -181,7 +181,7 @@ string(%d) "water,fruit -- file opened in r+ -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(20) int(20) bool(false) @@ -190,7 +190,7 @@ string(20) """"water"",""fruit" -- file opened in r+b -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(20) int(20) bool(false) @@ -199,7 +199,7 @@ string(20) """"water"",""fruit" -- file opened in r+t -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(20) int(20) bool(false) @@ -208,7 +208,7 @@ string(%d) """"water"",""fruit" -- file opened in a+ -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(20) int(20) bool(false) @@ -217,7 +217,7 @@ string(20) """"water"",""fruit" -- file opened in a+b -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(20) int(20) bool(false) @@ -226,7 +226,7 @@ string(20) """"water"",""fruit" -- file opened in a+t -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(20) int(20) bool(false) @@ -235,7 +235,7 @@ string(%d) """"water"",""fruit" -- file opened in w+ -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(20) int(20) bool(false) @@ -244,7 +244,7 @@ string(20) """"water"",""fruit" -- file opened in w+b -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(20) int(20) bool(false) @@ -253,7 +253,7 @@ string(20) """"water"",""fruit" -- file opened in w+t -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(20) int(20) bool(false) @@ -262,7 +262,7 @@ string(%d) """"water"",""fruit" -- file opened in x+ -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(20) int(20) bool(false) @@ -271,7 +271,7 @@ string(20) """"water"",""fruit" -- file opened in x+b -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(20) int(20) bool(false) @@ -280,7 +280,7 @@ string(20) """"water"",""fruit" -- file opened in x+t -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(20) int(20) bool(false) @@ -289,7 +289,7 @@ string(%d) """"water"",""fruit" -- file opened in r+ -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(22) int(22) bool(false) @@ -298,7 +298,7 @@ string(22) """"water"",""fruit""" -- file opened in r+b -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(22) int(22) bool(false) @@ -307,7 +307,7 @@ string(22) """"water"",""fruit""" -- file opened in r+t -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(22) int(22) bool(false) @@ -316,7 +316,7 @@ string(%d) """"water"",""fruit""" -- file opened in a+ -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(22) int(22) bool(false) @@ -325,7 +325,7 @@ string(22) """"water"",""fruit""" -- file opened in a+b -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(22) int(22) bool(false) @@ -334,7 +334,7 @@ string(22) """"water"",""fruit""" -- file opened in a+t -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(22) int(22) bool(false) @@ -343,7 +343,7 @@ string(%d) """"water"",""fruit""" -- file opened in w+ -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(22) int(22) bool(false) @@ -352,7 +352,7 @@ string(22) """"water"",""fruit""" -- file opened in w+b -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(22) int(22) bool(false) @@ -361,7 +361,7 @@ string(22) """"water"",""fruit""" -- file opened in w+t -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(22) int(22) bool(false) @@ -370,7 +370,7 @@ string(%d) """"water"",""fruit""" -- file opened in x+ -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(22) int(22) bool(false) @@ -379,7 +379,7 @@ string(22) """"water"",""fruit""" -- file opened in x+b -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(22) int(22) bool(false) @@ -388,7 +388,7 @@ string(22) """"water"",""fruit""" -- file opened in x+t -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(22) int(22) bool(false) @@ -397,7 +397,7 @@ string(%d) """"water"",""fruit""" -- file opened in r+ -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(18) int(18) bool(false) @@ -406,7 +406,7 @@ string(18) ""^water^ ^fruit^" -- file opened in r+b -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(18) int(18) bool(false) @@ -415,7 +415,7 @@ string(18) ""^water^ ^fruit^" -- file opened in r+t -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(18) int(18) bool(false) @@ -424,7 +424,7 @@ string(%d) ""^water^ ^fruit^" -- file opened in a+ -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(18) int(18) bool(false) @@ -433,7 +433,7 @@ string(18) ""^water^ ^fruit^" -- file opened in a+b -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(18) int(18) bool(false) @@ -442,7 +442,7 @@ string(18) ""^water^ ^fruit^" -- file opened in a+t -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(18) int(18) bool(false) @@ -451,7 +451,7 @@ string(%d) ""^water^ ^fruit^" -- file opened in w+ -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(18) int(18) bool(false) @@ -460,7 +460,7 @@ string(18) ""^water^ ^fruit^" -- file opened in w+b -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(18) int(18) bool(false) @@ -469,7 +469,7 @@ string(18) ""^water^ ^fruit^" -- file opened in w+t -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(18) int(18) bool(false) @@ -478,7 +478,7 @@ string(%d) ""^water^ ^fruit^" -- file opened in x+ -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(18) int(18) bool(false) @@ -487,7 +487,7 @@ string(18) ""^water^ ^fruit^" -- file opened in x+b -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(18) int(18) bool(false) @@ -496,7 +496,7 @@ string(18) ""^water^ ^fruit^" -- file opened in x+t -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(18) int(18) bool(false) @@ -505,7 +505,7 @@ string(%d) ""^water^ ^fruit^" -- file opened in r+ -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(16) int(16) bool(false) @@ -514,7 +514,7 @@ string(16) "&water&:&fruit& -- file opened in r+b -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(16) int(16) bool(false) @@ -523,7 +523,7 @@ string(16) "&water&:&fruit& -- file opened in r+t -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(16) int(16) bool(false) @@ -532,7 +532,7 @@ string(%d) "&water&:&fruit& -- file opened in a+ -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(16) int(16) bool(false) @@ -541,7 +541,7 @@ string(16) "&water&:&fruit& -- file opened in a+b -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(16) int(16) bool(false) @@ -550,7 +550,7 @@ string(16) "&water&:&fruit& -- file opened in a+t -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(16) int(16) bool(false) @@ -559,7 +559,7 @@ string(%d) "&water&:&fruit& -- file opened in w+ -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(16) int(16) bool(false) @@ -568,7 +568,7 @@ string(16) "&water&:&fruit& -- file opened in w+b -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(16) int(16) bool(false) @@ -577,7 +577,7 @@ string(16) "&water&:&fruit& -- file opened in w+t -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(16) int(16) bool(false) @@ -586,7 +586,7 @@ string(%d) "&water&:&fruit& -- file opened in x+ -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(16) int(16) bool(false) @@ -595,7 +595,7 @@ string(16) "&water&:&fruit& -- file opened in x+b -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(16) int(16) bool(false) @@ -604,7 +604,7 @@ string(16) "&water&:&fruit& -- file opened in x+t -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(16) int(16) bool(false) @@ -613,7 +613,7 @@ string(%d) "&water&:&fruit& -- file opened in r+ -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(16) int(16) bool(false) @@ -622,7 +622,7 @@ string(16) "=water===fruit= -- file opened in r+b -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(16) int(16) bool(false) @@ -631,7 +631,7 @@ string(16) "=water===fruit= -- file opened in r+t -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(16) int(16) bool(false) @@ -640,7 +640,7 @@ string(%d) "=water===fruit= -- file opened in a+ -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(16) int(16) bool(false) @@ -649,7 +649,7 @@ string(16) "=water===fruit= -- file opened in a+b -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(16) int(16) bool(false) @@ -658,7 +658,7 @@ string(16) "=water===fruit= -- file opened in a+t -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(16) int(16) bool(false) @@ -667,7 +667,7 @@ string(%d) "=water===fruit= -- file opened in w+ -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(16) int(16) bool(false) @@ -676,7 +676,7 @@ string(16) "=water===fruit= -- file opened in w+b -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(16) int(16) bool(false) @@ -685,7 +685,7 @@ string(16) "=water===fruit= -- file opened in w+t -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(16) int(16) bool(false) @@ -694,7 +694,7 @@ string(%d) "=water===fruit= -- file opened in x+ -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(16) int(16) bool(false) @@ -703,7 +703,7 @@ string(16) "=water===fruit= -- file opened in x+b -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(16) int(16) bool(false) @@ -712,7 +712,7 @@ string(16) "=water===fruit= -- file opened in x+t -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(16) int(16) bool(false) @@ -721,7 +721,7 @@ string(%d) "=water===fruit= -- file opened in r+ -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(18) int(18) bool(false) @@ -730,7 +730,7 @@ string(18) "-water--fruit-air -- file opened in r+b -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(18) int(18) bool(false) @@ -739,7 +739,7 @@ string(18) "-water--fruit-air -- file opened in r+t -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(18) int(18) bool(false) @@ -748,7 +748,7 @@ string(%d) "-water--fruit-air -- file opened in a+ -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(18) int(18) bool(false) @@ -757,7 +757,7 @@ string(18) "-water--fruit-air -- file opened in a+b -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(18) int(18) bool(false) @@ -766,7 +766,7 @@ string(18) "-water--fruit-air -- file opened in a+t -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(18) int(18) bool(false) @@ -775,7 +775,7 @@ string(%d) "-water--fruit-air -- file opened in w+ -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(18) int(18) bool(false) @@ -784,7 +784,7 @@ string(18) "-water--fruit-air -- file opened in w+b -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(18) int(18) bool(false) @@ -793,7 +793,7 @@ string(18) "-water--fruit-air -- file opened in w+t -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(18) int(18) bool(false) @@ -802,7 +802,7 @@ string(%d) "-water--fruit-air -- file opened in x+ -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(18) int(18) bool(false) @@ -811,7 +811,7 @@ string(18) "-water--fruit-air -- file opened in x+b -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(18) int(18) bool(false) @@ -820,7 +820,7 @@ string(18) "-water--fruit-air -- file opened in x+t -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(18) int(18) bool(false) @@ -829,7 +829,7 @@ string(%d) "-water--fruit-air -- file opened in r+ -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(22) int(22) bool(false) @@ -838,7 +838,7 @@ string(22) "-water---fruit---air- -- file opened in r+b -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(22) int(22) bool(false) @@ -847,7 +847,7 @@ string(22) "-water---fruit---air- -- file opened in r+t -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(22) int(22) bool(false) @@ -856,7 +856,7 @@ string(%d) "-water---fruit---air- -- file opened in a+ -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(22) int(22) bool(false) @@ -865,7 +865,7 @@ string(22) "-water---fruit---air- -- file opened in a+b -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(22) int(22) bool(false) @@ -874,7 +874,7 @@ string(22) "-water---fruit---air- -- file opened in a+t -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(22) int(22) bool(false) @@ -883,7 +883,7 @@ string(%d) "-water---fruit---air- -- file opened in w+ -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(22) int(22) bool(false) @@ -892,7 +892,7 @@ string(22) "-water---fruit---air- -- file opened in w+b -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(22) int(22) bool(false) @@ -901,7 +901,7 @@ string(22) "-water---fruit---air- -- file opened in w+t -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(22) int(22) bool(false) @@ -910,7 +910,7 @@ string(%d) "-water---fruit---air- -- file opened in x+ -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(22) int(22) bool(false) @@ -919,7 +919,7 @@ string(22) "-water---fruit---air- -- file opened in x+b -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(22) int(22) bool(false) @@ -928,7 +928,7 @@ string(22) "-water---fruit---air- -- file opened in x+t -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(22) int(22) bool(false) @@ -937,7 +937,7 @@ string(%d) "-water---fruit---air- -- file opened in r+ -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(32) int(32) bool(false) @@ -946,7 +946,7 @@ string(32) ""&""""""""&:&""&:,:"":&,&:,,,," -- file opened in r+b -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(32) int(32) bool(false) @@ -955,7 +955,7 @@ string(32) ""&""""""""&:&""&:,:"":&,&:,,,," -- file opened in r+t -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(32) int(32) bool(false) @@ -964,7 +964,7 @@ string(%d) ""&""""""""&:&""&:,:"":&,&:,,,," -- file opened in a+ -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(32) int(32) bool(false) @@ -973,7 +973,7 @@ string(32) ""&""""""""&:&""&:,:"":&,&:,,,," -- file opened in a+b -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(32) int(32) bool(false) @@ -982,7 +982,7 @@ string(32) ""&""""""""&:&""&:,:"":&,&:,,,," -- file opened in a+t -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(32) int(32) bool(false) @@ -991,7 +991,7 @@ string(%d) ""&""""""""&:&""&:,:"":&,&:,,,," -- file opened in w+ -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(32) int(32) bool(false) @@ -1000,7 +1000,7 @@ string(32) ""&""""""""&:&""&:,:"":&,&:,,,," -- file opened in w+b -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(32) int(32) bool(false) @@ -1009,7 +1009,7 @@ string(32) ""&""""""""&:&""&:,:"":&,&:,,,," -- file opened in w+t -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(32) int(32) bool(false) @@ -1018,7 +1018,7 @@ string(%d) ""&""""""""&:&""&:,:"":&,&:,,,," -- file opened in x+ -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(32) int(32) bool(false) @@ -1027,7 +1027,7 @@ string(32) ""&""""""""&:&""&:,:"":&,&:,,,," -- file opened in x+b -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(32) int(32) bool(false) @@ -1036,7 +1036,7 @@ string(32) ""&""""""""&:&""&:,:"":&,&:,,,," -- file opened in x+t -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d int(32) int(32) bool(false) diff --git a/ext/standard/tests/file/fputcsv_variation14.phpt b/ext/standard/tests/file/fputcsv_variation14.phpt index e5e98c5ce2665..5c4c669e7f562 100644 --- a/ext/standard/tests/file/fputcsv_variation14.phpt +++ b/ext/standard/tests/file/fputcsv_variation14.phpt @@ -81,9 +81,9 @@ echo "Done\n"; -- file opened in r -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d Notice: fputcsv(): Write of 12 bytes failed with errno=9 Bad file descriptor in %s on line %d bool(false) @@ -93,9 +93,9 @@ string(0) "" -- file opened in rb -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d Notice: fputcsv(): Write of 12 bytes failed with errno=9 Bad file descriptor in %s on line %d bool(false) @@ -105,9 +105,9 @@ string(0) "" -- file opened in rt -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d Notice: fputcsv(): Write of 12 bytes failed with errno=9 Bad file descriptor in %s on line %d bool(false) @@ -117,9 +117,9 @@ string(0) "" -- file opened in r -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d Notice: fputcsv(): Write of 15 bytes failed with errno=9 Bad file descriptor in %s on line %d bool(false) @@ -129,9 +129,9 @@ string(0) "" -- file opened in rb -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d Notice: fputcsv(): Write of 15 bytes failed with errno=9 Bad file descriptor in %s on line %d bool(false) @@ -141,9 +141,9 @@ string(0) "" -- file opened in rt -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d Notice: fputcsv(): Write of 15 bytes failed with errno=9 Bad file descriptor in %s on line %d bool(false) @@ -153,9 +153,9 @@ string(0) "" -- file opened in r -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d Notice: fputcsv(): Write of 16 bytes failed with errno=9 Bad file descriptor in %s on line %d bool(false) @@ -165,9 +165,9 @@ string(0) "" -- file opened in rb -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d Notice: fputcsv(): Write of 16 bytes failed with errno=9 Bad file descriptor in %s on line %d bool(false) @@ -177,9 +177,9 @@ string(0) "" -- file opened in rt -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d Notice: fputcsv(): Write of 16 bytes failed with errno=9 Bad file descriptor in %s on line %d bool(false) @@ -189,9 +189,9 @@ string(0) "" -- file opened in r -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d Notice: fputcsv(): Write of 18 bytes failed with errno=9 Bad file descriptor in %s on line %d bool(false) @@ -201,9 +201,9 @@ string(0) "" -- file opened in rb -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d Notice: fputcsv(): Write of 18 bytes failed with errno=9 Bad file descriptor in %s on line %d bool(false) @@ -213,9 +213,9 @@ string(0) "" -- file opened in rt -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d Notice: fputcsv(): Write of 18 bytes failed with errno=9 Bad file descriptor in %s on line %d bool(false) @@ -225,9 +225,9 @@ string(0) "" -- file opened in r -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d Notice: fputcsv(): Write of 16 bytes failed with errno=9 Bad file descriptor in %s on line %d bool(false) @@ -237,9 +237,9 @@ string(0) "" -- file opened in rb -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d Notice: fputcsv(): Write of 16 bytes failed with errno=9 Bad file descriptor in %s on line %d bool(false) @@ -249,9 +249,9 @@ string(0) "" -- file opened in rt -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d Notice: fputcsv(): Write of 16 bytes failed with errno=9 Bad file descriptor in %s on line %d bool(false) @@ -261,9 +261,9 @@ string(0) "" -- file opened in r -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d Notice: fputcsv(): Write of 16 bytes failed with errno=9 Bad file descriptor in %s on line %d bool(false) @@ -273,9 +273,9 @@ string(0) "" -- file opened in rb -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d Notice: fputcsv(): Write of 16 bytes failed with errno=9 Bad file descriptor in %s on line %d bool(false) @@ -285,9 +285,9 @@ string(0) "" -- file opened in rt -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d Notice: fputcsv(): Write of 16 bytes failed with errno=9 Bad file descriptor in %s on line %d bool(false) @@ -297,9 +297,9 @@ string(0) "" -- file opened in r -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d Notice: fputcsv(): Write of 18 bytes failed with errno=9 Bad file descriptor in %s on line %d bool(false) @@ -309,9 +309,9 @@ string(0) "" -- file opened in rb -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d Notice: fputcsv(): Write of 18 bytes failed with errno=9 Bad file descriptor in %s on line %d bool(false) @@ -321,9 +321,9 @@ string(0) "" -- file opened in rt -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d Notice: fputcsv(): Write of 18 bytes failed with errno=9 Bad file descriptor in %s on line %d bool(false) @@ -333,9 +333,9 @@ string(0) "" -- file opened in r -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d Notice: fputcsv(): Write of 22 bytes failed with errno=9 Bad file descriptor in %s on line %d bool(false) @@ -345,9 +345,9 @@ string(0) "" -- file opened in rb -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d Notice: fputcsv(): Write of 22 bytes failed with errno=9 Bad file descriptor in %s on line %d bool(false) @@ -357,9 +357,9 @@ string(0) "" -- file opened in rt -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d Notice: fputcsv(): Write of 22 bytes failed with errno=9 Bad file descriptor in %s on line %d bool(false) @@ -369,9 +369,9 @@ string(0) "" -- file opened in r -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d Notice: fputcsv(): Write of 24 bytes failed with errno=9 Bad file descriptor in %s on line %d bool(false) @@ -381,9 +381,9 @@ string(0) "" -- file opened in rb -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d Notice: fputcsv(): Write of 24 bytes failed with errno=9 Bad file descriptor in %s on line %d bool(false) @@ -393,9 +393,9 @@ string(0) "" -- file opened in rt -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d Notice: fputcsv(): Write of 24 bytes failed with errno=9 Bad file descriptor in %s on line %d bool(false) diff --git a/ext/standard/tests/file/fputcsv_variation9.phpt b/ext/standard/tests/file/fputcsv_variation9.phpt index e030c41bd2057..957fb9966f38e 100644 --- a/ext/standard/tests/file/fputcsv_variation9.phpt +++ b/ext/standard/tests/file/fputcsv_variation9.phpt @@ -73,9 +73,9 @@ echo "Done\n"; -- file opened in r+ -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(12) int(12) bool(false) @@ -84,9 +84,9 @@ string(12) "water,fruit -- file opened in r+b -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(12) int(12) bool(false) @@ -95,9 +95,9 @@ string(12) "water,fruit -- file opened in r+t -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(12) int(12) bool(false) @@ -106,9 +106,9 @@ string(%d) "water,fruit -- file opened in a+ -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(12) int(12) bool(false) @@ -117,9 +117,9 @@ string(12) "water,fruit -- file opened in a+b -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(12) int(12) bool(false) @@ -128,9 +128,9 @@ string(12) "water,fruit -- file opened in a+t -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(12) int(12) bool(false) @@ -139,9 +139,9 @@ string(%d) "water,fruit -- file opened in w+ -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(12) int(12) bool(false) @@ -150,9 +150,9 @@ string(12) "water,fruit -- file opened in w+b -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(12) int(12) bool(false) @@ -161,9 +161,9 @@ string(12) "water,fruit -- file opened in w+t -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(12) int(12) bool(false) @@ -172,9 +172,9 @@ string(%d) "water,fruit -- file opened in x+ -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(12) int(12) bool(false) @@ -183,9 +183,9 @@ string(12) "water,fruit -- file opened in x+b -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(12) int(12) bool(false) @@ -194,9 +194,9 @@ string(12) "water,fruit -- file opened in x+t -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(12) int(12) bool(false) @@ -205,9 +205,9 @@ string(%d) "water,fruit -- file opened in r+ -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(15) int(15) bool(false) @@ -216,9 +216,9 @@ string(15) ""water","fruit -- file opened in r+b -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(15) int(15) bool(false) @@ -227,9 +227,9 @@ string(15) ""water","fruit -- file opened in r+t -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(15) int(15) bool(false) @@ -238,9 +238,9 @@ string(%d) ""water","fruit -- file opened in a+ -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(15) int(15) bool(false) @@ -249,9 +249,9 @@ string(15) ""water","fruit -- file opened in a+b -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(15) int(15) bool(false) @@ -260,9 +260,9 @@ string(15) ""water","fruit -- file opened in a+t -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(15) int(15) bool(false) @@ -271,9 +271,9 @@ string(%d) ""water","fruit -- file opened in w+ -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(15) int(15) bool(false) @@ -282,9 +282,9 @@ string(15) ""water","fruit -- file opened in w+b -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(15) int(15) bool(false) @@ -293,9 +293,9 @@ string(15) ""water","fruit -- file opened in w+t -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(15) int(15) bool(false) @@ -304,9 +304,9 @@ string(%d) ""water","fruit -- file opened in x+ -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(15) int(15) bool(false) @@ -315,9 +315,9 @@ string(15) ""water","fruit -- file opened in x+b -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(15) int(15) bool(false) @@ -326,9 +326,9 @@ string(15) ""water","fruit -- file opened in x+t -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(15) int(15) bool(false) @@ -337,9 +337,9 @@ string(%d) ""water","fruit -- file opened in r+ -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(16) int(16) bool(false) @@ -348,9 +348,9 @@ string(16) ""water","fruit" -- file opened in r+b -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(16) int(16) bool(false) @@ -359,9 +359,9 @@ string(16) ""water","fruit" -- file opened in r+t -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(16) int(16) bool(false) @@ -370,9 +370,9 @@ string(%d) ""water","fruit" -- file opened in a+ -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(16) int(16) bool(false) @@ -381,9 +381,9 @@ string(16) ""water","fruit" -- file opened in a+b -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(16) int(16) bool(false) @@ -392,9 +392,9 @@ string(16) ""water","fruit" -- file opened in a+t -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(16) int(16) bool(false) @@ -403,9 +403,9 @@ string(%d) ""water","fruit" -- file opened in w+ -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(16) int(16) bool(false) @@ -414,9 +414,9 @@ string(16) ""water","fruit" -- file opened in w+b -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(16) int(16) bool(false) @@ -425,9 +425,9 @@ string(16) ""water","fruit" -- file opened in w+t -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(16) int(16) bool(false) @@ -436,9 +436,9 @@ string(%d) ""water","fruit" -- file opened in x+ -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(16) int(16) bool(false) @@ -447,9 +447,9 @@ string(16) ""water","fruit" -- file opened in x+b -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(16) int(16) bool(false) @@ -458,9 +458,9 @@ string(16) ""water","fruit" -- file opened in x+t -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(16) int(16) bool(false) @@ -469,9 +469,9 @@ string(%d) ""water","fruit" -- file opened in r+ -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(18) int(18) bool(false) @@ -480,9 +480,9 @@ string(18) "%^water^ ^fruit^% -- file opened in r+b -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(18) int(18) bool(false) @@ -491,9 +491,9 @@ string(18) "%^water^ ^fruit^% -- file opened in r+t -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(18) int(18) bool(false) @@ -502,9 +502,9 @@ string(%d) "%^water^ ^fruit^% -- file opened in a+ -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(18) int(18) bool(false) @@ -513,9 +513,9 @@ string(18) "%^water^ ^fruit^% -- file opened in a+b -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(18) int(18) bool(false) @@ -524,9 +524,9 @@ string(18) "%^water^ ^fruit^% -- file opened in a+t -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(18) int(18) bool(false) @@ -535,9 +535,9 @@ string(%d) "%^water^ ^fruit^% -- file opened in w+ -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(18) int(18) bool(false) @@ -546,9 +546,9 @@ string(18) "%^water^ ^fruit^% -- file opened in w+b -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(18) int(18) bool(false) @@ -557,9 +557,9 @@ string(18) "%^water^ ^fruit^% -- file opened in w+t -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(18) int(18) bool(false) @@ -568,9 +568,9 @@ string(%d) "%^water^ ^fruit^% -- file opened in x+ -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(18) int(18) bool(false) @@ -579,9 +579,9 @@ string(18) "%^water^ ^fruit^% -- file opened in x+b -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(18) int(18) bool(false) @@ -590,9 +590,9 @@ string(18) "%^water^ ^fruit^% -- file opened in x+t -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(18) int(18) bool(false) @@ -601,9 +601,9 @@ string(%d) "%^water^ ^fruit^% -- file opened in r+ -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(16) int(16) bool(false) @@ -612,9 +612,9 @@ string(16) "&water&:&fruit& -- file opened in r+b -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(16) int(16) bool(false) @@ -623,9 +623,9 @@ string(16) "&water&:&fruit& -- file opened in r+t -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(16) int(16) bool(false) @@ -634,9 +634,9 @@ string(%d) "&water&:&fruit& -- file opened in a+ -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(16) int(16) bool(false) @@ -645,9 +645,9 @@ string(16) "&water&:&fruit& -- file opened in a+b -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(16) int(16) bool(false) @@ -656,9 +656,9 @@ string(16) "&water&:&fruit& -- file opened in a+t -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(16) int(16) bool(false) @@ -667,9 +667,9 @@ string(%d) "&water&:&fruit& -- file opened in w+ -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(16) int(16) bool(false) @@ -678,9 +678,9 @@ string(16) "&water&:&fruit& -- file opened in w+b -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(16) int(16) bool(false) @@ -689,9 +689,9 @@ string(16) "&water&:&fruit& -- file opened in w+t -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(16) int(16) bool(false) @@ -700,9 +700,9 @@ string(%d) "&water&:&fruit& -- file opened in x+ -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(16) int(16) bool(false) @@ -711,9 +711,9 @@ string(16) "&water&:&fruit& -- file opened in x+b -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(16) int(16) bool(false) @@ -722,9 +722,9 @@ string(16) "&water&:&fruit& -- file opened in x+t -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(16) int(16) bool(false) @@ -733,9 +733,9 @@ string(%d) "&water&:&fruit& -- file opened in r+ -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(16) int(16) bool(false) @@ -744,9 +744,9 @@ string(16) "=water===fruit= -- file opened in r+b -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(16) int(16) bool(false) @@ -755,9 +755,9 @@ string(16) "=water===fruit= -- file opened in r+t -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(16) int(16) bool(false) @@ -766,9 +766,9 @@ string(%d) "=water===fruit= -- file opened in a+ -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(16) int(16) bool(false) @@ -777,9 +777,9 @@ string(16) "=water===fruit= -- file opened in a+b -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(16) int(16) bool(false) @@ -788,9 +788,9 @@ string(16) "=water===fruit= -- file opened in a+t -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(16) int(16) bool(false) @@ -799,9 +799,9 @@ string(%d) "=water===fruit= -- file opened in w+ -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(16) int(16) bool(false) @@ -810,9 +810,9 @@ string(16) "=water===fruit= -- file opened in w+b -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(16) int(16) bool(false) @@ -821,9 +821,9 @@ string(16) "=water===fruit= -- file opened in w+t -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(16) int(16) bool(false) @@ -832,9 +832,9 @@ string(%d) "=water===fruit= -- file opened in x+ -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(16) int(16) bool(false) @@ -843,9 +843,9 @@ string(16) "=water===fruit= -- file opened in x+b -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(16) int(16) bool(false) @@ -854,9 +854,9 @@ string(16) "=water===fruit= -- file opened in x+t -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(16) int(16) bool(false) @@ -865,9 +865,9 @@ string(%d) "=water===fruit= -- file opened in r+ -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(18) int(18) bool(false) @@ -876,9 +876,9 @@ string(18) "-water--fruit-air -- file opened in r+b -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(18) int(18) bool(false) @@ -887,9 +887,9 @@ string(18) "-water--fruit-air -- file opened in r+t -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(18) int(18) bool(false) @@ -898,9 +898,9 @@ string(%d) "-water--fruit-air -- file opened in a+ -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(18) int(18) bool(false) @@ -909,9 +909,9 @@ string(18) "-water--fruit-air -- file opened in a+b -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(18) int(18) bool(false) @@ -920,9 +920,9 @@ string(18) "-water--fruit-air -- file opened in a+t -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(18) int(18) bool(false) @@ -931,9 +931,9 @@ string(%d) "-water--fruit-air -- file opened in w+ -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(18) int(18) bool(false) @@ -942,9 +942,9 @@ string(18) "-water--fruit-air -- file opened in w+b -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(18) int(18) bool(false) @@ -953,9 +953,9 @@ string(18) "-water--fruit-air -- file opened in w+t -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(18) int(18) bool(false) @@ -964,9 +964,9 @@ string(%d) "-water--fruit-air -- file opened in x+ -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(18) int(18) bool(false) @@ -975,9 +975,9 @@ string(18) "-water--fruit-air -- file opened in x+b -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(18) int(18) bool(false) @@ -986,9 +986,9 @@ string(18) "-water--fruit-air -- file opened in x+t -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(18) int(18) bool(false) @@ -997,9 +997,9 @@ string(%d) "-water--fruit-air -- file opened in r+ -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(22) int(22) bool(false) @@ -1008,9 +1008,9 @@ string(22) "-water---fruit---air- -- file opened in r+b -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(22) int(22) bool(false) @@ -1019,9 +1019,9 @@ string(22) "-water---fruit---air- -- file opened in r+t -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(22) int(22) bool(false) @@ -1030,9 +1030,9 @@ string(%d) "-water---fruit---air- -- file opened in a+ -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(22) int(22) bool(false) @@ -1041,9 +1041,9 @@ string(22) "-water---fruit---air- -- file opened in a+b -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(22) int(22) bool(false) @@ -1052,9 +1052,9 @@ string(22) "-water---fruit---air- -- file opened in a+t -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(22) int(22) bool(false) @@ -1063,9 +1063,9 @@ string(%d) "-water---fruit---air- -- file opened in w+ -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(22) int(22) bool(false) @@ -1074,9 +1074,9 @@ string(22) "-water---fruit---air- -- file opened in w+b -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(22) int(22) bool(false) @@ -1085,9 +1085,9 @@ string(22) "-water---fruit---air- -- file opened in w+t -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(22) int(22) bool(false) @@ -1096,9 +1096,9 @@ string(%d) "-water---fruit---air- -- file opened in x+ -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(22) int(22) bool(false) @@ -1107,9 +1107,9 @@ string(22) "-water---fruit---air- -- file opened in x+b -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(22) int(22) bool(false) @@ -1118,9 +1118,9 @@ string(22) "-water---fruit---air- -- file opened in x+t -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(22) int(22) bool(false) @@ -1129,9 +1129,9 @@ string(%d) "-water---fruit---air- -- file opened in r+ -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(24) int(24) bool(false) @@ -1140,9 +1140,9 @@ string(24) "&""""&:&"&:,:":&,&:,,,, -- file opened in r+b -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(24) int(24) bool(false) @@ -1151,9 +1151,9 @@ string(24) "&""""&:&"&:,:":&,&:,,,, -- file opened in r+t -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(24) int(24) bool(false) @@ -1162,9 +1162,9 @@ string(%d) "&""""&:&"&:,:":&,&:,,,, -- file opened in a+ -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(24) int(24) bool(false) @@ -1173,9 +1173,9 @@ string(24) "&""""&:&"&:,:":&,&:,,,, -- file opened in a+b -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(24) int(24) bool(false) @@ -1184,9 +1184,9 @@ string(24) "&""""&:&"&:,:":&,&:,,,, -- file opened in a+t -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(24) int(24) bool(false) @@ -1195,9 +1195,9 @@ string(%d) "&""""&:&"&:,:":&,&:,,,, -- file opened in w+ -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(24) int(24) bool(false) @@ -1206,9 +1206,9 @@ string(24) "&""""&:&"&:,:":&,&:,,,, -- file opened in w+b -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(24) int(24) bool(false) @@ -1217,9 +1217,9 @@ string(24) "&""""&:&"&:,:":&,&:,,,, -- file opened in w+t -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(24) int(24) bool(false) @@ -1228,9 +1228,9 @@ string(%d) "&""""&:&"&:,:":&,&:,,,, -- file opened in x+ -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(24) int(24) bool(false) @@ -1239,9 +1239,9 @@ string(24) "&""""&:&"&:,:":&,&:,,,, -- file opened in x+b -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(24) int(24) bool(false) @@ -1250,9 +1250,9 @@ string(24) "&""""&:&"&:,:":&,&:,,,, -- file opened in x+t -- -Notice: fputcsv(): delimiter must be a single character in %s on line %d +Warning: fputcsv(): Argument #3 ($delimiter) must be a single character in %s on line %d -Notice: fputcsv(): enclosure must be a single character in %s on line %d +Warning: fputcsv(): Argument #4 ($enclosure) must be a single character in %s on line %d int(24) int(24) bool(false) diff --git a/ext/standard/tests/file/glob_error_002-win32.phpt b/ext/standard/tests/file/glob_error_002-win32.phpt index 4597e28e4b650..52b75fee43d28 100644 --- a/ext/standard/tests/file/glob_error_002-win32.phpt +++ b/ext/standard/tests/file/glob_error_002-win32.phpt @@ -11,7 +11,7 @@ if(substr(PHP_OS, 0, 3) != "WIN") @@ -19,5 +19,4 @@ echo "Done"; *** Testing glob() : error condition - pattern too long. *** Warning: glob(): Pattern exceeds the maximum allowed length of %d characters in %s on line %d -bool(false) Done diff --git a/ext/standard/tests/file/popen_pclose_error.phpt b/ext/standard/tests/file/popen_pclose_error.phpt index 2f05e7788d982..6c92708dddb74 100644 --- a/ext/standard/tests/file/popen_pclose_error.phpt +++ b/ext/standard/tests/file/popen_pclose_error.phpt @@ -1,28 +1,28 @@ --TEST-- Test popen() and pclose function: error conditions ---SKIPIF-- - --FILE-- ---CLEAN-- - ---EXPECTF-- -*** Testing for error conditions *** -Warning: popen(abc.txt,rw): %s on line %d -bool(false) +try { + popen("abc.txt", "x"); +} catch (ValueError $exception) { + echo $exception->getMessage() . "\n"; +} + +try { + popen("abc.txt", "rw"); +} catch (ValueError $exception) { + echo $exception->getMessage() . "\n"; +} ---- Done --- +try { + popen("abc.txt", "rwb"); +} catch (ValueError $exception) { + echo $exception->getMessage() . "\n"; +} + +?> +--EXPECT-- +popen(): Argument #2 ($mode) must be one of "r", "rb", "w", or "wb" +popen(): Argument #2 ($mode) must be one of "r", "rb", "w", or "wb" +popen(): Argument #2 ($mode) must be one of "r", "rb", "w", or "wb" diff --git a/ext/standard/tests/general_functions/010.phpt b/ext/standard/tests/general_functions/010.phpt index 99971616d215d..31b8bed9050c2 100644 --- a/ext/standard/tests/general_functions/010.phpt +++ b/ext/standard/tests/general_functions/010.phpt @@ -11,11 +11,14 @@ class test { } } -var_dump(register_shutdown_function(array("test","__call"))); +try { + register_shutdown_function(array("test","__call")); +} catch (TypeError $exception) { + echo $exception->getMessage() . "\n"; +} echo "Done\n"; ?> ---EXPECTF-- -Warning: register_shutdown_function(): Invalid shutdown callback 'test::__call' passed in %s on line %d -bool(false) +--EXPECT-- +register_shutdown_function(): Argument #1 ($function) must be a valid callback, function "test::__call" not found or invalid function name Done diff --git a/ext/standard/tests/general_functions/bug32647.phpt b/ext/standard/tests/general_functions/bug32647.phpt index ff7bf9f056e63..09735c9d86c48 100644 --- a/ext/standard/tests/general_functions/bug32647.phpt +++ b/ext/standard/tests/general_functions/bug32647.phpt @@ -15,39 +15,73 @@ class bar } unset($obj); -register_shutdown_function(array($obj,"")); // Invalid -register_shutdown_function(array($obj,"some string")); // Invalid -register_shutdown_function(array(0,"")); // Invalid -register_shutdown_function(array('bar','foo')); // Invalid -register_shutdown_function(array(0,"some string")); // Invalid -register_shutdown_function('bar'); // Invalid -register_shutdown_function('foo'); // Valid -register_shutdown_function(array('bar','barfoo')); // Invalid -$obj = new bar; -register_shutdown_function(array($obj,'foobar')); // Invalid -register_shutdown_function(array($obj,'barfoo')); // Valid +try { + register_shutdown_function(array($obj,"")); +} catch (TypeError $exception) { + echo $exception->getMessage() . "\n"; +} -?> ---EXPECTF-- -Warning: Undefined variable $obj in %s on line %d +try { + register_shutdown_function(array($obj,"some string")); +} catch (TypeError $exception) { + echo $exception->getMessage() . "\n"; +} -Warning: register_shutdown_function(): Invalid shutdown callback 'Array' passed in %s on line %d +try { + register_shutdown_function(array(0,"")); +} catch (TypeError $exception) { + echo $exception->getMessage() . "\n"; +} -Warning: Undefined variable $obj in %s on line %d +try { + register_shutdown_function(array('bar','foo')); +} catch (TypeError $exception) { + echo $exception->getMessage() . "\n"; +} + +try { + register_shutdown_function(array(0,"some string")); +} catch (TypeError $exception) { + echo $exception->getMessage() . "\n"; +} -Warning: register_shutdown_function(): Invalid shutdown callback 'Array' passed in %s on line %d +try { + register_shutdown_function('bar'); +} catch (TypeError $exception) { + echo $exception->getMessage() . "\n"; +} -Warning: register_shutdown_function(): Invalid shutdown callback 'Array' passed in %s on line %d +register_shutdown_function('foo'); -Warning: register_shutdown_function(): Invalid shutdown callback 'bar::foo' passed in %s on line %d +try { + register_shutdown_function(array('bar','barfoo')); +} catch (TypeError $exception) { + echo $exception->getMessage() . "\n"; +} + +$obj = new bar; -Warning: register_shutdown_function(): Invalid shutdown callback 'Array' passed in %s on line %d +try { + register_shutdown_function(array($obj,'foobar')); +} catch (TypeError $exception) { + echo $exception->getMessage() . "\n"; +} -Warning: register_shutdown_function(): Invalid shutdown callback 'bar' passed in %s on line %d +register_shutdown_function(array($obj,'barfoo')); -Warning: register_shutdown_function(): Invalid shutdown callback 'bar::barfoo' passed in %sbug32647.php on line %d +?> +--EXPECTF-- +Warning: Undefined variable $obj in %s on line %d +register_shutdown_function(): Argument #1 ($function) must be a valid callback, function "Array" not found or invalid function name -Warning: register_shutdown_function(): Invalid shutdown callback 'bar::foobar' passed in %sbug32647.php on line %d +Warning: Undefined variable $obj in %s on line %d +register_shutdown_function(): Argument #1 ($function) must be a valid callback, function "Array" not found or invalid function name +register_shutdown_function(): Argument #1 ($function) must be a valid callback, function "Array" not found or invalid function name +register_shutdown_function(): Argument #1 ($function) must be a valid callback, function "bar::foo" not found or invalid function name +register_shutdown_function(): Argument #1 ($function) must be a valid callback, function "Array" not found or invalid function name +register_shutdown_function(): Argument #1 ($function) must be a valid callback, function "bar" not found or invalid function name +register_shutdown_function(): Argument #1 ($function) must be a valid callback, function "bar::barfoo" not found or invalid function name +register_shutdown_function(): Argument #1 ($function) must be a valid callback, function "bar::foobar" not found or invalid function name foo! bar! diff --git a/ext/standard/tests/general_functions/bug41037.phpt b/ext/standard/tests/general_functions/bug41037.phpt index c8d0a668d0106..683b18ec25156 100644 --- a/ext/standard/tests/general_functions/bug41037.phpt +++ b/ext/standard/tests/general_functions/bug41037.phpt @@ -4,8 +4,12 @@ Bug #41037 (unregister_tick_function() inside the tick function crash PHP) getMessage() . "\n"; + } } declare (ticks=1) { @@ -14,9 +18,9 @@ declare (ticks=1) { echo "Done\n"; } ?> ---EXPECTF-- +--EXPECT-- hello -Warning: unregister_tick_function(): Unable to delete tick function executed at the moment in %s on line %d +Registered tick function cannot be unregistered while it is being executed Done hello -Warning: unregister_tick_function(): Unable to delete tick function executed at the moment in %s on line %d +Registered tick function cannot be unregistered while it is being executed diff --git a/ext/standard/tests/general_functions/dl-cve-2007-4887.phpt b/ext/standard/tests/general_functions/dl-cve-2007-4887.phpt index 263c9a6def492..0fe2a5814343a 100644 --- a/ext/standard/tests/general_functions/dl-cve-2007-4887.phpt +++ b/ext/standard/tests/general_functions/dl-cve-2007-4887.phpt @@ -11,8 +11,10 @@ if (!in_array(php_sapi_name(), $enabled_sapi)) { enable_dl=1 --FILE-- --EXPECTF-- -Warning: dl(): File name exceeds the maximum allowed length of %d characters in %s on line %d +Warning: dl(): Filename exceeds the maximum allowed length of %d characters in %s on line %d bool(false) diff --git a/ext/standard/tests/general_functions/ini_get_all.phpt b/ext/standard/tests/general_functions/ini_get_all.phpt index ca450f1bc43ba..2b71b474a013b 100644 --- a/ext/standard/tests/general_functions/ini_get_all.phpt +++ b/ext/standard/tests/general_functions/ini_get_all.phpt @@ -24,10 +24,10 @@ echo "Done\n"; --EXPECTF-- string(5) "array" -Warning: ini_get_all(): Unable to find extension '' in %s on line %d +Warning: ini_get_all(): Extension "" cannot be found in %s on line %d bool(false) -Warning: ini_get_all(): Unable to find extension 'nosuchextension' in %s on line %d +Warning: ini_get_all(): Extension "nosuchextension" cannot be found in %s on line %d bool(false) array(0) { } @@ -71,6 +71,6 @@ array(3) { array(0) { } -Warning: ini_get_all(): Unable to find extension '' in %sini_get_all.php on line %d +Warning: ini_get_all(): Extension "" cannot be found in %s on line %d bool(false) Done diff --git a/ext/standard/tests/mail/mail_basic7.phpt b/ext/standard/tests/mail/mail_basic7.phpt index 54d020e46ce2a..47614c011eb76 100644 --- a/ext/standard/tests/mail/mail_basic7.phpt +++ b/ext/standard/tests/mail/mail_basic7.phpt @@ -29,37 +29,65 @@ $outFile = "mailBasic7.out"; echo "-- All Mail Content Parameters --\n"; // Calling mail() with all additional headers -var_dump( mail($to, $subject, $message, $additional_headers) ); + +var_dump(mail($to, $subject, $message, $additional_headers)); echo file_get_contents($outFile); unlink($outFile); - echo "\n\n************* TEST ******************\n"; // Should fail all // Initialise all required variables $to = 'user@example.com'; $subject = 'Test Subject'; $message = 'A Message'; -// Headers should not have array values -$additional_headers = array( - 'orig-date' => array('foo1'), - 'from' => array('foo2'), - 'sender' => array('foo3'), - 'reply-to' => array('foo4'), - 'to' => array('foo5'), - 'bcc' => array('foo6'), - 'message-id' => array('foo7'), - 'in-reply-to'=> array('foo8'), -); -$outFile = "mailBasic7.out"; -@unlink($outFile); - -echo "-- All Mail Content Parameters --\n"; -// Calling mail() with all additional headers -var_dump( mail($to, $subject, $message, $additional_headers) ); -echo file_get_contents($outFile); -unlink($outFile); +try { + mail($to, $subject, $message, ['orig-date' => array('foo1')]); +} catch (TypeError|ValueError $exception) { + echo get_class($exception) . ": " . $exception->getMessage() . "\n"; +} + +try { + mail($to, $subject, $message, ['from' => array('foo2')]); +} catch (TypeError|ValueError $exception) { + echo get_class($exception) . ": " . $exception->getMessage() . "\n"; +} + +try { + mail($to, $subject, $message, ['sender' => array('foo3')]); +} catch (TypeError|ValueError $exception) { + echo get_class($exception) . ": " . $exception->getMessage() . "\n"; +} + +try { + mail($to, $subject, $message, ['reply-to' => array('foo4')]); +} catch (TypeError|ValueError $exception) { + echo get_class($exception) . ": " . $exception->getMessage() . "\n"; +} + +try { + mail($to, $subject, $message, ['to' => array('foo5')]); +} catch (TypeError|ValueError $exception) { + echo get_class($exception) . ": " . $exception->getMessage() . "\n"; +} + +try { + mail($to, $subject, $message, ['bcc' => array('foo6')]); +} catch (TypeError|ValueError $exception) { + echo get_class($exception) . ": " . $exception->getMessage() . "\n"; +} + +try { + mail($to, $subject, $message, ['message-id' => array('foo7')]); +} catch (TypeError|ValueError $exception) { + echo get_class($exception) . ": " . $exception->getMessage() . "\n"; +} + +try { + mail($to, $subject, $message, ['in-reply-to'=> array('foo8')]); +} catch (TypeError|ValueError $exception) { + echo get_class($exception) . ": " . $exception->getMessage() . "\n"; +} echo "\n\n************* TEST ******************\n"; // Should fail all @@ -67,24 +95,48 @@ echo "\n\n************* TEST ******************\n"; $to = 'user@example.com'; $subject = 'Test Subject'; $message = 'A Message'; -$additional_headers = array( - 'foo1' => array('foo1'=>'bar1'), - 'foo2' => array('foo2', array('foo3')), - 'foo3' => array(123), - 'foo4' => array(123.456), - 'foo5' => array(FALSE), - 'foo6' => array(NULL), - 'foo7' => array(new StdClass), -); -$outFile = "mailBasic7.out"; -@unlink($outFile); - -echo "-- All Mail Content Parameters --\n"; -// Calling mail() with all additional headers -var_dump( mail($to, $subject, $message, $additional_headers) ); -echo file_get_contents($outFile); -unlink($outFile); +try { + mail($to, $subject, $message, ['foo1' => array('foo2'=>'bar1')]); +} catch (TypeError|ValueError $exception) { + echo get_class($exception) . ": " . $exception->getMessage() . "\n"; +} + +try { + mail($to, $subject, $message, ['foo2' => array('foo2', array('foo3'))]); +} catch (TypeError|ValueError $exception) { + echo get_class($exception) . ": " . $exception->getMessage() . "\n"; +} + +try { + mail($to, $subject, $message, ['foo3' => array(123)]); +} catch (TypeError|ValueError $exception) { + echo get_class($exception) . ": " . $exception->getMessage() . "\n"; +} + +try { + mail($to, $subject, $message, ['foo4' => array(123.456)]); +} catch (TypeError|ValueError $exception) { + echo get_class($exception) . ": " . $exception->getMessage() . "\n"; +} + +try { + mail($to, $subject, $message, ['foo5' => array(FALSE)]); +} catch (TypeError|ValueError $exception) { + echo get_class($exception) . ": " . $exception->getMessage() . "\n"; +} + +try { + mail($to, $subject, $message, ['foo6' => array(NULL)]); +} catch (TypeError|ValueError $exception) { + echo get_class($exception) . ": " . $exception->getMessage() . "\n"; +} + +try { + mail($to, $subject, $message, ['foo7' => array(new StdClass)]); +} catch (TypeError|ValueError $exception) { + echo get_class($exception) . ": " . $exception->getMessage() . "\n"; +} echo "\n\n************* TEST ******************\n"; // Should fail most @@ -92,27 +144,68 @@ echo "\n\n************* TEST ******************\n"; $to = 'user@example.com'; $subject = 'Test Subject'; $message = 'A Message'; -$additional_headers = array( - '*:foo1' => array('bar1'), - 'foo2:::' => array('bar1'), - 'foo3()' => array('bar1'), - 'foo4@' => array('bar1'), - 'foo5|' => array('bar1'), - "\0foo6" => array('bar1'), - "foo7\0" => array('bar1'), - "foo8" => array(), - "foo9" => '%&$#!', - "foo10" => "abc\0\tdef", -); + $outFile = "mailBasic7.out"; @unlink($outFile); -echo "-- All Mail Content Parameters --\n"; -// Calling mail() with all additional headers -var_dump( mail($to, $subject, $message, $additional_headers) ); +try { + mail($to, $subject, $message, ['*:foo1' => array('bar1')]); +} catch (TypeError|ValueError $exception) { + echo get_class($exception) . ": " . $exception->getMessage() . "\n"; +} + +try { + mail($to, $subject, $message, ['foo2:::' => array('bar1')]); +} catch (TypeError|ValueError $exception) { + echo get_class($exception) . ": " . $exception->getMessage() . "\n"; +} + +try { + mail($to, $subject, $message, ['foo3()' => array('bar1')]); +} catch (TypeError|ValueError $exception) { + echo get_class($exception) . ": " . $exception->getMessage() . "\n"; +} + +try { + mail($to, $subject, $message, ['foo4@' => array('bar1')]); +} catch (TypeError|ValueError $exception) { + echo get_class($exception) . ": " . $exception->getMessage() . "\n"; +} + +try { + mail($to, $subject, $message, ['foo5|' => array('bar1')]); +} catch (TypeError|ValueError $exception) { + echo get_class($exception) . ": " . $exception->getMessage() . "\n"; +} + +try { + mail($to, $subject, $message, ["\0foo6" => array('bar1')]); +} catch (TypeError|ValueError $exception) { + echo get_class($exception) . ": " . $exception->getMessage() . "\n"; +} + +try { + mail($to, $subject, $message, ["foo7\0" => array('bar1')]); +} catch (TypeError|ValueError $exception) { + echo get_class($exception) . ": " . $exception->getMessage() . "\n"; +} + +try { + mail($to, $subject, $message, ["foo8" => array()]); +} catch (TypeError|ValueError $exception) { + echo get_class($exception) . ": " . $exception->getMessage() . "\n"; +} + +var_dump(mail($to, $subject, $message, ["foo9" => '%&$#!'])); echo file_get_contents($outFile); unlink($outFile); +try { + mail($to, $subject, $message, ["foo10" => "abc\0\tdef"]); +} catch (TypeError|ValueError $exception) { + echo get_class($exception) . ": " . $exception->getMessage() . "\n"; +} + ?> --EXPECTF-- *** Testing mail() : basic functionality *** @@ -134,72 +227,35 @@ A Message ************* TEST ****************** --- All Mail Content Parameters -- - -Warning: mail(): 'orig-date' header must be at most one header. Array is passed for 'orig-date' in %s on line %d - -Warning: mail(): 'from' header must be at most one header. Array is passed for 'from' in %s on line %d - -Warning: mail(): 'sender' header must be at most one header. Array is passed for 'sender' in %s on line %d - -Warning: mail(): 'reply-to' header must be at most one header. Array is passed for 'reply-to' in %s on line %d - -Warning: mail(): Extra header cannot contain 'To' header in %s on line %d - -Warning: mail(): 'bcc' header must be at most one header. Array is passed for 'bcc' in %s on line %d - -Warning: mail(): 'message-id' header must be at most one header. Array is passed for 'message-id' in %s on line %d - -Warning: mail(): 'in-reply-to' header must be at most one header. Array is passed for 'in-reply-to' in %s on line %d -bool(true) -To: user@example.com -Subject: Test Subject - -A Message +TypeError: Header "orig-date" must be of type string, array given +TypeError: Header "from" must be of type string, array given +TypeError: Header "sender" must be of type string, array given +TypeError: Header "reply-to" must be of type string, array given +ValueError: The additional headers cannot contain the "To" header +TypeError: Header "bcc" must be of type string, array given +TypeError: Header "message-id" must be of type string, array given +TypeError: Header "in-reply-to" must be of type string, array given ************* TEST ****************** --- All Mail Content Parameters -- - -Warning: mail(): Multiple header key must be numeric index (foo1) in %s on line %d - -Warning: mail(): Multiple header values must be string (foo2) in %s on line %d - -Warning: mail(): Multiple header values must be string (foo3) in %s on line %d - -Warning: mail(): Multiple header values must be string (foo4) in %s on line %d - -Warning: mail(): Multiple header values must be string (foo5) in %s on line %d - -Warning: mail(): Multiple header values must be string (foo6) in %s on line %d - -Warning: mail(): Multiple header values must be string (foo7) in %s on line %d -bool(true) -To: user@example.com -Subject: Test Subject -foo2: foo2 - -A Message +TypeError: Header "foo1" must only contain numeric keys, "foo2" found +TypeError: Header "foo2" must only contain values of type string, array found +TypeError: Header "foo3" must only contain values of type string, int found +TypeError: Header "foo4" must only contain values of type string, float found +TypeError: Header "foo5" must only contain values of type string, bool found +TypeError: Header "foo6" must only contain values of type string, null found +TypeError: Header "foo7" must only contain values of type string, stdClass found ************* TEST ****************** --- All Mail Content Parameters -- - -Warning: mail(): Header field name (*:foo1) contains invalid chars in %s on line %d - -Warning: mail(): Header field name (foo2:::) contains invalid chars in %s on line %d - -Warning: mail(): Header field name () contains invalid chars in %s on line %d - -Warning: mail(): Header field name (foo7) contains invalid chars in %s on line %d - -Warning: mail(): Header field value (foo10 => abc) contains invalid chars or format in %s on line %d +ValueError: Header name "*:foo1" contains invalid characters +ValueError: Header name "foo2:::" contains invalid characters +ValueError: Header name "" contains invalid characters +ValueError: Header name "foo7" contains invalid characters bool(true) To: user@example.com Subject: Test Subject -foo3(): bar1 -foo4@: bar1 -foo5|: bar1 foo9: %&$#! A Message +ValueError: Header "foo10" has invalid format, or contains invalid characters diff --git a/ext/standard/tests/misc/time_sleep_until_error1.phpt b/ext/standard/tests/misc/time_sleep_until_error1.phpt index 2a409a38b407f..eaa809f4d1a4d 100644 --- a/ext/standard/tests/misc/time_sleep_until_error1.phpt +++ b/ext/standard/tests/misc/time_sleep_until_error1.phpt @@ -8,8 +8,10 @@ Danilo Sanchi sanchi@grupporetina.com #PHPTestFest Cesena Italia on 2009-06-20 --FILE-- --EXPECTF-- -Warning: time_sleep_until(): Sleep until to time is less than current time in %s on line 2 +Warning: time_sleep_until(): Argument #1 ($timestamp) must be greater than or equal to the current time in %s on line %d bool(false) diff --git a/ext/standard/tests/network/dns_check_record_error_conditions.phpt b/ext/standard/tests/network/dns_check_record_error_conditions.phpt new file mode 100644 index 0000000000000..dae0bfb3750c6 --- /dev/null +++ b/ext/standard/tests/network/dns_check_record_error_conditions.phpt @@ -0,0 +1,19 @@ +--TEST-- +dns_check_record() error conditions +--FILE-- +getMessage() . "\n"; +} +try { + // A random DNS Mode + dns_check_record('php.net', 15263480); +} catch (\ValueError $exception) { + echo $exception->getMessage() . "\n"; +} +?> +--EXPECT-- +dns_check_record(): Argument #1 ($hostname) cannot be empty +dns_check_record(): Argument #2 ($type) must be a valid DNS record type diff --git a/ext/standard/tests/network/dns_get_record_error_conditions.phpt b/ext/standard/tests/network/dns_get_record_error_conditions.phpt new file mode 100644 index 0000000000000..6506aca4108e8 --- /dev/null +++ b/ext/standard/tests/network/dns_get_record_error_conditions.phpt @@ -0,0 +1,31 @@ +--TEST-- +dns_get_record() error conditions +--FILE-- +getMessage() . "\n"; +} +try { + // DNS Mode 0 + $auth = []; + $additional = []; + dns_get_record('php.net', 0, $auth, $additional, true); +} catch (\ValueError $exception) { + echo $exception->getMessage() . "\n"; +} +try { + // A random DNS Mode + $auth = []; + $additional = []; + dns_get_record('php.net', 15263480, $auth, $additional, true); +} catch (\ValueError $exception) { + echo $exception->getMessage() . "\n"; +} +?> +--EXPECT-- +dns_get_record(): Argument #2 ($type) must be a DNS_* constant +dns_get_record(): Argument #2 ($type) must be between 1 and 65535 when argument #5 ($raw) is true +dns_get_record(): Argument #2 ($type) must be between 1 and 65535 when argument #5 ($raw) is true diff --git a/ext/standard/tests/password/password_removed_salt_option.phpt b/ext/standard/tests/password/password_removed_salt_option.phpt index 356bdec3e8aab..da7cb22d1c543 100644 --- a/ext/standard/tests/password/password_removed_salt_option.phpt +++ b/ext/standard/tests/password/password_removed_salt_option.phpt @@ -12,9 +12,9 @@ var_dump(strlen(password_hash("test", PASSWORD_BCRYPT, array("salt" => "12345678 echo "OK!"; ?> --EXPECTF-- -Warning: password_hash(): The 'salt' option is no longer supported. The provided salt has been been ignored in %s on line %d +Warning: password_hash(): The "salt" option has been ignored, since providing a custom salt is no longer supported in %s on line %d int(60) -Warning: password_hash(): The 'salt' option is no longer supported. The provided salt has been been ignored in %s on line %d +Warning: password_hash(): The "salt" option has been ignored, since providing a custom salt is no longer supported in %s on line %d int(60) OK! diff --git a/ext/standard/tests/serialize/bug14293.phpt b/ext/standard/tests/serialize/bug14293.phpt index ae108ba53a740..86066607fbcbe 100644 --- a/ext/standard/tests/serialize/bug14293.phpt +++ b/ext/standard/tests/serialize/bug14293.phpt @@ -26,7 +26,7 @@ var_dump($t); --EXPECTF-- __sleep called -Notice: serialize(): "b" returned as member variable from __sleep() but does not exist in %sbug14293.php on line %d +Warning: serialize(): "b" returned as member variable from __sleep() but does not exist in %s on line %d O:1:"t":1:{s:1:"a";s:5:"hello";} object(t)#%d (1) { ["a"]=> diff --git a/ext/standard/tests/serialize/bug35895.phpt b/ext/standard/tests/serialize/bug35895.phpt index 22fce0d1f2624..de7ff6d3e1a4f 100644 --- a/ext/standard/tests/serialize/bug35895.phpt +++ b/ext/standard/tests/serialize/bug35895.phpt @@ -21,4 +21,4 @@ serialize($obj); ?> --EXPECTF-- -Notice: serialize(): "parents" returned as member variable from __sleep() but does not exist in %sbug35895.php on line %d +Warning: serialize(): "parents" returned as member variable from __sleep() but does not exist in %s on line %d diff --git a/ext/standard/tests/serialize/bug71995.phpt b/ext/standard/tests/serialize/bug71995.phpt index f1c45d25cc9c2..bf62c7da1eea8 100644 --- a/ext/standard/tests/serialize/bug71995.phpt +++ b/ext/standard/tests/serialize/bug71995.phpt @@ -18,7 +18,7 @@ var_dump($s); var_dump(unserialize($s)); ?> --EXPECTF-- -Notice: serialize(): "b" is returned from __sleep multiple times in %sbug71995.php on line %d +Notice: serialize(): "b" is returned from __sleep() multiple times in %s on line %d string(39) "O:1:"A":1:{s:1:"b";O:8:"stdClass":0:{}}" object(A)#%d (1) { ["b"]=> diff --git a/ext/standard/tests/serialize/bug79526.phpt b/ext/standard/tests/serialize/bug79526.phpt index 19f07fe9891e4..440c18772d53d 100644 --- a/ext/standard/tests/serialize/bug79526.phpt +++ b/ext/standard/tests/serialize/bug79526.phpt @@ -24,9 +24,9 @@ serialize(new B()); ?> Done --EXPECTF-- -Notice: serialize(): A::__sleep should return an array only containing the names of instance-variables to serialize in %sbug79526.php on line %d +Warning: serialize(): A::__sleep() should return an array only containing the names of instance-variables to serialize in %s on line %d -Notice: serialize(): B::__sleep should return an array only containing the names of instance-variables to serialize in %sbug79526.php on line %d +Warning: serialize(): B::__sleep() should return an array only containing the names of instance-variables to serialize in %s on line %d -Notice: serialize(): "1" returned as member variable from __sleep() but does not exist in %sbug79526.php on line %d +Warning: serialize(): "1" returned as member variable from __sleep() but does not exist in %s on line %d Done diff --git a/ext/standard/tests/serialize/max_depth.phpt b/ext/standard/tests/serialize/max_depth.phpt index 312f22226c21c..1899e21f0472a 100644 --- a/ext/standard/tests/serialize/max_depth.phpt +++ b/ext/standard/tests/serialize/max_depth.phpt @@ -104,8 +104,8 @@ var_dump(is_array(unserialize( ?> --EXPECTF-- Invalid max_depth: -unserialize(): "max_depth" option must be of type int, string given -unserialize(): "max_depth" option must be greater than or equal to 0 +unserialize(): Option "max_depth" must be of type int, string given +unserialize(): Option "max_depth" must be greater than or equal to 0 Array: bool(true) diff --git a/ext/standard/tests/serialize/sleep_mangled_name_clash.phpt b/ext/standard/tests/serialize/sleep_mangled_name_clash.phpt index df9db6a473a71..ac0c835a45a92 100644 --- a/ext/standard/tests/serialize/sleep_mangled_name_clash.phpt +++ b/ext/standard/tests/serialize/sleep_mangled_name_clash.phpt @@ -12,5 +12,5 @@ $s = serialize(new Test); var_dump(str_replace("\0", '\0', $s)); ?> --EXPECTF-- -Notice: serialize(): "priv" is returned from __sleep multiple times in %s on line %d +Notice: serialize(): "priv" is returned from __sleep() multiple times in %s on line %d string(37) "O:4:"Test":1:{s:10:"\0Test\0priv";N;}" diff --git a/ext/standard/tests/serialize/sleep_undefined_declared_properties.phpt b/ext/standard/tests/serialize/sleep_undefined_declared_properties.phpt index 05a638cfba8d7..3c7f802e670b6 100644 --- a/ext/standard/tests/serialize/sleep_undefined_declared_properties.phpt +++ b/ext/standard/tests/serialize/sleep_undefined_declared_properties.phpt @@ -21,9 +21,9 @@ var_dump(serialize(new Test)); ?> --EXPECTF-- -Notice: serialize(): "pub" returned as member variable from __sleep() but does not exist in %s on line %d +Warning: serialize(): "pub" returned as member variable from __sleep() but does not exist in %s on line %d -Notice: serialize(): "prot" returned as member variable from __sleep() but does not exist in %s on line %d +Warning: serialize(): "prot" returned as member variable from __sleep() but does not exist in %s on line %d -Notice: serialize(): "priv" returned as member variable from __sleep() but does not exist in %s on line %d +Warning: serialize(): "priv" returned as member variable from __sleep() but does not exist in %s on line %d string(15) "O:4:"Test":0:{}" diff --git a/ext/standard/tests/serialize/unserialize_error_001.phpt b/ext/standard/tests/serialize/unserialize_error_001.phpt index 25bad8b1b1f49..f390c36a78fef 100644 --- a/ext/standard/tests/serialize/unserialize_error_001.phpt +++ b/ext/standard/tests/serialize/unserialize_error_001.phpt @@ -8,16 +8,27 @@ class foo { $z = array(new foo(), 2, "3"); $s = serialize($z); -var_dump(unserialize($s, ["allowed_classes" => null])); -var_dump(unserialize($s, ["allowed_classes" => 0])); -var_dump(unserialize($s, ["allowed_classes" => 1])); -?> ---EXPECTF-- -Warning: unserialize(): allowed_classes option should be array or boolean in %s on line %d -bool(false) +try { + unserialize($s, ["allowed_classes" => null]); +} catch (TypeError $exception) { + echo $exception->getMessage() . "\n"; +} + +try { + unserialize($s, ["allowed_classes" => 0]); +} catch (TypeError $exception) { + echo $exception->getMessage() . "\n"; +} -Warning: unserialize(): allowed_classes option should be array or boolean in %s on line %d -bool(false) -Warning: unserialize(): allowed_classes option should be array or boolean in %s on line %d -bool(false) +try { + unserialize($s, ["allowed_classes" => 1]); +} catch (TypeError $exception) { + echo $exception->getMessage() . "\n"; +} + +?> +--EXPECT-- +unserialize(): Option "allowed_classes" must be of type array|bool, null given +unserialize(): Option "allowed_classes" must be of type array|bool, int given +unserialize(): Option "allowed_classes" must be of type array|bool, int given 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 a0efebc1f193c..7bfe8d5724d73 100644 --- a/ext/standard/tests/streams/stream_get_contents_negative_length.phpt +++ b/ext/standard/tests/streams/stream_get_contents_negative_length.phpt @@ -6,11 +6,14 @@ stream_get_contents() with negative max length $tmp = tmpfile(); fwrite($tmp, "abcd"); var_dump(stream_get_contents($tmp, 2, 1)); -var_dump(stream_get_contents($tmp, -2)); + +try { + stream_get_contents($tmp, -2); +} catch (ValueError $exception) { + echo $exception->getMessage() . "\n"; +} ?> --EXPECTF-- string(2) "bc" - -Warning: stream_get_contents(): Length must be greater than or equal to 0, or -1 in %s on line %d -bool(false) +stream_get_contents(): Argument #2 ($maxlength) must be greater than or equal to -1 diff --git a/ext/standard/tests/strings/bug40754.phpt b/ext/standard/tests/strings/bug40754.phpt index b71f28044aefd..609e47732a6d6 100644 --- a/ext/standard/tests/strings/bug40754.phpt +++ b/ext/standard/tests/strings/bug40754.phpt @@ -17,7 +17,11 @@ try { echo $exception->getMessage() . "\n"; } -var_dump(substr_compare("abcde", "abc", $v, $v)); +try { + substr_compare("abcde", "abc", $v, $v); +} catch (ValueError $exception) { + echo $exception->getMessage() . "\n"; +} try { stripos("abcde", "abc", $v); @@ -31,7 +35,11 @@ try { echo $exception->getMessage() . "\n"; } -var_dump(substr_count("abcde", "abc", 1, $v)); +try { + substr_count("abcde", "abc", 1, $v); +} catch (ValueError $exception) { + echo $exception->getMessage() . "\n"; +} try { strpos("abcde", "abc", $v); @@ -57,29 +65,32 @@ try { echo $exception->getMessage() . "\n"; } +try { + strripos("abcde", "abc", $v); +} catch (ValueError $exception) { + echo $exception->getMessage() . "\n"; +} + var_dump(strncmp("abcde", "abc", $v)); var_dump(chunk_split("abcde", $v, "abc")); var_dump(substr("abcde", $v, $v)); ?> ---EXPECTF-- +--EXPECT-- string(4) "bcde" string(6) "abcdex" bool(false) bool(false) substr_count(): Argument #3 ($offset) must be contained in argument #1 ($haystack) - -Warning: substr_compare(): The start position cannot exceed initial string length in %s on line %d -bool(false) +substr_compare(): Argument #3 ($offset) must be contained in argument #1 ($main_str) stripos(): Argument #3 ($offset) must be contained in argument #1 ($haystack) substr_count(): Argument #3 ($offset) must be contained in argument #1 ($haystack) - -Warning: substr_count(): Invalid length value in %s on line %d -bool(false) +substr_count(): Argument #4 ($length) must be contained in argument #1 ($haystack) strpos(): Argument #3 ($offset) must be contained in argument #1 ($haystack) stripos(): Argument #3 ($offset) must be contained in argument #1 ($haystack) strrpos(): Argument #3 ($offset) must be contained in argument #1 ($haystack) strripos(): Argument #3 ($offset) must be contained in argument #1 ($haystack) +strripos(): Argument #3 ($offset) must be contained in argument #1 ($haystack) int(2) string(8) "abcdeabc" bool(false) diff --git a/ext/standard/tests/strings/bug44703.phpt b/ext/standard/tests/strings/bug44703.phpt index f9f0e6ea8f0f8..8cbff1504ff04 100644 --- a/ext/standard/tests/strings/bug44703.phpt +++ b/ext/standard/tests/strings/bug44703.phpt @@ -22,25 +22,25 @@ var_dump(htmlspecialchars("<>", ENT_COMPAT, str_repeat('a', 100))); ?> --EXPECTF-- -Warning: htmlspecialchars(): Charset `1' not supported, assuming utf-8 in %s on line %d +Warning: htmlspecialchars(): Charset "1" is not supported, assuming UTF-8 in %s on line %d string(35) "<a href='test'>Test</a>" -Warning: htmlspecialchars(): Charset `12' not supported, assuming utf-8 in %s on line %d +Warning: htmlspecialchars(): Charset "12" is not supported, assuming UTF-8 in %s on line %d string(35) "<a href='test'>Test</a>" -Warning: htmlspecialchars(): Charset `125' not supported, assuming utf-8 in %s on line %d +Warning: htmlspecialchars(): Charset "125" is not supported, assuming UTF-8 in %s on line %d string(35) "<a href='test'>Test</a>" string(35) "<a href='test'>Test</a>" -Warning: htmlspecialchars(): Charset `12526' not supported, assuming utf-8 in %s on line %d +Warning: htmlspecialchars(): Charset "12526" is not supported, assuming UTF-8 in %s on line %d string(35) "<a href='test'>Test</a>" string(8) "<>" -Warning: htmlspecialchars(): Charset `8666' not supported, assuming utf-8 in %s on line %d +Warning: htmlspecialchars(): Charset "8666" is not supported, assuming UTF-8 in %s on line %d string(8) "<>" string(8) "<>" string(8) "<>" string(8) "<>" -Warning: htmlspecialchars(): Charset `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' not supported, assuming utf-8 in %s on line %d +Warning: htmlspecialchars(): Charset "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" is not supported, assuming UTF-8 in %s on line %d string(8) "<>" diff --git a/ext/standard/tests/strings/bug67252.phpt b/ext/standard/tests/strings/bug67252.phpt index eab2112afa359..bd758a1c79fde 100644 --- a/ext/standard/tests/strings/bug67252.phpt +++ b/ext/standard/tests/strings/bug67252.phpt @@ -8,5 +8,5 @@ var_dump(convert_uudecode($a)); ?> --EXPECTF-- -Warning: convert_uudecode(): The given parameter is not a valid uuencoded string in %s on line %d +Warning: convert_uudecode(): Argument #1 ($data) is not a valid uuencoded string in %s on line %d bool(false) diff --git a/ext/standard/tests/strings/substr_count_basic.phpt b/ext/standard/tests/strings/substr_count_basic.phpt index a98a51bea26fc..3b871ac0da3d8 100644 --- a/ext/standard/tests/strings/substr_count_basic.phpt +++ b/ext/standard/tests/strings/substr_count_basic.phpt @@ -34,8 +34,8 @@ var_dump(substr_count($a, "bca", -200, -50)); ?> --EXPECT-- ***Testing basic operations *** -substr_count(): Argument #2 ($needle) must be a non-empty string -substr_count(): Argument #2 ($needle) must be a non-empty string +substr_count(): Argument #2 ($needle) cannot be empty +substr_count(): Argument #2 ($needle) cannot be empty int(0) int(0) int(0) diff --git a/ext/standard/tests/strings/substr_count_error.phpt b/ext/standard/tests/strings/substr_count_error.phpt index 648d9b51e8c67..dc0d3d9834eb6 100644 --- a/ext/standard/tests/strings/substr_count_error.phpt +++ b/ext/standard/tests/strings/substr_count_error.phpt @@ -21,23 +21,27 @@ try { } /* Using offset and length to go beyond the size of the string: - Warning message expected, as length+offset > length of string */ -var_dump( substr_count($str, "i", 5, 7) ); + Exception is expected, as length+offset > length of string */ +try { + substr_count($str, "i", 5, 7); +} catch (ValueError $exception) { + echo $exception->getMessage() . "\n"; +} /* length too small */ -var_dump( substr_count($str, "t", 2, -20) ); +try { + substr_count($str, "t", 2, -20); +} catch (ValueError $exception) { + echo $exception->getMessage() . "\n"; +} echo "Done\n"; ?> ---EXPECTF-- +--EXPECT-- *** Testing error conditions *** substr_count(): Argument #3 ($offset) must be contained in argument #1 ($haystack) substr_count(): Argument #3 ($offset) must be contained in argument #1 ($haystack) - -Warning: substr_count(): Invalid length value in %s on line %d -bool(false) - -Warning: substr_count(): Invalid length value in %s on line %d -bool(false) +substr_count(): Argument #4 ($length) must be contained in argument #1 ($haystack) +substr_count(): Argument #4 ($length) must be contained in argument #1 ($haystack) Done diff --git a/ext/standard/tests/strings/uuencode.phpt b/ext/standard/tests/strings/uuencode.phpt index 8199a2ed0571b..b0a2a2321d025 100644 --- a/ext/standard/tests/strings/uuencode.phpt +++ b/ext/standard/tests/strings/uuencode.phpt @@ -27,6 +27,6 @@ string(36) "6;F]T('9Ename)); + php_error_docref(NULL, E_WARNING, "%s::__sleep() should return an array only containing the names of instance-variables to serialize", ZSTR_VAL(ce->name)); return FAILURE; } @@ -785,7 +785,7 @@ static int php_var_serialize_try_add_sleep_prop( if (!zend_hash_add(ht, name, val)) { php_error_docref(NULL, E_NOTICE, - "\"%s\" is returned from __sleep multiple times", ZSTR_VAL(error_name)); + "\"%s\" is returned from __sleep() multiple times", ZSTR_VAL(error_name)); return SUCCESS; } @@ -810,8 +810,8 @@ static int php_var_serialize_get_sleep_props( ZVAL_DEREF(name_val); if (Z_TYPE_P(name_val) != IS_STRING) { - php_error_docref(NULL, E_NOTICE, - "%s::__sleep should return an array only containing the names of instance-variables to serialize", + php_error_docref(NULL, E_WARNING, + "%s::__sleep() should return an array only containing the names of instance-variables to serialize", ZSTR_VAL(ce->name)); } @@ -858,7 +858,7 @@ static int php_var_serialize_get_sleep_props( break; } - php_error_docref(NULL, E_NOTICE, + php_error_docref(NULL, E_WARNING, "\"%s\" returned as member variable from __sleep() but does not exist", ZSTR_VAL(name)); zend_tmp_string_release(tmp_name); } ZEND_HASH_FOREACH_END(); @@ -1195,8 +1195,7 @@ PHPAPI void php_unserialize_with_options(zval *return_value, const char *buf, co classes = zend_hash_str_find_deref(options, "allowed_classes", sizeof("allowed_classes")-1); if (classes && Z_TYPE_P(classes) != IS_ARRAY && Z_TYPE_P(classes) != IS_TRUE && Z_TYPE_P(classes) != IS_FALSE) { - php_error_docref(NULL, E_WARNING, "allowed_classes option should be array or boolean"); - RETVAL_FALSE; + zend_type_error("%s(): Option \"allowed_classes\" must be of type array|bool, %s given", function_name, zend_zval_type_name(classes)); goto cleanup; } @@ -1225,11 +1224,11 @@ PHPAPI void php_unserialize_with_options(zval *return_value, const char *buf, co max_depth = zend_hash_str_find_deref(options, "max_depth", sizeof("max_depth") - 1); if (max_depth) { if (Z_TYPE_P(max_depth) != IS_LONG) { - zend_type_error("%s(): \"max_depth\" option must be of type int, %s given", function_name, zend_zval_type_name(max_depth)); + zend_type_error("%s(): Option \"max_depth\" must be of type int, %s given", function_name, zend_zval_type_name(max_depth)); goto cleanup; } if (Z_LVAL_P(max_depth) < 0) { - zend_value_error("%s(): \"max_depth\" option must be greater than or equal to 0", function_name); + zend_value_error("%s(): Option \"max_depth\" must be greater than or equal to 0", function_name); goto cleanup; } diff --git a/ext/sysvshm/tests/001.phpt b/ext/sysvshm/tests/001.phpt index 106f6699ee87a..e9d00bc6dc24c 100644 --- a/ext/sysvshm/tests/001.phpt +++ b/ext/sysvshm/tests/001.phpt @@ -7,13 +7,24 @@ if (!function_exists('ftok')){ print 'skip'; } ?> --FILE-- getMessage() . \PHP_EOL; +} + try { - var_dump(ftok("","")); + ftok(-1, -1); +} catch (\ValueError $e) { + echo $e->getMessage() . \PHP_EOL; +} + +try { + ftok("qwertyu","qwertyu"); } catch (\ValueError $e) { echo $e->getMessage() . \PHP_EOL; } -var_dump(ftok(-1, -1)); -var_dump(ftok("qwertyu","qwertyu")); var_dump(ftok("nonexistentfile","q")); @@ -23,12 +34,8 @@ echo "Done\n"; ?> --EXPECTF-- ftok(): Argument #1 ($pathname) cannot be empty - -Warning: ftok(): Project identifier is invalid in %s on line %d -int(-1) - -Warning: ftok(): Project identifier is invalid in %s on line %d -int(-1) +ftok(): Argument #2 ($proj) must be a single character +ftok(): Argument #2 ($proj) must be a single character Warning: ftok(): ftok() failed - No such file or directory in %s on line %d int(-1) diff --git a/main/main.c b/main/main.c index 890116e45c8a8..103c10a06b241 100644 --- a/main/main.c +++ b/main/main.c @@ -2044,8 +2044,9 @@ int php_module_startup(sapi_module_struct *sf, zend_module_entry *additional_mod zend_startup(&zuf); zend_update_current_locale(); + zend_observer_startup(); #if ZEND_DEBUG - zend_register_error_notify_callback(report_zend_debug_error_notify_cb); + zend_observer_error_register(report_zend_debug_error_notify_cb); #endif #if HAVE_TZSET @@ -2192,7 +2193,6 @@ int php_module_startup(sapi_module_struct *sf, zend_module_entry *additional_mod php_startup_auto_globals(); zend_set_utility_values(&zuv); php_startup_sapi_content_types(); - zend_observer_startup(); /* startup extensions statically compiled in */ if (php_register_internal_extensions_func() == FAILURE) { diff --git a/sapi/cli/tests/006.phpt b/sapi/cli/tests/006.phpt index eac538017837e..f3443b7475e64 100644 --- a/sapi/cli/tests/006.phpt +++ b/sapi/cli/tests/006.phpt @@ -125,7 +125,7 @@ string(%d) "Extension [ extension #%d pcre version %s ] { - Parameters [5] { Parameter #0 [ array $pattern ] - Parameter #1 [ $subject ] + Parameter #1 [ array|string $subject ] Parameter #2 [ int $limit = -1 ] Parameter #3 [ &$count = null ] Parameter #4 [ int $flags = 0 ] diff --git a/tests/classes/bug26737.phpt b/tests/classes/bug26737.phpt index f6f33fbf805f8..ea7ae1ed9a1cc 100644 --- a/tests/classes/bug26737.phpt +++ b/tests/classes/bug26737.phpt @@ -18,5 +18,5 @@ $data = serialize($foo); var_dump(str_replace("\0", '\0', $data)); ?> --EXPECTF-- -Notice: serialize(): "no_such" returned as member variable from __sleep() but does not exist in %s on line %d +Warning: serialize(): "no_such" returned as member variable from __sleep() but does not exist in %s on line %d string(114) "O:3:"foo":3:{s:12:"\0foo\0private";s:7:"private";s:12:"\0*\0protected";s:9:"protected";s:6:"public";s:6:"public";}" diff --git a/tests/lang/operators/divide_basiclong_64bit.phpt b/tests/lang/operators/divide_basiclong_64bit.phpt index 358d068843f11..65ab5b69a2212 100644 --- a/tests/lang/operators/divide_basiclong_64bit.phpt +++ b/tests/lang/operators/divide_basiclong_64bit.phpt @@ -23,10 +23,14 @@ $otherVals = array(0, 1, -1, 7, 9, 65, -44, MAX_32Bit, MAX_64Bit); error_reporting(E_ERROR); foreach ($longVals as $longVal) { - foreach($otherVals as $otherVal) { - echo "--- testing: $longVal / $otherVal ---\n"; - var_dump($longVal/$otherVal); - } + foreach($otherVals as $otherVal) { + echo "--- testing: $longVal / $otherVal ---\n"; + try { + var_dump($longVal/$otherVal); + } catch (\Throwable $e) { + echo get_class($e) . ': ' . $e->getMessage() . \PHP_EOL; + } + } } foreach ($otherVals as $otherVal) { @@ -39,7 +43,7 @@ foreach ($otherVals as $otherVal) { ?> --EXPECT-- --- testing: 9223372036854775807 / 0 --- -float(INF) +DivisionByZeroError: Division by zero --- testing: 9223372036854775807 / 1 --- int(9223372036854775807) --- testing: 9223372036854775807 / -1 --- @@ -57,7 +61,7 @@ float(4294967298) --- testing: 9223372036854775807 / 9223372036854775807 --- int(1) --- testing: -9223372036854775808 / 0 --- -float(-INF) +DivisionByZeroError: Division by zero --- testing: -9223372036854775808 / 1 --- int(-9223372036854775808) --- testing: -9223372036854775808 / -1 --- @@ -75,7 +79,7 @@ float(-4294967298) --- testing: -9223372036854775808 / 9223372036854775807 --- float(-1) --- testing: 2147483647 / 0 --- -float(INF) +DivisionByZeroError: Division by zero --- testing: 2147483647 / 1 --- int(2147483647) --- testing: 2147483647 / -1 --- @@ -93,7 +97,7 @@ int(1) --- testing: 2147483647 / 9223372036854775807 --- float(2.328306435454494E-10) --- testing: -2147483648 / 0 --- -float(-INF) +DivisionByZeroError: Division by zero --- testing: -2147483648 / 1 --- int(-2147483648) --- testing: -2147483648 / -1 --- @@ -111,7 +115,7 @@ float(-1.0000000004656613) --- testing: -2147483648 / 9223372036854775807 --- float(-2.3283064365386963E-10) --- testing: 9223372034707292160 / 0 --- -float(INF) +DivisionByZeroError: Division by zero --- testing: 9223372034707292160 / 1 --- int(9223372034707292160) --- testing: 9223372034707292160 / -1 --- @@ -129,7 +133,7 @@ float(4294967297) --- testing: 9223372034707292160 / 9223372036854775807 --- float(0.9999999997671694) --- testing: -9223372034707292160 / 0 --- -float(-INF) +DivisionByZeroError: Division by zero --- testing: -9223372034707292160 / 1 --- int(-9223372034707292160) --- testing: -9223372034707292160 / -1 --- @@ -147,7 +151,7 @@ float(-4294967297) --- testing: -9223372034707292160 / 9223372036854775807 --- float(-0.9999999997671694) --- testing: 2147483648 / 0 --- -float(INF) +DivisionByZeroError: Division by zero --- testing: 2147483648 / 1 --- int(2147483648) --- testing: 2147483648 / -1 --- @@ -165,7 +169,7 @@ float(1.0000000004656613) --- testing: 2147483648 / 9223372036854775807 --- float(2.3283064365386963E-10) --- testing: -2147483649 / 0 --- -float(-INF) +DivisionByZeroError: Division by zero --- testing: -2147483649 / 1 --- int(-2147483649) --- testing: -2147483649 / -1 --- @@ -183,7 +187,7 @@ float(-1.0000000009313226) --- testing: -2147483649 / 9223372036854775807 --- float(-2.3283064376228985E-10) --- testing: 4294967294 / 0 --- -float(INF) +DivisionByZeroError: Division by zero --- testing: 4294967294 / 1 --- int(4294967294) --- testing: 4294967294 / -1 --- @@ -201,7 +205,7 @@ int(2) --- testing: 4294967294 / 9223372036854775807 --- float(4.656612870908988E-10) --- testing: 4294967295 / 0 --- -float(INF) +DivisionByZeroError: Division by zero --- testing: 4294967295 / 1 --- int(4294967295) --- testing: 4294967295 / -1 --- @@ -219,7 +223,7 @@ float(2.0000000004656613) --- testing: 4294967295 / 9223372036854775807 --- float(4.6566128719931904E-10) --- testing: 4294967293 / 0 --- -float(INF) +DivisionByZeroError: Division by zero --- testing: 4294967293 / 1 --- int(4294967293) --- testing: 4294967293 / -1 --- @@ -237,7 +241,7 @@ float(1.9999999995343387) --- testing: 4294967293 / 9223372036854775807 --- float(4.656612869824786E-10) --- testing: 9223372036854775806 / 0 --- -float(INF) +DivisionByZeroError: Division by zero --- testing: 9223372036854775806 / 1 --- int(9223372036854775806) --- testing: 9223372036854775806 / -1 --- @@ -255,7 +259,7 @@ int(4294967298) --- testing: 9223372036854775806 / 9223372036854775807 --- float(1) --- testing: 9.2233720368548E+18 / 0 --- -float(INF) +DivisionByZeroError: Division by zero --- testing: 9.2233720368548E+18 / 1 --- float(9.223372036854776E+18) --- testing: 9.2233720368548E+18 / -1 --- @@ -273,7 +277,7 @@ float(4294967298) --- testing: 9.2233720368548E+18 / 9223372036854775807 --- float(1) --- testing: -9223372036854775807 / 0 --- -float(-INF) +DivisionByZeroError: Division by zero --- testing: -9223372036854775807 / 1 --- int(-9223372036854775807) --- testing: -9223372036854775807 / -1 --- @@ -291,7 +295,7 @@ float(-4294967298) --- testing: -9223372036854775807 / 9223372036854775807 --- int(-1) --- testing: -9.2233720368548E+18 / 0 --- -float(-INF) +DivisionByZeroError: Division by zero --- testing: -9.2233720368548E+18 / 1 --- float(-9.223372036854776E+18) --- testing: -9.2233720368548E+18 / -1 --- diff --git a/tests/lang/operators/divide_variationStr.phpt b/tests/lang/operators/divide_variationStr.phpt index be7118edbda4f..6c62972ffd38c 100644 --- a/tests/lang/operators/divide_variationStr.phpt +++ b/tests/lang/operators/divide_variationStr.phpt @@ -17,6 +17,8 @@ foreach ($strVals as $strVal) { var_dump($strVal/$otherVal); } catch (\TypeError $e) { echo $e->getMessage() . \PHP_EOL; + } catch (\DivisionByZeroError $e) { + echo $e->getMessage() . \PHP_EOL; } } } @@ -25,7 +27,7 @@ foreach ($strVals as $strVal) { ?> --EXPECT-- --- testing: '0'/'0' --- -float(NAN) +Division by zero --- testing: '0'/'65' --- int(0) --- testing: '0'/'-44' --- @@ -53,7 +55,7 @@ float(0) --- testing: '0'/'a5.9' --- Unsupported operand types: string / string --- testing: '65'/'0' --- -float(INF) +Division by zero --- testing: '65'/'65' --- int(1) --- testing: '65'/'-44' --- @@ -81,7 +83,7 @@ float(19.11764705882353) --- testing: '65'/'a5.9' --- Unsupported operand types: string / string --- testing: '-44'/'0' --- -float(-INF) +Division by zero --- testing: '-44'/'65' --- float(-0.676923076923077) --- testing: '-44'/'-44' --- @@ -109,7 +111,7 @@ float(-12.941176470588236) --- testing: '-44'/'a5.9' --- Unsupported operand types: string / string --- testing: '1.2'/'0' --- -float(INF) +Division by zero --- testing: '1.2'/'65' --- float(0.01846153846153846) --- testing: '1.2'/'-44' --- @@ -137,7 +139,7 @@ float(0.35294117647058826) --- testing: '1.2'/'a5.9' --- Unsupported operand types: string / string --- testing: '-7.7'/'0' --- -float(-INF) +Division by zero --- testing: '-7.7'/'65' --- float(-0.11846153846153847) --- testing: '-7.7'/'-44' --- @@ -193,7 +195,7 @@ Unsupported operand types: string / string --- testing: 'abc'/'a5.9' --- Unsupported operand types: string / string --- testing: '123abc'/'0' --- -float(INF) +Division by zero --- testing: '123abc'/'65' --- float(1.8923076923076922) --- testing: '123abc'/'-44' --- @@ -221,7 +223,7 @@ float(36.1764705882353) --- testing: '123abc'/'a5.9' --- Unsupported operand types: string / string --- testing: '123e5'/'0' --- -float(INF) +Division by zero --- testing: '123e5'/'65' --- float(189230.76923076922) --- testing: '123e5'/'-44' --- @@ -249,7 +251,7 @@ float(3617647.0588235296) --- testing: '123e5'/'a5.9' --- Unsupported operand types: string / string --- testing: '123e5xyz'/'0' --- -float(INF) +Division by zero --- testing: '123e5xyz'/'65' --- float(189230.76923076922) --- testing: '123e5xyz'/'-44' --- @@ -277,7 +279,7 @@ float(3617647.0588235296) --- testing: '123e5xyz'/'a5.9' --- Unsupported operand types: string / string --- testing: ' 123abc'/'0' --- -float(INF) +Division by zero --- testing: ' 123abc'/'65' --- float(1.8923076923076922) --- testing: ' 123abc'/'-44' --- @@ -305,7 +307,7 @@ float(36.1764705882353) --- testing: ' 123abc'/'a5.9' --- Unsupported operand types: string / string --- testing: '123 abc'/'0' --- -float(INF) +Division by zero --- testing: '123 abc'/'65' --- float(1.8923076923076922) --- testing: '123 abc'/'-44' --- @@ -333,7 +335,7 @@ float(36.1764705882353) --- testing: '123 abc'/'a5.9' --- Unsupported operand types: string / string --- testing: '123abc '/'0' --- -float(INF) +Division by zero --- testing: '123abc '/'65' --- float(1.8923076923076922) --- testing: '123abc '/'-44' --- @@ -361,7 +363,7 @@ float(36.1764705882353) --- testing: '123abc '/'a5.9' --- Unsupported operand types: string / string --- testing: '3.4a'/'0' --- -float(INF) +Division by zero --- testing: '3.4a'/'65' --- float(0.052307692307692305) --- testing: '3.4a'/'-44' ---