From cbf86efc218e203ec692941aab8ab8077ab63f1b Mon Sep 17 00:00:00 2001 From: =?utf8?q?M=C3=A1t=C3=A9=20Kocsis?= Date: Mon, 25 May 2020 17:29:46 +0200 Subject: [PATCH] Fix ZPP of v*printf() --- UPGRADING | 2 + ext/standard/basic_functions.stub.php | 13 ++-- ext/standard/basic_functions_arginfo.h | 6 +- ext/standard/formatted_print.c | 26 ++++--- .../tests/strings/vfprintf_error3.phpt | 9 ++- .../tests/strings/vfprintf_variation1.phpt | 19 +++--- .../tests/strings/vprintf_variation2.phpt | 68 +++++++------------ 7 files changed, 66 insertions(+), 77 deletions(-) diff --git a/UPGRADING b/UPGRADING index 87e12f23ab..c67d619355 100644 --- a/UPGRADING +++ b/UPGRADING @@ -386,6 +386,8 @@ PHP 8.0 UPGRADE NOTES . The length argument for array_splice() can now be null. Null values will behave identically to omitting the argument, thus removing everything from the 'offset' to the end of the array. + . The args argument of vsprintf(), vfprintf(), and vprintf() must now be an + array. Previously any type was accepted. . The 'salt' option of password_hash() is no longer supported. If the 'salt' option is used a warning is generated, the provided salt is ignored, and a generated salt is used instead. diff --git a/ext/standard/basic_functions.stub.php b/ext/standard/basic_functions.stub.php index 71b922d7b2..21c711111e 100755 --- a/ext/standard/basic_functions.stub.php +++ b/ext/standard/basic_functions.stub.php @@ -966,11 +966,9 @@ function sprintf(string $format, ...$args): string {} /** @param mixed ...$args */ function printf(string $format, ...$args): int {} -/** @param mixed $args */ -function vprintf(string $format, $args): int {} +function vprintf(string $format, array $args): int {} -/** @param mixed $args */ -function vsprintf(string $format, $args): string {} +function vsprintf(string $format, array $args): string {} /** * @param resource $handle @@ -978,11 +976,8 @@ function vsprintf(string $format, $args): string {} */ function fprintf($handle, string $format, ...$args): int {} -/** - * @param resource $handle - * @param mixed $args - */ -function vfprintf($handle, string $format, $args): int {} +/** @param resource $handle */ +function vfprintf($handle, string $format, array $args): int {} /* fsock.c */ diff --git a/ext/standard/basic_functions_arginfo.h b/ext/standard/basic_functions_arginfo.h index 23152bc22e..b646c698d9 100755 --- a/ext/standard/basic_functions_arginfo.h +++ b/ext/standard/basic_functions_arginfo.h @@ -1480,12 +1480,12 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_vprintf, 0, 2, IS_LONG, 0) ZEND_ARG_TYPE_INFO(0, format, IS_STRING, 0) - ZEND_ARG_INFO(0, args) + ZEND_ARG_TYPE_INFO(0, args, IS_ARRAY, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_vsprintf, 0, 2, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, format, IS_STRING, 0) - ZEND_ARG_INFO(0, args) + ZEND_ARG_TYPE_INFO(0, args, IS_ARRAY, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_fprintf, 0, 2, IS_LONG, 0) @@ -1497,7 +1497,7 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_vfprintf, 0, 3, IS_LONG, 0) ZEND_ARG_INFO(0, handle) ZEND_ARG_TYPE_INFO(0, format, IS_STRING, 0) - ZEND_ARG_INFO(0, args) + ZEND_ARG_TYPE_INFO(0, args, IS_ARRAY, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_fsockopen, 0, 0, 1) diff --git a/ext/standard/formatted_print.c b/ext/standard/formatted_print.c index 3448b86bc2..d982de7420 100644 --- a/ext/standard/formatted_print.c +++ b/ext/standard/formatted_print.c @@ -651,20 +651,15 @@ fail: /* }}} */ /* php_formatted_print_get_array() {{{ */ -static zval* -php_formatted_print_get_array(zval *array, int *argc) +static zval *php_formatted_print_get_array(zend_array *array, int *argc) { zval *args, *zv; int n; - if (Z_TYPE_P(array) != IS_ARRAY) { - convert_to_array(array); - } - - n = zend_hash_num_elements(Z_ARRVAL_P(array)); + n = zend_hash_num_elements(array); args = (zval *)safe_emalloc(n, sizeof(zval), 0); n = 0; - ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(array), zv) { + ZEND_HASH_FOREACH_VAL(array, zv) { ZVAL_COPY_VALUE(&args[n], zv); n++; } ZEND_HASH_FOREACH_END(); @@ -704,12 +699,13 @@ PHP_FUNCTION(vsprintf) zend_string *result; char *format; size_t format_len; - zval *array, *args; + zval *args; + zend_array *array; int argc; ZEND_PARSE_PARAMETERS_START(2, 2) Z_PARAM_STRING(format, format_len) - Z_PARAM_ZVAL(array) + Z_PARAM_ARRAY_HT(array) ZEND_PARSE_PARAMETERS_END(); args = php_formatted_print_get_array(array, &argc); @@ -757,12 +753,13 @@ PHP_FUNCTION(vprintf) size_t rlen; char *format; size_t format_len; - zval *array, *args; + zval *args; + zend_array *array; int argc; ZEND_PARSE_PARAMETERS_START(2, 2) Z_PARAM_STRING(format, format_len) - Z_PARAM_ZVAL(array) + Z_PARAM_ARRAY_HT(array) ZEND_PARSE_PARAMETERS_END(); args = php_formatted_print_get_array(array, &argc); @@ -820,7 +817,8 @@ PHP_FUNCTION(vfprintf) php_stream *stream; char *format; size_t format_len; - zval *arg1, *array, *args; + zval *arg1, *args; + zend_array *array; int argc; zend_string *result; @@ -831,7 +829,7 @@ PHP_FUNCTION(vfprintf) ZEND_PARSE_PARAMETERS_START(3, 3) Z_PARAM_RESOURCE(arg1) Z_PARAM_STRING(format, format_len) - Z_PARAM_ZVAL(array) + Z_PARAM_ARRAY_HT(array) ZEND_PARSE_PARAMETERS_END(); php_stream_from_zval(stream, arg1); diff --git a/ext/standard/tests/strings/vfprintf_error3.phpt b/ext/standard/tests/strings/vfprintf_error3.phpt index e409f8741b..d7ebdce3e2 100644 --- a/ext/standard/tests/strings/vfprintf_error3.phpt +++ b/ext/standard/tests/strings/vfprintf_error3.phpt @@ -24,7 +24,13 @@ try { } try { - var_dump( vfprintf( $fp, "Foo %y fake", "not available" ) ); + vfprintf($fp, "Foo: %s", "not available"); +} catch (TypeError $e) { + echo $e->getMessage(), "\n"; +} + +try { + vfprintf($fp, "Foo %y fake", ["not available"]); } catch (ValueError $e) { echo $e->getMessage(), "\n"; } @@ -48,5 +54,6 @@ unlink( $file ); --EXPECT-- -- Testing vfprintf() function with wrong variable types as argument -- vfprintf(): Argument #2 ($format) must be of type string, array given +vfprintf(): Argument #3 ($args) must be of type array, string given Unknown format specifier 'y' string(0) "" diff --git a/ext/standard/tests/strings/vfprintf_variation1.phpt b/ext/standard/tests/strings/vfprintf_variation1.phpt index d7120e41c0..bd8ba985cb 100644 --- a/ext/standard/tests/strings/vfprintf_variation1.phpt +++ b/ext/standard/tests/strings/vfprintf_variation1.phpt @@ -32,12 +32,16 @@ class FooClass // Output facilitating function function writeAndDump($fp, $format, $args) { - ftruncate( $fp, 0 ); - $length = vfprintf( $fp, $format, $args ); - rewind( $fp ); - $content = stream_get_contents( $fp ); - var_dump( $content ); - var_dump( $length ); + try { + ftruncate( $fp, 0 ); + $length = vfprintf( $fp, $format, $args ); + rewind( $fp ); + $content = stream_get_contents( $fp ); + var_dump( $content ); + var_dump( $length ); + } catch (TypeError $exception) { + echo $exception->getMessage() . "\n"; + } } // Test vfprintf() @@ -62,8 +66,7 @@ unlink( $file ); ?> --EXPECT-- *** Testing vfprintf() : variation functionality *** -string(6) "format" -int(6) +vfprintf(): Argument #3 ($args) must be of type array, null given string(17) "Foo is 30 and bar" int(17) string(14) "Foobar testing" diff --git a/ext/standard/tests/strings/vprintf_variation2.phpt b/ext/standard/tests/strings/vprintf_variation2.phpt index 12ffb6dd1f..30892395fe 100644 --- a/ext/standard/tests/strings/vprintf_variation2.phpt +++ b/ext/standard/tests/strings/vprintf_variation2.phpt @@ -88,6 +88,8 @@ foreach($values as $value) { $result = vprintf($format,$value); echo "\n"; var_dump($result); + } catch (\TypeError $e) { + echo $e->getMessage(), "\n"; } catch (\ValueError $e) { echo $e->getMessage(), "\n"; } @@ -98,92 +100,74 @@ foreach($values as $value) { fclose($file_handle); ?> ---EXPECTF-- +--EXPECT-- *** Testing vprintf() : with unexpected values for args argument *** -- Iteration 1 -- -0 -int(1) +vprintf(): Argument #2 ($args) must be of type array, int given -- Iteration 2 -- -1 -int(1) +vprintf(): Argument #2 ($args) must be of type array, int given -- Iteration 3 -- -12345 -int(5) +vprintf(): Argument #2 ($args) must be of type array, int given -- Iteration 4 -- --2345 -int(5) +vprintf(): Argument #2 ($args) must be of type array, int given -- Iteration 5 -- -10.5 -int(4) +vprintf(): Argument #2 ($args) must be of type array, float given -- Iteration 6 -- --10.5 -int(5) +vprintf(): Argument #2 ($args) must be of type array, float given -- Iteration 7 -- -101234567000 -int(12) +vprintf(): Argument #2 ($args) must be of type array, float given -- Iteration 8 -- -1.07654321E-9 -int(13) +vprintf(): Argument #2 ($args) must be of type array, float given -- Iteration 9 -- -0.5 -int(3) +vprintf(): Argument #2 ($args) must be of type array, float given -- Iteration 10 -- -The arguments array must contain 1 items, 0 given +vprintf(): Argument #2 ($args) must be of type array, null given -- Iteration 11 -- -The arguments array must contain 1 items, 0 given +vprintf(): Argument #2 ($args) must be of type array, null given -- Iteration 12 -- -1 -int(1) +vprintf(): Argument #2 ($args) must be of type array, bool given -- Iteration 13 -- - -int(0) +vprintf(): Argument #2 ($args) must be of type array, bool given -- Iteration 14 -- -1 -int(1) +vprintf(): Argument #2 ($args) must be of type array, bool given -- Iteration 15 -- - -int(0) +vprintf(): Argument #2 ($args) must be of type array, bool given -- Iteration 16 -- - -int(0) +vprintf(): Argument #2 ($args) must be of type array, string given -- Iteration 17 -- - -int(0) +vprintf(): Argument #2 ($args) must be of type array, string given -- Iteration 18 -- -string -int(6) +vprintf(): Argument #2 ($args) must be of type array, string given -- Iteration 19 -- -string -int(6) +vprintf(): Argument #2 ($args) must be of type array, string given -- Iteration 20 -- -The arguments array must contain 1 items, 0 given +vprintf(): Argument #2 ($args) must be of type array, object given -- Iteration 21 -- -The arguments array must contain 1 items, 0 given +vprintf(): Argument #2 ($args) must be of type array, null given -- Iteration 22 -- -The arguments array must contain 1 items, 0 given +vprintf(): Argument #2 ($args) must be of type array, null given -- Iteration 23 -- -Resource id #%d -int(%d) +vprintf(): Argument #2 ($args) must be of type array, resource given -- 2.40.0