]> granicus.if.org Git - php/commitdiff
Convert warnings to Errors in sprintf() functions
authorkharhamel <oognic@gmail.com>
Tue, 15 Oct 2019 15:51:39 +0000 (17:51 +0200)
committerNikita Popov <nikita.ppv@gmail.com>
Mon, 28 Oct 2019 10:58:59 +0000 (11:58 +0100)
Closes GH-4837.

ext/standard/formatted_print.c
ext/standard/tests/file/fscanf_variation14.phpt
ext/standard/tests/strings/printf_64bit.phpt
ext/standard/tests/strings/printf_error.phpt
ext/standard/tests/strings/sprintf_error.phpt
ext/standard/tests/strings/vfprintf_error4.phpt
ext/standard/tests/strings/vfprintf_variation21.phpt
ext/standard/tests/strings/vprintf_variation2.phpt
ext/standard/tests/strings/vsprintf_variation2.phpt
tests/strings/002.phpt

index b91a41de5419a18b247911475bd158f8e7bc55a5..a5acaeea9bd7e0ba6bf0feead7b3eb26458e7ffe 100644 (file)
@@ -387,9 +387,12 @@ php_sprintf_getnumber(char **buffer, size_t *len)
  *  "x"   integer argument is printed as lowercase hexadecimal
  *  "X"   integer argument is printed as uppercase hexadecimal
  *
+ * nb_additional_parameters is used for throwing errors:
+ *  - -1: ValueError is thrown (for vsprintf where args originates from an array)
+ *  - 0 or more: ArgumentCountError is thrown
  */
 static zend_string *
