This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
[perl #125540] handle already being at EOF while not finding a heredoc terminator
authorTony Cook <tony@develop-help.com>
Wed, 20 Jan 2016 04:35:13 +0000 (15:35 +1100)
committerTony Cook <tony@develop-help.com>
Wed, 3 Feb 2016 03:41:46 +0000 (14:41 +1100)
In some cases, S_scan_heredoc() can already be at end of file and
PL_rsfp is NULL.  If we're on the final line and that line has no
newline we'd assert or crash.

Now, if we don't find that newline, we obviously can't find the
terminator, so go straight to reporting the missing terminator.

I considered setting s to PL_bufend, but that would just be more
work to print the same message.

t/op/heredoc.t
toke.c

index dadf105..8fe0c0f 100644 (file)
@@ -7,7 +7,7 @@ BEGIN {
 }
 
 use strict;
-plan(tests => 40);
+plan(tests => 41);
 
 
 # heredoc without newline (#65838)
@@ -98,4 +98,12 @@ HEREDOC
         {},
         "don't use an invalid oldoldbufptr"
     );
+
+    # [perl #125540] this asserted or crashed
+    fresh_perl_like(
+       q(map d$#<<<<),
+       qr/Can't find string terminator "" anywhere before EOF at - line 1\./,
+       {},
+       "Don't assert parsing a here-doc if we hit EOF early"
+    );
 }
diff --git a/toke.c b/toke.c
index d2a7e7c..e2f2bfe 100644 (file)
--- a/toke.c
+++ b/toke.c
@@ -9577,9 +9577,10 @@ S_scan_heredoc(pTHX_ char *s)
                goto streaming;
            }
          }
-       else {  /* eval */
+       else {  /* eval or we've already hit EOF */
            s = (char*)memchr((void*)s, '\n', PL_bufend - s);
-           assert(s);
+           if (!s)
+                goto interminable;
        }
        linestr = shared->ls_linestr;
        bufend = SvEND(linestr);