diff options
author | Father Chrysostomos <sprout@cpan.org> | 2014-12-23 20:12:06 -0800 |
---|---|---|
committer | Father Chrysostomos <sprout@cpan.org> | 2014-12-23 20:13:11 -0800 |
commit | 3c6ef0a5332fe51f7e409d17fce0788646ee5bf6 (patch) | |
tree | aef0d1875f1be7015d2d5da1d5828e23aed44f7f /t/bigmem | |
parent | 4bba85d0fdb428e77c7a589a992b892d7999bb33 (diff) | |
download | perl-3c6ef0a5332fe51f7e409d17fce0788646ee5bf6.tar.gz |
[perl #103260] Fix s/// with long strings
This is also the subject of perl #123071.
The iteration count was stored in an I32 and was overflowing. If the
maximum number of iterations possible overflowed, then it would become
negative, and the substitution would fail immediately with ‘Substitu-
tion loop’.
I tried fixing this without increasing the size of the context
stack entries on 64-bit builds (by skipping the loop check for long
strings), but was unable to, because we have to return the number of
iterations, which was also stored as I32. If we change just that one
to SSize_t, we get an I32-sized alignment hole, so we might as well
make maxiters a SSize_t as well, fixing the bug that way (the more
straightforward way).
Diffstat (limited to 't/bigmem')
-rw-r--r-- | t/bigmem/subst.t | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/t/bigmem/subst.t b/t/bigmem/subst.t new file mode 100644 index 0000000000..394729e75a --- /dev/null +++ b/t/bigmem/subst.t @@ -0,0 +1,23 @@ +#!perl +BEGIN { + chdir 't' if -d 't'; + @INC = "../lib"; + require './test.pl'; +} + +use Config qw(%Config); + +$ENV{PERL_TEST_MEMORY} >= 4 + or skip_all("Need ~4Gb for this test"); +$Config{ptrsize} >= 8 + or skip_all("Need 64-bit pointers for this test"); + +plan(2); + +# [perl #103260] [perl #123071] +# ${\2} to defeat constant folding, which in this case actually slows +# things down +my $x; +$x .=" "x4096 for 1..2**30/4096; +is eval { $x =~ s/ /_/g }, 2**30, "subst on long strings" ; +is eval { $x =~ s/_/${\" "}/g },2**30,"subst on long strings (substcont)" ; |