-php_formatted_print(zval *z_format, zval *args, int argc)
+php_formatted_print(zval *z_format, zval *args, int argc, int nb_additional_parameters)
 {
        size_t size = 240, outpos = 0;
        int alignment, currarg, adjusting, argnum, width, precision;
@@ -397,6 +400,7 @@ php_formatted_print(zval *z_format, zval *args, int argc)
        zend_string *result;
        int always_sign;
        size_t format_len;
+       int bad_arg_number = 0;
 
        if (!try_convert_to_string(z_format)) {
                return NULL;
@@ -407,6 +411,7 @@ php_formatted_print(zval *z_format, zval *args, int argc)
        result = zend_string_alloc(size, 0);
 
        currarg = 0;
+       argnum = 0;
 
        while (format_len) {
                int expprec;
@@ -450,7 +455,7 @@ php_formatted_print(zval *z_format, zval *args, int argc)
 
                                        if (argnum <= 0) {
                                                zend_string_efree(result);
-                                               php_error_docref(NULL, E_WARNING, "Argument number must be greater than zero");
+                                               zend_value_error("Argument number must be greater than zero");
                                                return NULL;
                                        }
                                        argnum--;
@@ -491,7 +496,7 @@ php_formatted_print(zval *z_format, zval *args, int argc)
                                        PRINTF_DEBUG(("sprintf: getting width\n"));
                                        if ((width = php_sprintf_getnumber(&format, &format_len)) < 0) {
                                                efree(result);
-                                               php_error_docref(NULL, E_WARNING, "Width must be greater than zero and less than %d", INT_MAX);
+                                               zend_value_error("Width must be greater than zero and less than %d", INT_MAX);
                                                return NULL;
                                        }
                                        adjusting |= ADJ_WIDTH;
@@ -508,7 +513,7 @@ php_formatted_print(zval *z_format, zval *args, int argc)
                                        if (isdigit((int)*format)) {
                                                if ((precision = php_sprintf_getnumber(&format, &format_len)) < 0) {
                                                        efree(result);
-                                                       php_error_docref(NULL, E_WARNING, "Precision must be greater than zero and less than %d", INT_MAX);
+                                                       zend_value_error("Precision must be greater than zero and less than %d", INT_MAX);
                                                        return NULL;
                                                }
                                                adjusting |= ADJ_PRECISION;
@@ -522,17 +527,17 @@ php_formatted_print(zval *z_format, zval *args, int argc)
                                PRINTF_DEBUG(("sprintf: precision=%d\n", precision));
                        }
 
-                       if (argnum >= argc) {
-                               efree(result);
-                               php_error_docref(NULL, E_WARNING, "Too few arguments");
-                               return NULL;
-                       }
-
                        if (*format == 'l') {
                                format++;
                                format_len--;
                        }
                        PRINTF_DEBUG(("sprintf: format character='%c'\n", *format));
+
+                       if (argnum >= argc) {
+                               bad_arg_number = 1;
+                               continue;
+                       }
+
                        /* now we expect to find a type specifier */
                        tmp = &args[argnum];
                        switch (*format) {
@@ -628,6 +633,16 @@ php_formatted_print(zval *z_format, zval *args, int argc)
                }
        }
 
+       if (bad_arg_number == 1) {
+               efree(result);
+               if (nb_additional_parameters == -1) {
+                       zend_value_error("The arguments array must contain %d items, %d given", argnum + 1, argc);
+               } else {
+                       zend_argument_count_error("%d parameters are required, %d given", argnum + nb_additional_parameters + 1, argc + nb_additional_parameters);
+               }
+               return NULL;
+       }
+
 exit:
        /* possibly, we have to make sure we have room for the terminating null? */
        ZSTR_VAL(result)[outpos]=0;
@@ -660,7 +675,7 @@ php_formatted_print_get_array(zval *array, int *argc)
 }
 /* }}} */
 
-/* {{{ proto string|false sprintf(string format [, mixed arg1 [, mixed ...]])
+/* {{{ proto string sprintf(string format [, mixed arg1 [, mixed ...]])
    Return a formatted string */
 PHP_FUNCTION(user_sprintf)
 {
@@ -673,15 +688,15 @@ PHP_FUNCTION(user_sprintf)
                Z_PARAM_VARIADIC('*', args, argc)
        ZEND_PARSE_PARAMETERS_END();
 
-       result = php_formatted_print(format, args, argc);
+       result = php_formatted_print(format, args, argc, 1);
        if (result == NULL) {
-               RETURN_FALSE;
+               return;
        }
        RETVAL_STR(result);
 }
 /* }}} */
 
-/* {{{ proto string|false vsprintf(string format, array args)
+/* {{{ proto string vsprintf(string format, array args)
    Return a formatted string */
 PHP_FUNCTION(vsprintf)
 {
@@ -696,16 +711,16 @@ PHP_FUNCTION(vsprintf)
 
        args = php_formatted_print_get_array(array, &argc);
 
-       result = php_formatted_print(format, args, argc);
+       result = php_formatted_print(format, args, argc, -1);
        efree(args);
        if (result == NULL) {
-               RETURN_FALSE;
+               return;
        }
        RETVAL_STR(result);
 }
 /* }}} */
 
-/* {{{ proto int|false printf(string format [, mixed arg1 [, mixed ...]])
+/* {{{ proto int printf(string format [, mixed arg1 [, mixed ...]])
    Output a formatted string */
 PHP_FUNCTION(user_printf)
 {
@@ -719,9 +734,9 @@ PHP_FUNCTION(user_printf)
                Z_PARAM_VARIADIC('*', args, argc)
        ZEND_PARSE_PARAMETERS_END();
 
-       result = php_formatted_print(format, args, argc);
+       result = php_formatted_print(format, args, argc, 1);
        if (result == NULL) {
-               RETURN_FALSE;
+               return;
        }
        rlen = PHPWRITE(ZSTR_VAL(result), ZSTR_LEN(result));
        zend_string_efree(result);
@@ -729,7 +744,7 @@ PHP_FUNCTION(user_printf)
 }
 /* }}} */
 
-/* {{{ proto int|false vprintf(string format, array args)
+/* {{{ proto int vprintf(string format, array args)
    Output a formatted string */
 PHP_FUNCTION(vprintf)
 {
@@ -745,10 +760,10 @@ PHP_FUNCTION(vprintf)
 
        args = php_formatted_print_get_array(array, &argc);
 
-       result = php_formatted_print(format, args, argc);
+       result = php_formatted_print(format, args, argc, -1);
        efree(args);
        if (result == NULL) {
-               RETURN_FALSE;
+               return;
        }
        rlen = PHPWRITE(ZSTR_VAL(result), ZSTR_LEN(result));
        zend_string_efree(result);
@@ -756,7 +771,7 @@ PHP_FUNCTION(vprintf)
 }
 /* }}} */
 
-/* {{{ proto int|false fprintf(resource stream, string format [, mixed arg1 [, mixed ...]])
+/* {{{ proto int fprintf(resource stream, string format [, mixed arg1 [, mixed ...]])
    Output a formatted string into a stream */
 PHP_FUNCTION(fprintf)
 {
@@ -777,9 +792,9 @@ PHP_FUNCTION(fprintf)
 
        php_stream_from_zval(stream, arg1);
 
-       result = php_formatted_print(format, args, argc);
+       result = php_formatted_print(format, args, argc, 2);
        if (result == NULL) {
-               RETURN_FALSE;
+               return;
        }
 
        php_stream_write(stream, ZSTR_VAL(result), ZSTR_LEN(result));
@@ -789,7 +804,7 @@ PHP_FUNCTION(fprintf)
 }
 /* }}} */
 
-/* {{{ proto int|false vfprintf(resource stream, string format, array args)
+/* {{{ proto int vfprintf(resource stream, string format, array args)
    Output a formatted string into a stream */
 PHP_FUNCTION(vfprintf)
 {
@@ -812,10 +827,10 @@ PHP_FUNCTION(vfprintf)
 
        args = php_formatted_print_get_array(array, &argc);
 
-       result = php_formatted_print(format, args, argc);
+       result = php_formatted_print(format, args, argc, -1);
        efree(args);
        if (result == NULL) {
-               RETURN_FALSE;
+               return;
        }
 
        php_stream_write(stream, ZSTR_VAL(result), ZSTR_LEN(result));
index 47caaa3568ad4e2c3794971cd794ed74fb0764ff..151c975776b92a3df596d01e1b79d0f6041ee68f 100644 (file)
@@ -76,8 +76,12 @@ $counter = 1;
 
 // writing to the file
 foreach($valid_strings as $string) {
-  @fprintf($file_handle, $string);
-  @fprintf($file_handle, "\n");
+    try {
+        fprintf($file_handle, $string);
+    } catch (\ValueError $e) {
+    } catch (\ArgumentCountError $e) {
+    }
+  fprintf($file_handle, "\n");
 }
 // closing the file
 fclose($file_handle);
index 0106f71445bd4819ccce4b63ccd4b203f89229c1..9d3b4484958001061460e699240258b38f9d17d9 100644 (file)
@@ -39,7 +39,11 @@ echo "\n*** Output for insufficient number of arguments ***\n";
 $string = "dingy%sflem%dwombat";
 $nbr = 5;
 $name = "voudras";
-printf("%d $string %s", $nbr, $name);
+try {
+    printf("%d $string %s", $nbr, $name);
+} catch (\ArgumentCountError $e) {
+    print('Error found: '.$e->getMessage());
+}
 
 
 /* Scalar argument */
@@ -233,9 +237,7 @@ printf("%d", $tempstring);
 printf() expects at least 1 parameter, 0 given
 
 *** Output for insufficient number of arguments ***
-
-Warning: printf(): Too few arguments in %s on line %d
-
+Error found: 5 parameters are required, 3 given
 *** Output for scalar argument ***
 3
 *** Output for NULL as argument ***
index aff95426e6ab7ca6f8bace4d3fbf74c6500086b0..e5bd8c7e21fca22094fc2a634354244b7f3ac50e 100644 (file)
@@ -25,16 +25,40 @@ $arg1 = 'one';
 $arg2 = 'two';
 
 echo "\n-- Call printf with one argument less than expected --\n";
-var_dump( printf($format1) );
-var_dump( printf($format2,$arg1) );
-var_dump( printf($format3,$arg1,$arg2) );
+try {
+    var_dump( printf($format1) );
+} catch (\ArgumentCountError $e) {
+    echo $e->getMessage(), "\n";
+}
+try {
+    var_dump( printf($format2,$arg1) );
+} catch (\ArgumentCountError $e) {
+    echo $e->getMessage(), "\n";
+}
+try {
+    var_dump( printf($format3,$arg1,$arg2) );
+} catch (\ArgumentCountError $e) {
+    echo $e->getMessage(), "\n";
+}
 
 echo "\n-- Call printf with two argument less than expected --\n";
-var_dump( printf($format2) );
-var_dump( printf($format3,$arg1) );
+try {
+    var_dump( printf($format2) );
+} catch (\ArgumentCountError $e) {
+    echo $e->getMessage(), "\n";
+}
+try {
+    var_dump( printf($format3,$arg1) );
+} catch (\ArgumentCountError $e) {
+    echo $e->getMessage(), "\n";
+}
 
 echo "\n-- Call printf with three argument less than expected --\n";
-var_dump( printf($format3) );
+try {
+    var_dump( printf($format3) );
+} catch (\ArgumentCountError $e) {
+    echo $e->getMessage(), "\n";
+}
 
 ?>
 ===DONE===
@@ -47,26 +71,14 @@ printf() expects at least 1 parameter, 0 given
 -- Testing printf() function with less than expected no. of arguments --
 
 -- Call printf with one argument less than expected --
-
-Warning: printf(): Too few arguments in %s on line %d
-bool(false)
-
-Warning: printf(): Too few arguments in %s on line %d
-bool(false)
-
-Warning: printf(): Too few arguments in %s on line %d
-bool(false)
+2 parameters are required, 1 given
+3 parameters are required, 2 given
+4 parameters are required, 3 given
 
 -- Call printf with two argument less than expected --
-
-Warning: printf(): Too few arguments in %s on line %d
-bool(false)
-
-Warning: printf(): Too few arguments in %s on line %d
-bool(false)
+3 parameters are required, 1 given
+4 parameters are required, 2 given
 
 -- Call printf with three argument less than expected --
-
-Warning: printf(): Too few arguments in %s on line %d
-bool(false)
+4 parameters are required, 1 given
 ===DONE===
index 1b21b8b141cfbb81c0401631dfb2dd1e10be5229..4ba7a539feab6126f694e7b5afea471a1dfb010a 100644 (file)
@@ -25,16 +25,40 @@ $arg1 = 'one';
 $arg2 = 'two';
 
 // with one argument less than expected
-var_dump( sprintf($format1) );
-var_dump( sprintf($format2,$arg1) );
-var_dump( sprintf($format3,$arg1,$arg2) );
+try {
+    var_dump( sprintf($format1) );
+} catch (\ArgumentCountError $e) {
+    echo $e->getMessage(), "\n";
+}
+try {
+    var_dump( sprintf($format2,$arg1) );
+} catch (\ArgumentCountError $e) {
+    echo $e->getMessage(), "\n";
+}
+try {
+    var_dump( sprintf($format3,$arg1,$arg2) );
+} catch (\ArgumentCountError $e) {
+    echo $e->getMessage(), "\n";
+}
 
 // with two argument less than expected
-var_dump( sprintf($format2) );
-var_dump( sprintf($format3,$arg1) );
+try {
+    var_dump( sprintf($format2) );
+} catch (\ArgumentCountError $e) {
+    echo $e->getMessage(), "\n";
+}
+try {
+    var_dump( sprintf($format3,$arg1) );
+} catch (\ArgumentCountError $e) {
+    echo $e->getMessage(), "\n";
+}
 
 // with three argument less than expected
-var_dump( sprintf($format3) );
+try {
+    var_dump( sprintf($format3) );
+} catch (\ArgumentCountError $e) {
+    echo $e->getMessage(), "\n";
+}
 
 echo "Done";
 ?>
@@ -45,22 +69,10 @@ echo "Done";
 sprintf() expects at least %d parameter, %d given
 
 -- Testing sprintf() function with less than expected no. of arguments --
-
-Warning: sprintf(): Too few arguments in %s on line %d
-bool(false)
-
-Warning: sprintf(): Too few arguments in %s on line %d
-bool(false)
-
-Warning: sprintf(): Too few arguments in %s on line %d
-bool(false)
-
-Warning: sprintf(): Too few arguments in %s on line %d
-bool(false)
-
-Warning: sprintf(): Too few arguments in %s on line %d
-bool(false)
-
-Warning: sprintf(): Too few arguments in %s on line %d
-bool(false)
+2 parameters are required, 1 given
+3 parameters are required, 2 given
+4 parameters are required, 3 given
+3 parameters are required, 1 given
+4 parameters are required, 2 given
+4 parameters are required, 1 given
 Done
index e54e34f4cdf6345b69f6dc56e0714b25e0556958..9ccd83b2d8346f280267e981145fa3ef858d8028 100644 (file)
@@ -22,8 +22,11 @@ try {
 } catch (TypeError $e) {
     echo $e->getMessage(), "\n";
 }
-var_dump( vfprintf( $fp, 'Foo %$c-0202Sd', array( 2 ) ) );
-
+try {
+    var_dump( vfprintf( $fp, 'Foo %$c-0202Sd', array( 2 ) ) );
+} catch(\ValueError $e) {
+    print('Error found: '.$e->getMessage().".\n");
+}
 // Close handle
 fclose( $fp );
 
@@ -39,7 +42,5 @@ unlink( $file );
 --EXPECTF--
 -- Testing vfprintf() function with other strangeties  --
 vfprintf() expects parameter 1 to be resource, string given
-
-Warning: vfprintf(): Argument number must be greater than zero in %s on line %d
-bool(false)
+Error found: Argument number must be greater than zero.
 ===DONE===
index 11f29e87acc59959bfe657557cdc94d94e4dd60e..1358154f9510c002f5903fef14c043da5e9e1824 100644 (file)
@@ -90,7 +90,11 @@ fprintf($fp, "\n*** Testing vprintf() with unexpected values for args argument *
 $counter = 1;
 foreach( $values as $value ) {
   fprintf($fp, "\n-- Iteration %d --\n",$counter);
-  vfprintf($fp, $format, $value);
+  try {
+       vfprintf($fp, $format, $value);
+  } catch (\ValueError $e) {
+       fwrite($fp, $e->getMessage() . "\n");
+  }
   $counter++;
 }
 
@@ -106,16 +110,6 @@ unlink($data_file);
 --EXPECTF--
 *** Testing vfprintf() : with unexpected values for args argument ***
 
-Warning: vfprintf(): Too few arguments in %s on line %d
-
-Warning: vfprintf(): Too few arguments in %s on line %d
-
-Warning: vfprintf(): Too few arguments in %s on line %d
-
-Warning: vfprintf(): Too few arguments in %s on line %d
-
-Warning: vfprintf(): Too few arguments in %s on line %d
-
 *** Testing vprintf() with unexpected values for args argument ***
 
 -- Iteration 1 --
@@ -137,8 +131,10 @@ Warning: vfprintf(): Too few arguments in %s on line %d
 -- Iteration 9 --
 0.5
 -- Iteration 10 --
+The arguments array must contain 1 items, 0 given
 
 -- Iteration 11 --
+The arguments array must contain 1 items, 0 given
 
 -- Iteration 12 --
 1
@@ -157,10 +153,13 @@ string
 -- Iteration 19 --
 string
 -- Iteration 20 --
+The arguments array must contain 1 items, 0 given
 
 -- Iteration 21 --
+The arguments array must contain 1 items, 0 given
 
 -- Iteration 22 --
+The arguments array must contain 1 items, 0 given
 
 -- Iteration 23 --
 Resource id #%d
index 69e17d21a75e1fc10146497ae6ab2d835ba0b29b..a26d3590bc83ebc5263f725666cabfa0d1792d45 100644 (file)
@@ -84,9 +84,13 @@ $values = array(
 $counter = 1;
 foreach($values as $value) {
   echo "\n-- Iteration $counter --\n";
-  $result = vprintf($format,$value);
-  echo "\n";
-  var_dump($result);
+  try {
+       $result = vprintf($format,$value);
+       echo "\n";
+       var_dump($result);
+  } catch (\ValueError $e) {
+       echo $e->getMessage(), "\n";
+  }
   $counter++;
 };
 
@@ -135,16 +139,10 @@ int(13)
 int(3)
 
 -- Iteration 10 --
-
-Warning: vprintf(): Too few arguments in %s on line %d
-
-bool(false)
+The arguments array must contain 1 items, 0 given
 
 -- Iteration 11 --
-
-Warning: vprintf(): Too few arguments in %s on line %d
-
-bool(false)
+The arguments array must contain 1 items, 0 given
 
 -- Iteration 12 --
 1
@@ -179,22 +177,13 @@ string
 int(6)
 
 -- Iteration 20 --
-
-Warning: vprintf(): Too few arguments in %s on line %d
-
-bool(false)
+The arguments array must contain 1 items, 0 given
 
 -- Iteration 21 --
-
-Warning: vprintf(): Too few arguments in %s on line %d
-
-bool(false)
+The arguments array must contain 1 items, 0 given
 
 -- Iteration 22 --
-
-Warning: vprintf(): Too few arguments in %s on line %d
-
-bool(false)
+The arguments array must contain 1 items, 0 given
 
 -- Iteration 23 --
 Resource id #%d
index 838093cdb16d3f9fe88bdff1225ac41641e5c536..3af9b854fe1b1b2bbf6a3b66924422c3ca0c0ce6 100644 (file)
@@ -84,7 +84,11 @@ $values = array(
 $counter = 1;
 foreach($values as $value) {
   echo "\n-- Iteration $counter --\n";
-  var_dump( vsprintf($format,$value) );
+  try {
+    var_dump( vsprintf($format,$value) );
+  } catch (\ValueError $e) {
+    echo $e->getMessage(), "\n";
+  }
   $counter++;
 };
 
@@ -124,14 +128,10 @@ string(13) "1.07654321E-9"
 string(3) "0.5"
 
 -- Iteration 10 --
-
-Warning: vsprintf(): Too few arguments in %s on line %d
-bool(false)
+The arguments array must contain 1 items, 0 given
 
 -- Iteration 11 --
-
-Warning: vsprintf(): Too few arguments in %s on line %d
-bool(false)
+The arguments array must contain 1 items, 0 given
 
 -- Iteration 12 --
 string(1) "1"
@@ -158,19 +158,13 @@ string(6) "string"
 string(6) "string"
 
 -- Iteration 20 --
-
-Warning: vsprintf(): Too few arguments in %s on line %d
-bool(false)
+The arguments array must contain 1 items, 0 given
 
 -- Iteration 21 --
-
-Warning: vsprintf(): Too few arguments in %s on line %d
-bool(false)
+The arguments array must contain 1 items, 0 given
 
 -- Iteration 22 --
-
-Warning: vsprintf(): Too few arguments in %s on line %d
-bool(false)
+The arguments array must contain 1 items, 0 given
 
 -- Iteration 23 --
 string(%d) "Resource id #%d"
index 5e82091088471152dacd5b4dd70c5ff7369036ff..a43a68c88b99989909f2da9c657b11b1411b83bd 100644 (file)
@@ -2,7 +2,6 @@
 Formatted print functions
 --FILE--
 <?php
-error_reporting(0);
 
 $fp = fopen("php://stdout", "w") or die("Arrggsgg!!");
 $x = fprintf($fp, "fprintf test 1:%.5s", "abcdefghij");
@@ -40,7 +39,11 @@ printf("printf test 26:%2\$d %1\$d\n", 1, 2);
 printf("printf test 27:%3\$d %d %d\n", 1, 2, 3);
 printf("printf test 28:%2\$02d %1\$2d\n", 1, 2);
 printf("printf test 29:%2\$-2d %1\$2d\n", 1, 2);
-print("printf test 30:"); printf("%0\$s", 1); print("x\n");
+try {
+    print("printf test 30:"); printf("%0\$s", 1); print("x\n");
+} catch(\ValueError $e) {
+    print('Error found: '.$e->getMessage()."\n");
+}
 vprintf("vprintf test 1:%2\$-2d %1\$2d\n", array(1, 2));
 
 
@@ -79,5 +82,5 @@ printf test 26:2 1
 printf test 27:3 1 2
 printf test 28:02  1
 printf test 29:2   1
-printf test 30:x
+printf test 30:Error found: Argument number must be greater than zero
 vprintf test 1:2   1