Skip to content

Change E_WARNING to ValueError in sprintf functions #4837

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 31 additions & 16 deletions ext/standard/formatted_print.c
Original file line number Diff line number Diff line change
Expand Up @@ -387,16 +387,20 @@ 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;
char *format, *temppos, padding;
zend_string *result;
int always_sign;
size_t format_len;
int bad_arg_number = 0;

if (!try_convert_to_string(z_format)) {
return NULL;
Expand All @@ -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;
Expand Down Expand Up @@ -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--;
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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) {
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -673,7 +688,7 @@ 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;
}
Expand All @@ -696,7 +711,7 @@ 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;
Expand All @@ -719,7 +734,7 @@ 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;
}
Expand All @@ -745,7 +760,7 @@ 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;
Expand Down Expand Up @@ -777,7 +792,7 @@ 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;
}
Expand Down Expand Up @@ -812,7 +827,7 @@ 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;
Expand Down
8 changes: 6 additions & 2 deletions ext/standard/tests/file/fscanf_variation14.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
10 changes: 6 additions & 4 deletions ext/standard/tests/strings/printf_64bit.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down Expand Up @@ -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 ***
Expand Down
60 changes: 36 additions & 24 deletions ext/standard/tests/strings/printf_error.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -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===
Expand All @@ -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===
60 changes: 36 additions & 24 deletions ext/standard/tests/strings/sprintf_error.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -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";
?>
Expand All @@ -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
11 changes: 6 additions & 5 deletions ext/standard/tests/strings/vfprintf_error4.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -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 );

Expand All @@ -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===
Loading