]> granicus.if.org Git - php/commitdiff
Fix number of required parameters in printf
authorNikita Popov <nikita.ppv@gmail.com>
Tue, 21 Apr 2020 15:00:12 +0000 (17:00 +0200)
committerNikita Popov <nikita.ppv@gmail.com>
Tue, 21 Apr 2020 15:01:47 +0000 (17:01 +0200)
If n$ references are involved, the maximum argnum referenced may
not the one at the end. Store it explicitly.

ext/standard/formatted_print.c
ext/standard/tests/strings/sprintf_error.phpt

index ad8a79960c282ef573371cbfd3756f6af3ef2d05..f99187b1c8e797b88ebeef3814ad8effdbad6b67 100644 (file)
@@ -399,7 +399,7 @@ php_formatted_print(char *format, size_t format_len, zval *args, int argc, int n
        char *temppos, padding;
        zend_string *result;
        int always_sign;
-       int bad_arg_number = 0;
+       int max_missing_argnum = -1;
 
        result = zend_string_alloc(size, 0);
 
@@ -527,7 +527,7 @@ php_formatted_print(char *format, size_t format_len, zval *args, int argc, int n
                        PRINTF_DEBUG(("sprintf: format character='%c'\n", *format));
 
                        if (argnum >= argc) {
-                               bad_arg_number = 1;
+                               max_missing_argnum = MAX(max_missing_argnum, argnum);
                                continue;
                        }
 
@@ -626,12 +626,12 @@ php_formatted_print(char *format, size_t format_len, zval *args, int argc, int n
                }
        }
 
-       if (bad_arg_number == 1) {
+       if (max_missing_argnum >= 0) {
                efree(result);
                if (nb_additional_parameters == -1) {
-                       zend_value_error("The arguments array must contain %d items, %d given", argnum + 1, argc);
+                       zend_value_error("The arguments array must contain %d items, %d given", max_missing_argnum + 1, argc);
                } else {
-                       zend_argument_count_error("%d parameters are required, %d given", argnum + nb_additional_parameters + 1, argc + nb_additional_parameters);
+                       zend_argument_count_error("%d parameters are required, %d given", max_missing_argnum + nb_additional_parameters + 1, argc + nb_additional_parameters);
                }
                return NULL;
        }
index 4ba7a539feab6126f694e7b5afea471a1dfb010a..bc34b1d0f3dc63efafa1edf3f72649a11560139b 100644 (file)
@@ -60,6 +60,12 @@ try {
     echo $e->getMessage(), "\n";
 }
 
+try {
+    var_dump(sprintf('%100$d %d'));
+} catch (\ArgumentCountError $e) {
+    echo $e->getMessage(), "\n";
+}
+
 echo "Done";
 ?>
 --EXPECTF--
@@ -75,4 +81,5 @@ sprintf() expects at least %d parameter, %d given
 3 parameters are required, 1 given
 4 parameters are required, 2 given
 4 parameters are required, 1 given
+101 parameters are required, 1 given
 Done