This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
[perl #70836] Fix err msg for unterminated here-doc in eval
authorFather Chrysostomos <sprout@cpan.org>
Sun, 19 Aug 2012 06:54:02 +0000 (23:54 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Tue, 21 Aug 2012 21:10:59 +0000 (14:10 -0700)
$ perl -e '<<foo'
Can't find string terminator "foo" anywhere before EOF at -e line 1.

$ perl -e 'eval "<<foo"; die $@'
Can't find string terminator "
foo" anywhere before EOF at (eval 1) line 1.

An internal implementation detail is leaking out.

When the lexer happens to have a multiline string in its line buffer
(in a string eval or quoted construct), it looks for "\nfoo" instead
of "foo".  It was passing that same string to the error-reporting code
(S_missingterm), resulting in that extraneous newline.

t/lib/croak/toke
toke.c

index 7ab5a4d..ddfaaeb 100644 (file)
@@ -1,4 +1,14 @@
 __END__
+# NAME Unterminated here-doc in string eval
+eval "<<foo"; die $@
+EXPECT
+Can't find string terminator "foo" anywhere before EOF at (eval 1) line 1.
+########
+# NAME Unterminated here-doc in s/// string eval
+eval "s//<<foo/e"; die $@
+EXPECT
+Can't find string terminator "foo" anywhere before EOF at (eval 1) line 1.
+########
 # NAME Missing name in "my sub"
 my sub;
 EXPECT
diff --git a/toke.c b/toke.c
index 787a3b6..33a560c 100644 (file)
--- a/toke.c
+++ b/toke.c
@@ -9447,6 +9447,7 @@ S_scan_heredoc(pTHX_ register char *s)
     char *d;
     char *e;
     char *peek;
+    char *origd;
     const int outer = (PL_rsfp || PL_parser->filtered)
                   && !(PL_lex_inwhat == OP_SCALAR);
 #ifdef PERL_MAD
@@ -9459,10 +9460,10 @@ S_scan_heredoc(pTHX_ register char *s)
     PERL_ARGS_ASSERT_SCAN_HEREDOC;
 
     s += 2;
-    d = PL_tokenbuf;
+    d = origd = PL_tokenbuf;
     e = PL_tokenbuf + sizeof PL_tokenbuf - 1;
     if (!outer)
-       *d++ = '\n';
+       *d++ = '\n', ++origd;
     peek = s;
     while (SPACE_OR_TAB(*peek))
        peek++;
@@ -9589,7 +9590,7 @@ S_scan_heredoc(pTHX_ register char *s)
        }
        if (s >= bufend) {
            CopLINE_set(PL_curcop, (line_t)PL_multi_start);
-           missingterm(PL_tokenbuf);
+           missingterm(origd);
        }
        sv_setpvn(herewas,bufptr,d-bufptr+1);
        sv_setpvn(tmpstr,d+1,s-d);
@@ -9609,7 +9610,7 @@ S_scan_heredoc(pTHX_ register char *s)
        }
        if (s >= PL_bufend) {
            CopLINE_set(PL_curcop, (line_t)PL_multi_start);
-           missingterm(PL_tokenbuf);
+           missingterm(origd);
        }
        sv_setpvn(tmpstr,d+1,s-d);
 #ifdef PERL_MAD