Stop eval "qq'\$\0foo'" from leaking
authorFather Chrysostomos <sprout@cpan.org>
Tue, 6 Nov 2012 18:00:12 +0000 (10:00 -0800)
committerFather Chrysostomos <sprout@cpan.org>
Tue, 6 Nov 2012 20:33:37 +0000 (12:33 -0800)
commit3ce3dcd9d07ae1c7dc2ed63c1b826be9ff13a7c7
tree841be18e2a7f6c375c9f63bd91b4fe7f2ddc2999
parent6a95d59fd5c2a811937c65b2f20b410d556a2002
Stop eval "qq'\$\0foo'" from leaking

If the dollar sign in a double-quoted string is followed by a null,
then scan_ident gets confused, as it uses the nullness to keep track
of whether it has found an identifier.  In this case it treats $\0 as
a punctuation variable but then loses track of that fact and thinks it
has found the end of the string.

It’s complicated, but the end result is that the sequence of tokens
emitted for eval "qq'$\0foo'" would be the following:

    stringify ( $ . "foo" )

instead of this:

    stringify ( $ <ident> . "foo" )

But the missing identifier after the dollar sign results in a syn-
tax error that prevents yylex from having a chance to emit the
"foo", which by that time it has put on the forced token stack.

There are cases in which the CV that owns the ops on the forced token
stack can be freed while the ops are still on that stack and will
still be fed to the parser, so we treat the forced token stack like
the savestack, and do not allow ops thereon to be freed when their CV
is freed, to avoid feeding freed ops to the parser.

In this case, it means that the ops on the stack are never freed,
resulting in a memory leak.

Whether scan_ident needs to be fixed (or ‘fixed’) I don’t know.  I do
know that when the parser is freed any remaining forced tokens should
also be freed.  Even if this leak could be fixed some other way, it
would still be a good idea for parser_free to check for forced tokens
that need to be cleaned up.
t/op/svleak.t
toke.c