In perl.git, the branch blead has been updated <http://perl5.git.perl.org/perl.git/commitdiff/2415a0a27e4707ca7be52f2a92148dcc8d517aa1?hp=5dcc8417a3fe161282405373988b7a279bef500d>
- Log ----------------------------------------------------------------- commit 2415a0a27e4707ca7be52f2a92148dcc8d517aa1 Author: Aaron Crane <a...@cpan.org> Date: Tue Jan 12 00:05:40 2016 +0000 Data::Dumper: handle huge inputs on 64-bit platforms Several quantities relating to string escaping were being stored in 32-bit variables. On a 64-bit system, pathological inputs could overflow the available space and cause incorrect output. The test for this requires about 10 GB of memory, so it is disabled except when PERL_TEST_MEMORY is set to at least 10. There are other questionable-looking uses of I32 in Dumper.xs, but they don't seem to be exploitable. (It helps, for example, that the core hash API restricts key lengths to 2**31-1.) That said, it may be worth auditing the code rather more carefully for potential problems. ----------------------------------------------------------------------- Summary of changes: MANIFEST | 1 + dist/Data-Dumper/Dumper.pm | 4 ++-- dist/Data-Dumper/Dumper.xs | 27 +++++++++++++-------------- dist/Data-Dumper/t/huge.t | 33 +++++++++++++++++++++++++++++++++ 4 files changed, 49 insertions(+), 16 deletions(-) create mode 100644 dist/Data-Dumper/t/huge.t diff --git a/MANIFEST b/MANIFEST index 0d41bbf..e75199d 100644 --- a/MANIFEST +++ b/MANIFEST @@ -3069,6 +3069,7 @@ dist/Data-Dumper/t/dumper.t See if Data::Dumper works dist/Data-Dumper/t/dumpperl.t See if Data::Dumper::Dumpperl works dist/Data-Dumper/t/freezer.t See if Data::Dumper::Freezer works dist/Data-Dumper/t/freezer_useperl.t See if Data::Dumper works +dist/Data-Dumper/t/huge.t See if Data::Dumper works on huge inputs dist/Data-Dumper/t/indent.t See if Data::Dumper::Indent works dist/Data-Dumper/t/lib/Testing.pm Functions used in testing Data-Dumper dist/Data-Dumper/t/misc.t Miscellaneous tests for Data-Dumper diff --git a/dist/Data-Dumper/Dumper.pm b/dist/Data-Dumper/Dumper.pm index ace9b78..13be89d 100644 --- a/dist/Data-Dumper/Dumper.pm +++ b/dist/Data-Dumper/Dumper.pm @@ -10,7 +10,7 @@ package Data::Dumper; BEGIN { - $VERSION = '2.159'; # Don't forget to set version and release + $VERSION = '2.160'; # Don't forget to set version and release } # date in POD below! #$| = 1; @@ -1472,7 +1472,7 @@ modify it under the same terms as Perl itself. =head1 VERSION -Version 2.159 (December 15 2015) +Version 2.160 (January 12 2016) =head1 SEE ALSO diff --git a/dist/Data-Dumper/Dumper.xs b/dist/Data-Dumper/Dumper.xs index 3440891..8220241 100644 --- a/dist/Data-Dumper/Dumper.xs +++ b/dist/Data-Dumper/Dumper.xs @@ -65,9 +65,9 @@ typedef struct { int trailingcomma; } Style; -static I32 num_q (const char *s, STRLEN slen); -static I32 esc_q (char *dest, const char *src, STRLEN slen); -static I32 esc_q_utf8 (pTHX_ SV *sv, const char *src, STRLEN slen, I32 do_utf8, I32 useqq); +static STRLEN num_q (const char *s, STRLEN slen); +static STRLEN esc_q (char *dest, const char *src, STRLEN slen); +static STRLEN esc_q_utf8 (pTHX_ SV *sv, const char *src, STRLEN slen, I32 do_utf8, I32 useqq); static bool globname_needs_quote(const char *s, STRLEN len); static bool key_needs_quote(const char *s, STRLEN len); static bool safe_decimal_number(const char *p, STRLEN len); @@ -217,10 +217,10 @@ safe_decimal_number(const char *p, STRLEN len) { } /* count the number of "'"s and "\"s in string */ -static I32 +static STRLEN num_q(const char *s, STRLEN slen) { - I32 ret = 0; + STRLEN ret = 0; while (slen > 0) { if (*s == '\'' || *s == '\\') @@ -235,10 +235,10 @@ num_q(const char *s, STRLEN slen) /* returns number of chars added to escape "'"s and "\"s in s */ /* slen number of characters in s will be escaped */ /* destination must be long enough for additional chars */ -static I32 +static STRLEN esc_q(char *d, const char *s, STRLEN slen) { - I32 ret = 0; + STRLEN ret = 0; while (slen > 0) { switch (*s) { @@ -257,7 +257,7 @@ esc_q(char *d, const char *s, STRLEN slen) } /* this function is also misused for implementing $Useqq */ -static I32 +static STRLEN esc_q_utf8(pTHX_ SV* sv, const char *src, STRLEN slen, I32 do_utf8, I32 useqq) { char *r, *rstart; @@ -886,7 +886,7 @@ DD_dump(pTHX_ SV *val, const char *name, STRLEN namelen, SV *retval, HV *seenhv, SV *sname; HE *entry = NULL; char *key; - I32 klen; + STRLEN klen; SV *hval; AV *keys = NULL; @@ -974,10 +974,10 @@ DD_dump(pTHX_ SV *val, const char *name, STRLEN namelen, SV *retval, HV *seenhv, for (i = 0; 1; i++) { char *nkey; char *nkey_buffer = NULL; - I32 nticks = 0; + STRLEN nticks = 0; SV* keysv; STRLEN keylen; - I32 nlen; + STRLEN nlen; bool do_utf8 = FALSE; if (style->sortkeys) { @@ -1059,7 +1059,7 @@ DD_dump(pTHX_ SV *val, const char *name, STRLEN namelen, SV *retval, HV *seenhv, sv_catsv(retval, style->pair); if (style->indent >= 2) { char *extra; - I32 elen = 0; + STRLEN elen = 0; newapad = newSVsv(apad); New(0, extra, klen+4+1, char); while (elen < (klen+4)) @@ -1104,8 +1104,7 @@ DD_dump(pTHX_ SV *val, const char *name, STRLEN namelen, SV *retval, HV *seenhv, } if (realpack && !no_bless) { /* free blessed allocs */ - I32 plen; - I32 pticks; + STRLEN plen, pticks; if (style->indent >= 2) { SvREFCNT_dec(apad); diff --git a/dist/Data-Dumper/t/huge.t b/dist/Data-Dumper/t/huge.t new file mode 100644 index 0000000..09343b7 --- /dev/null +++ b/dist/Data-Dumper/t/huge.t @@ -0,0 +1,33 @@ +#!./perl -w +# +# automated tests for Data::Dumper that need large amounts of memory; they +# are skipped unless PERL_TEST_MEMORY is set, and at least 10 +# + +use strict; +use warnings; + +use Test::More; + +use Config; +use Data::Dumper; + +BEGIN { + plan skip_all => 'Data::Dumper was not built' + if $Config{extensions} !~ m{\b Data/Dumper \b}x; + plan skip_all => 'Need 64-bit pointers for this test' + if $Config{ptrsize} < 8; + plan skip_all => 'Need ~10 GiB of core for this test' + if !$ENV{PERL_TEST_MEMORY} || $ENV{PERL_TEST_MEMORY} < 10; +} + +plan tests => 1; + +{ + my $input = q/'/ x 2**31; + my $len = length Dumper($input); + # Each single-quote will get backslashed, so the output must have + # stricly more than twice as many characters as the input. + cmp_ok($len, '>', 2**32, 'correct output for huge all-quotable value'); + undef $input; +} -- Perl5 Master Repository