From 61bc22580524a6d92bf31b2046baa6dcc4e400d4 Mon Sep 17 00:00:00 2001 From: Hio Date: Fri, 18 Oct 2013 16:48:47 +0100 Subject: [PATCH] Correctly parse class name in 'for my class $foo The code in toke.c on encountering 'for my' or for our', skips past any optional package name, then checks that the next thing is a '$', so that it can give a "Missing $ on loop variable" error if necessary. However, the code to skip the package name was using scan_ident() rather than scan_word(); the latter assumes that the first char was the sigil, and starts scanning from the second char onwards. So in something like for my a1b $x (...) scan_ident() starts scanning at '1b' in 'a1b', thinks it scanning $1 or similar, and stops at the first non-digit char, in this case the b. The fix is to use parse_word() instead. --- AUTHORS | 1 + t/comp/parser.t | 12 ++++++++---- toke.c | 2 +- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/AUTHORS b/AUTHORS index b84a6e4..58d9ce5 100644 --- a/AUTHORS +++ b/AUTHORS @@ -460,6 +460,7 @@ Henrik Tougaard Herbert Breunung Hernan Perez Masci Hershel Walters +Hio Hojung Youn Holger Bechtold Hongwen Qiu diff --git a/t/comp/parser.t b/t/comp/parser.t index 8fd7e85..7caa116 100644 --- a/t/comp/parser.t +++ b/t/comp/parser.t @@ -8,7 +8,7 @@ BEGIN { chdir 't'; } -print "1..168\n"; +print "1..169\n"; sub failed { my ($got, $expected, $name) = @_; @@ -333,10 +333,10 @@ like($@, qr/BEGIN failed--compilation aborted/, 'BEGIN 7' ); eval qq[ *$xFD ]; like($@, qr/Identifier too long/, "too long id in glob ctx"); - eval qq[ for $xFD ]; + eval qq[ for $xFC ]; like($@, qr/Missing \$ on loop variable/, - "253 char id ok, but a different error"); - eval qq[ for $xFE; ]; + "252 char id ok, but a different error"); + eval qq[ for $xFD; ]; like($@, qr/Identifier too long/, "too long id in for ctx"); # the specific case from the ticket @@ -495,6 +495,10 @@ eval 'Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo' .'ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo'; like $@, "^Identifier too long at ", 'ident buffer overflow'; +eval 'for my a1b $i (1) {}'; +# ng: 'Missing $ on loop variable' +like $@, "^No such class a1b at ", 'TYPE of my of for statement'; + # Add new tests HERE (above this line) # bug #74022: Loop on characters in \p{OtherIDContinue} diff --git a/toke.c b/toke.c index 28e3511..1ab57f3 100644 --- a/toke.c +++ b/toke.c @@ -8035,7 +8035,7 @@ Perl_yylex(pTHX) p += 3; p = PEEKSPACE(p); if (isIDFIRST_lazy_if(p,UTF)) { - p = scan_ident(p, PL_tokenbuf, sizeof PL_tokenbuf, TRUE); + p = scan_word(p, PL_tokenbuf, sizeof PL_tokenbuf, TRUE, &len); p = PEEKSPACE(p); } if (*p != '$') -- 2.7.4