Skip to content

Commit 027471c

Browse files
committed
(perl #133913) limit numeric format results to INT_MAX
The return value of v?snprintf() is int, and we pay attention to that return value, so limit the expected size of numeric formats to INT_MAX.
1 parent 755e4ca commit 027471c

File tree

3 files changed

+20
-0
lines changed

3 files changed

+20
-0
lines changed

pod/perldiag.pod

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4354,6 +4354,12 @@ the meantime, try using scientific notation (e.g. "1e6" instead of
43544354
a number. This happens, for example with C<\o{}>, with no number between
43554355
the braces.
43564356

4357+
=item Numeric format result too large
4358+
4359+
(F) The length of the result of a numeric format supplied to sprintf()
4360+
or printf() would have been too large for the underlying C function to
4361+
report. This limit is typically 2GB.
4362+
43574363
=item Octal number > 037777777777 non-portable
43584364

43594365
(W portable) The octal number you specified is larger than 2**32-1

sv.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13085,6 +13085,13 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p
1308513085
if (float_need < width)
1308613086
float_need = width;
1308713087

13088+
if (float_need > INT_MAX) {
13089+
/* snprintf() returns an int, and we use that return value,
13090+
so die horribly if the expected size is too large for int
13091+
*/
13092+
Perl_croak(aTHX_ "Numeric format result too large");
13093+
}
13094+
1308813095
if (PL_efloatsize <= float_need) {
1308913096
/* PL_efloatbuf should be at least 1 greater than
1309013097
* float_need to allow a trailing \0 to be returned by

t/op/sprintf2.t

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1153,4 +1153,11 @@ foreach(
11531153
is sprintf("%.0f", $_), sprintf("%-.0f", $_), "special-case %.0f on $_";
11541154
}
11551155

1156+
# large uvsize needed so the large width is parsed properly
1157+
# large sizesize needed so the STRLEN check doesn't
1158+
if ($Config{intsize} == 4 && $Config{uvsize} > 4 && $Config{sizesize} > 4) {
1159+
eval { my $x = sprintf("%7000000000E", 0) };
1160+
like($@, qr/^Numeric format result too large at /,
1161+
"croak for very large numeric format results");
1162+
}
11561163
done_testing();

0 commit comments

Comments
 (0)