This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
fix errror handling for ':attr(foo' with no ')'
authorDavid Mitchell <davem@iabyn.com>
Wed, 7 Sep 2016 08:30:26 +0000 (09:30 +0100)
committerDavid Mitchell <davem@iabyn.com>
Wed, 7 Sep 2016 10:42:30 +0000 (11:42 +0100)
commit7fe45fb9daf39e88f96409d466aeeec689812bbb
tree2437d364966c824a8c10df6825d78523f13474bb
parent6402f8b059acd9e4acb8c9492bc1e60aae24478d
fix errror handling for ':attr(foo' with no ')'

When the parameter of an attribute has no matching closing ')', there
are several issues with the way the error is handled.

First, the code currently tries to set PL_bufptr back to the position
of the opening '(' for a better error message. However, since the error
will have been discovered only at EOF after all the remaining lines have
been read and discarded, the buffer no longer contains ':attr(...'.
So the error message includes a spurious \0 followed by possibly some
random chunk of characters from the last line read in.

Worse, if the input buffer gets realloced while perl searches for the ')',
then PL_bufptr is reset to point into the freed buffer. [perl #129086].

It does yyerror() rather than croak(), so further error messages appear,
even though we're at EOF and no further parsing can occur. Similar cases
such as no matching closing string delimiter all croak instead.

It resets cop_line to zero *before* printing the error, so the line number
of the error is erroneously reported as zero.

This commit fixes all these issues by handling the error more similarly
to the way unterminated strings are handled. In particular, it no longer
tries to print out the section of src where it thinks the error is.

For comparison, running perl on this code file:

    # this is line 1
    my $x :foo(bar;
    the
    quick
    brown
    fox jumps over the lazy dog

used to output:

    Unterminated attribute parameter in attribute list at /tmp/p1 line 0, near "\0\0x jumps "
    syntax error at /tmp/p1 line 0, at EOF
    Execution of /tmp/p1 aborted due to compilation errors.

but now outputs:

    Unterminated attribute parameter in attribute list at /tmp/p1 line 2.

Note how previously: the error message included two literal null chars
(represented by \0 above), followed by a random chunk of the last line;
it claimed to be on line 0; it output two further error messages.

For comparison, change the ':foo' to 'q' so that its an unterminated
string, and you get (and always got):

    Can't find string terminator ")" anywhere before EOF at /tmp/p1 line 2.
t/op/attrs.t
toke.c