This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
[perl #128307] Fix ‘foo ? require : bar’
authorFather Chrysostomos <sprout@cpan.org>
Fri, 3 Jun 2016 05:35:10 +0000 (22:35 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Fri, 3 Jun 2016 05:37:36 +0000 (22:37 -0700)
The lexer’s bareword-parser that kicks in after it sees ‘require’ was
getting confused by the single colon, since it assumed that if the
thing that followed began with a letter or colon it must be a package
or module name.  Hence, require with : after it was parsed as
require "", but with a ‘bareword’ "".  The lexer should be checking
for two colons, not just one.

t/op/lex.t
toke.c

index c515449..00e64fc 100644 (file)
@@ -7,7 +7,7 @@ use warnings;
 
 BEGIN { chdir 't' if -d 't'; require './test.pl'; }
 
-plan(tests => 25);
+plan(tests => 26);
 
 {
     no warnings 'deprecated';
@@ -209,3 +209,10 @@ fresh_perl_is(
    { stderr => 1 },
   's;@{<<a; [perl #123995]'
 );
+
+fresh_perl_is(
+  '$_ = q-strict.pm-; 1 ? require : die;'
+ .' print qq-ok\n- if $INC{q-strict.pm-}',
+  "ok\n",
+  'foo ? require : bar [perl #128307]'
+);
diff --git a/toke.c b/toke.c
index 2c6cd85..02c1325 100644 (file)
--- a/toke.c
+++ b/toke.c
@@ -2012,7 +2012,7 @@ S_force_word(pTHX_ char *start, int token, int check_keyword, int allow_pack)
     start = skipspace(start);
     s = start;
     if (isIDFIRST_lazy_if(s,UTF)
-        || (allow_pack && *s == ':') )
+        || (allow_pack && *s == ':' && s[1] == ':') )
     {
        s = scan_word(s, PL_tokenbuf, sizeof PL_tokenbuf, allow_pack, &len);
        if (check_keyword) {