This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Fix here-doc body extraction in eval 's//<<END/'
authorFather Chrysostomos <sprout@cpan.org>
Wed, 29 Aug 2012 19:47:32 +0000 (12:47 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Fri, 31 Aug 2012 01:18:08 +0000 (18:18 -0700)
commit76f9939ee09e325216d1b8afce3e3d7183c5eeb8
treeb1b472e7e77c818959bc0784f61442a2df193378
parent3328ab5af72319f76fe9be3910a8e07d38b14de2
Fix here-doc body extraction in eval 's//<<END/'

Outside of string eval, this:

s//<<END/e; print "a
END
b\n";

prints this:

a
b

But when we have string eval involved,

eval 's//<<END/e; print "a
END
b\n"';

we get this:

a

b

Amazing!

The buggy code in question goes back to commit 0244c3a403.

Since PL_linestr only contains the contents of the replacement
("<<END"), it peeks into the outer lexing scope’s linestr buffer, mod-
ifying it in place to remove the here-doc body, by copying everything
after the here-doc back to the spot where the body begins.

It was off by one, however, and left an extra line break.

When the code in question is reached, the variables are set as follows:

bufptr = "; print \"a"...  (just after the s///)
s      = "\nb\\n\""        (newline after the heredoc terminator)

The herewas variable already contains everything after the quote-
like operator containing the <<heredoc marker to the end of the line
including the \n ("; print \"a\n").

But then we concatenate everything from s onwards.  So we end up with
the \n before the here-doc body and the \n from after the here-doc
terminator juxtaposed.

So after using s to extract the re-eval string, we increment s so it
points afer the final newline.
t/base/lex.t
toke.c