diff options
author | Tony Cook <tony@develop-help.com> | 2017-07-26 12:04:18 +1000 |
---|---|---|
committer | Tony Cook <tony@develop-help.com> | 2017-08-17 10:46:45 +1000 |
commit | 36000cd1c47863d8412b285701db7232dd450239 (patch) | |
tree | d3e8cd50c1fdbedf487a0f94801c78f52cbcf35e | |
parent | 7b0b49a788000e00f19945fc6d7f28c1f368ac03 (diff) | |
download | perl-36000cd1c47863d8412b285701db7232dd450239.tar.gz |
(perl #131793) sanely handle PL_linestart > PL_bufptr
In the test case, scan_ident() ends up fetching another line
(updating PL_linestart), and since in this case we don't
successfully parse ${identifier} s (and PL_bufptr) end up being
before PL_linestart.
-rw-r--r-- | t/comp/parser_run.t | 9 | ||||
-rw-r--r-- | toke.c | 19 |
2 files changed, 23 insertions, 5 deletions
diff --git a/t/comp/parser_run.t b/t/comp/parser_run.t index e74644d3fb..0fca5b2800 100644 --- a/t/comp/parser_run.t +++ b/t/comp/parser_run.t @@ -10,7 +10,7 @@ BEGIN { } require './test.pl'; -plan(1); +plan(2); # [perl #130814] can reallocate lineptr while looking ahead for # "Missing $ on loop variable" diagnostic. @@ -24,5 +24,12 @@ syntax error at - line 3, near "foreach m0 Identifier too long at - line 3. EXPECT +fresh_perl_is(<<EOS, <<'EXPECT', {}, "linestart before bufptr"); +\${ \xD5eeeeeeeeeeee +'x +EOS +Unrecognized character \xD5; marked by <-- HERE after ${ <-- HERE near column 4 at - line 1. +EXPECT + __END__ # ex: set ts=8 sts=4 sw=4 et: @@ -5158,12 +5158,23 @@ Perl_yylex(pTHX) else { c = Perl_form(aTHX_ "\\x%02X", (unsigned char)*s); } - len = UTF ? Perl_utf8_length(aTHX_ (U8 *) PL_linestart, (U8 *) s) : (STRLEN) (s - PL_linestart); - if (len > UNRECOGNIZED_PRECEDE_COUNT) { - d = UTF ? (char *) utf8_hop_back((U8 *) s, -UNRECOGNIZED_PRECEDE_COUNT, (U8 *)PL_linestart) : s - UNRECOGNIZED_PRECEDE_COUNT; - } else { + + if (s >= PL_linestart) { d = PL_linestart; } + else { + /* somehow (probably due to a parse failure), PL_linestart has advanced + * pass PL_bufptr, get a reasonable beginning of line + */ + d = s; + while (d > SvPVX(PL_linestr) && d[-1] && d[-1] != '\n') + --d; + } + len = UTF ? Perl_utf8_length(aTHX_ (U8 *) d, (U8 *) s) : (STRLEN) (s - d); + if (len > UNRECOGNIZED_PRECEDE_COUNT) { + d = UTF ? (char *) utf8_hop_back((U8 *) s, -UNRECOGNIZED_PRECEDE_COUNT, (U8 *)d) : s - UNRECOGNIZED_PRECEDE_COUNT; + } + Perl_croak(aTHX_ "Unrecognized character %s; marked by <-- HERE after %" UTF8f "<-- HERE near column %d", c, UTF8fARG(UTF, (s - d), d), (int) len + 1); |