This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
toke.c, S_scan_ident: Ignore whitespace on both sides of ${ ... }
authorBrian Fraser <fraserbn@gmail.com>
Fri, 15 Mar 2013 00:05:23 +0000 (21:05 -0300)
committerKarl Williamson <public@khwilliamson.com>
Fri, 15 Mar 2013 19:48:41 +0000 (13:48 -0600)
${ var } (and ${ \7LOBAL_PHASE}) were broken by 32833930e. However,
it turns out that the behavior prior to that commit was already
strange:

${ .};              # Legal
${. };              # Illegal
${ . };             # Illegal
${  \7LOBAL_PHASE}; # Legal
${  ^GLOBAL_PHASE}; # Illegal
${^GLOBAL_PHASE };  # Illegal

This commit restores ${ var } and makes all of the above work by
always ignoring spaces on both sides of ${ ... }.

t/uni/variables.t
toke.c

index 9a469d6..cee681f 100644 (file)
@@ -12,7 +12,7 @@ use utf8;
 use open qw( :utf8 :std );
 no warnings qw(misc reserved);
 
-plan (tests => 65856);
+plan (tests => 65869);
 
 # ${single:colon} should not be valid syntax
 {
@@ -201,3 +201,29 @@ EOP
         );
     }
 }
+
+{
+    # bleadperl v5.17.9-109-g3283393 breaks JEREMY/File-Signature-1.009.tar.gz
+    # https://rt.perl.org/rt3/Ticket/Display.html?id=117145
+    local $@;
+    my $var = 10;
+    eval ' ${  var  }';
+
+    is(
+        $@,
+        '',
+        '${  var  } works under strict'
+    );
+
+    {
+        no strict;
+        for my $var ( '$', "\7LOBAL_PHASE", "^GLOBAL_PHASE", "^V" ) {
+            eval "\${ $var}";
+            is($@, '', "\${ $var} works" );
+            eval "\${$var }";
+            is($@, '', "\${$var } works" );
+            eval "\${ $var }";
+            is($@, '', "\${ $var } works" );
+        }
+    }
+}
diff --git a/toke.c b/toke.c
index 332f653..66a197f 100644 (file)
--- a/toke.c
+++ b/toke.c
@@ -9292,6 +9292,8 @@ S_scan_ident(pTHX_ char *s, const char *send, char *dest, STRLEN destlen, I32 ck
     if (*s == '{') {
        bracket = s;
        s++;
+       while (s < send && SPACE_OR_TAB(*s))
+          s++;
     }
 
 #define VALID_LEN_ONE_IDENT(d, u)     (isPUNCT_A((U8)*(d))     \
@@ -9320,15 +9322,6 @@ S_scan_ident(pTHX_ char *s, const char *send, char *dest, STRLEN destlen, I32 ck
     else if (ck_uni && !bracket)
        check_uni();
     if (bracket) {
-       if (isSPACE(s[-1])) {
-           while (s < send) {
-               const char ch = *s++;
-               if (!SPACE_OR_TAB(ch)) {
-                   *d = ch;
-                   break;
-               }
-           }
-       }
        if (isIDFIRST_lazy_if(d,is_utf8)) {
         d += is_utf8 ? UTF8SKIP(d) : 1;
         parse_ident(&s, &d, e, 1, is_utf8);
@@ -9364,6 +9357,10 @@ S_scan_ident(pTHX_ char *s, const char *send, char *dest, STRLEN destlen, I32 ck
                Perl_croak(aTHX_ "%s", ident_too_long);
            *d = '\0';
        }
+
+        while (s < send && SPACE_OR_TAB(*s))
+           s++;
+
        if (*s == '}') {
            s++;
            if (PL_lex_state == LEX_INTERPNORMAL && !PL_lex_brackets) {