In perl.git, the branch smoke-me/nicholas/rt-65838-fixup has been updated

<http://perl5.git.perl.org/perl.git/commitdiff/78a9cd0fe99ca35bb2a4ffe8640c44e4e25bc995?hp=ec79994d178a58009af5b2b0b22e1d93a4787c7a>

- Log -----------------------------------------------------------------
commit 78a9cd0fe99ca35bb2a4ffe8640c44e4e25bc995
Author: Nicholas Clark <n...@ccl4.org>
Date:   Thu Jun 27 18:09:32 2013 +0200

    Avoid read-after-free in S_scan_heredoc() if the terminator line has no 
"\n".
    
    The code added by commit 112d128413206514 to fix RT #65838 (Allow here-doc
    with no final newline) could in some rare cases cause a read of free()d
    memory during parsing. The code itself is only run if the Perl program
    ends with a heredoc (which is an unusual structure), and if the last line of
    the file on disk has terminating newline character (which is also unusual,
    as many editors default to adding a final newline). The bug would be
    triggered if the fixup code in S_scan_heredoc() triggered a reallocation of
    the buffer in PL_linestr when adding a newline to it.
-----------------------------------------------------------------------

Summary of changes:
 t/op/heredoc.t | 21 ++++++++++++++-------
 toke.c         |  3 ++-
 2 files changed, 16 insertions(+), 8 deletions(-)

diff --git a/t/op/heredoc.t b/t/op/heredoc.t
index 08b0af2..55a19f0 100644
--- a/t/op/heredoc.t
+++ b/t/op/heredoc.t
@@ -7,7 +7,7 @@ BEGIN {
 }
 
 use strict;
-plan(tests => 9);
+plan(tests => 39);
 
 
 # heredoc without newline (#65838)
@@ -69,12 +69,19 @@ HEREDOC
         "string terminator must start at newline"
     );
 
-    fresh_perl_like(
-        "print <<;\nno more newlines",
-        qr/find string terminator/,
-        { switches => ['-X'] },
-        "empty string terminator still needs a newline"
-    );
+    # Loop over various lengths to try to force at least one to cause a
+    # reallocation in S_scan_heredoc()
+    # Timing on a modern machine suggests that this loop executes in less than
+    # 0.1s, so it's a very small cost for the default build. The benefit is
+    # that building with ASAN will reveal the bug and any related regressions.
+    for (1..31) {
+       fresh_perl_like(
+            "print <<;\n" . "x" x $_,
+            qr/find string terminator/,
+            { switches => ['-X'] },
+            "empty string terminator still needs a newline (length $_)"
+        );
+    }
 
     fresh_perl_like(
         "print <<ThisTerminatorIsLongerThanTheData;\nno more newlines",
diff --git a/toke.c b/toke.c
index aedccc5..f9c9937 100644
--- a/toke.c
+++ b/toke.c
@@ -10115,8 +10115,9 @@ S_scan_heredoc(pTHX_ char *s)
        }
        CopLINE_set(PL_curcop, (line_t)PL_multi_start - 1);
        if (!SvCUR(PL_linestr) || PL_bufend[-1] != '\n') {
-           lex_grow_linestr(SvCUR(PL_linestr) + 2);
+            s = lex_grow_linestr(SvLEN(PL_linestr) + 3);
            sv_catpvs(PL_linestr, "\n\0");
+            PL_bufend = SvEND(PL_linestr);
        }
        s = PL_bufptr;
 #ifdef PERL_MAD

--
Perl5 Master Repository

Reply via email to