This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
disable lexing of (?{}) within \Q, \U etc
authorDavid Mitchell <davem@iabyn.com>
Mon, 1 Aug 2011 11:40:32 +0000 (12:40 +0100)
committerDavid Mitchell <davem@iabyn.com>
Wed, 13 Jun 2012 12:25:48 +0000 (13:25 +0100)
when (?{..}) or (??{..}) is enclosed in one of the modifiers like \Q,
don't parse it; treat it as plain characters that are modified by \Q etc.
This means that any code blocks will be interpreted by the regexp compiler
rather than the lexer. This restores behaviour similar to 5.14 and
earlier, except that the (?{}) is *completely* uninterpreted by the lexer,
whereas 5.14 would skip  till matching {}.

t/re/pat_re_eval.t
toke.c

index 20bc7b3..5a79942 100644 (file)
@@ -22,7 +22,7 @@ BEGIN {
 }
 
 
-plan tests => 123;  # Update this when adding/deleting tests.
+plan tests => 127;  # Update this when adding/deleting tests.
 
 run_tests() unless caller;
 
@@ -342,6 +342,17 @@ sub run_tests {
        }
     }
 
+    {
+       # re evals within \U, \Q etc shouldn't be seen by the lexer
+       local our $a  = "i";
+       local our $B  = "J";
+       ok('(?{1})' =~ /^\Q(?{1})\E$/,   '\Q(?{1})\E');
+       ok('(?{1})' =~ /^\Q(?{\E1\}\)$/, '\Q(?{\E1\}\)');
+       use re 'eval';
+       ok('Ia' =~ /^\U(??{"$a\Ea"})$/,  '^\U(??{"$a\Ea"})$');
+       ok('ja' =~ /^\L(??{"$B\Ea"})$/,  '^\L(??{"$B\Ea"})$');
+    }
+
 } # End of sub run_tests
 
 1;
diff --git a/toke.c b/toke.c
index 015a415..a823597 100644 (file)
--- a/toke.c
+++ b/toke.c
@@ -2870,8 +2870,9 @@ S_scan_const(pTHX_ char *start)
                while (s+1 < send && *s != ')')
                    *d++ = NATIVE_TO_NEED(has_utf8,*s++);
            }
-           else if (s[2] == '{' /* This should match regcomp.c */
-                   || (s[2] == '?' && s[3] == '{'))
+           else if (!PL_lex_casemods &&
+                    (    s[2] == '{' /* This should match regcomp.c */
+                     || (s[2] == '?' && s[3] == '{')))
            {
                break;
            }