xref: /openbsd-src/gnu/usr.bin/perl/t/uni/variables.t (revision 50b7afb2c2c0993b0894d4e34bf857cb13ed9c80)
1#!./perl
2
3# Checks if the parser behaves correctly in edge case
4# (including weird syntax errors)
5
6BEGIN {
7    require './test.pl';
8}
9
10use 5.016;
11use utf8;
12use open qw( :utf8 :std );
13no warnings qw(misc reserved);
14
15plan (tests => 65869);
16
17# ${single:colon} should not be valid syntax
18{
19    no strict;
20
21    local $@;
22    eval "\${\x{30cd}single:\x{30cd}colon} = 1";
23    like($@,
24         qr/syntax error .* near "\x{30cd}single:/,
25         '${\x{30cd}single:\x{30cd}colon} should not be valid syntax'
26        );
27
28    local $@;
29    no utf8;
30    evalbytes '${single:colon} = 1';
31    like($@,
32         qr/syntax error .* near "single:/,
33         '...same with ${single:colon}'
34        );
35}
36
37# ${yadda'etc} and ${yadda::etc} should both work under strict
38{
39    local $@;
40    eval q<use strict; ${flark::fleem}>;
41    is($@, '', q<${package::var} works>);
42
43    local $@;
44    eval q<use strict; ${fleem'flark}>;
45    is($@, '', q<...as does ${package'var}>);
46}
47
48# The first character in ${...} should respect the rules
49{
50   local $@;
51   use utf8;
52   eval '${☭asd} = 1';
53   like($@, qr/\QUnrecognized character/, q(the first character in ${...} isn't special))
54}
55
56# Checking that at least some of the special variables work
57for my $v (qw( ^V ; < > ( ) {^GLOBAL_PHASE} ^W _ 1 4 0 [ ] ! @ / \ = )) {
58    local $@;
59    evalbytes "\$$v;";
60    is $@, '', "No syntax error for \$$v";
61
62    local $@;
63    eval "use utf8; \$$v;";
64    is $@, '', "No syntax error for \$$v under use utf8";
65}
66
67# Checking if the Latin-1 range behaves as expected, and that the behavior is the
68# same whenever under strict or not.
69for ( 0x80..0xff ) {
70    no warnings 'closure';
71    my $chr = chr;
72    my $esc = sprintf("%X", ord $chr);
73    utf8::downgrade($chr);
74    if ($chr !~ /\p{XIDS}/u) {
75        is evalbytes "no strict; \$$chr = 10",
76            10,
77            sprintf("\\x%02x, part of the latin-1 range, is legal as a length-1 variable", $_);
78
79        utf8::upgrade($chr);
80        local $@;
81        eval "no strict; use utf8; \$$chr = 1";
82        like $@,
83            qr/\QUnrecognized character \x{\E\L$esc/,
84            sprintf("..but is illegal as a length-1 variable under use utf8", $_);
85    }
86    else {
87        {
88            no utf8;
89            local $@;
90            evalbytes "no strict; \$$chr = 1";
91            is($@, '', sprintf("\\x%02x, =~ \\p{XIDS}, latin-1, no utf8, no strict, is a valid length-1 variable", $_));
92
93            local $@;
94            evalbytes "use strict; \$$chr = 1";
95            is($@,
96                '',
97                sprintf("\\x%02x under no utf8 does not have to be required under strict, even though it matches XIDS", $_)
98            );
99
100            local $@;
101            evalbytes "\$a$chr = 1";
102            like($@,
103                qr/Unrecognized character /,
104                sprintf("...but under no utf8, it's not allowed in two-or-more character variables")
105            );
106
107            local $@;
108            evalbytes "\$a$chr = 1";
109            like($@,
110                qr/Unrecognized character /,
111                sprintf("...but under no utf8, it's not allowed in two-or-more character variables")
112            );
113        }
114        {
115            use utf8;
116            my $u = $chr;
117            utf8::upgrade($u);
118            local $@;
119            eval "no strict; \$$u = 1";
120            is($@, '', sprintf("\\x%02x, =~ \\p{XIDS}, UTF-8, use utf8, no strict, is a valid length-1 variable", $_));
121
122            local $@;
123            eval "use strict; \$$u = 1";
124            like($@,
125                qr/Global symbol "\$$u" requires explicit package name/,
126                sprintf("\\x%02x under utf8 has to be required under strict", $_)
127            );
128        }
129    }
130}
131
132{
133    use utf8;
134    my $ret = eval "my \$c\x{327} = 100; \$c\x{327}"; # c + cedilla
135    is($@, '', "ASCII character + combining character works as a variable name");
136    is($ret, 100, "...and returns the correct value");
137}
138
139# From Tom Christiansen's 'highly illegal variable names are now accidentally legal' mail
140for my $chr (
141      "\N{EM DASH}", "\x{F8FF}", "\N{POUND SIGN}", "\N{SOFT HYPHEN}",
142      "\N{THIN SPACE}", "\x{11_1111}", "\x{DC00}", "\N{COMBINING DIAERESIS}",
143      "\N{COMBINING ENCLOSING CIRCLE BACKSLASH}",
144   )
145{
146   no warnings 'non_unicode';
147   my $esc = sprintf("%x", ord $chr);
148   local $@;
149   eval "\$$chr = 1; \$$chr";
150   like($@,
151        qr/\QUnrecognized character \x{$esc};/,
152        "\\x{$esc} is illegal for a length-one identifier"
153       );
154}
155
156for my $i (0x100..0xffff) {
157   my $chr = chr($i);
158   my $esc = sprintf("%x", $i);
159   local $@;
160   eval "my \$$chr = q<test>; \$$chr;";
161   if ( $chr =~ /^\p{_Perl_IDStart}$/ ) {
162      is($@, '', sprintf("\\x{%04x} is XIDS, works as a length-1 variable", $i));
163   }
164   else {
165      like($@,
166           qr/\QUnrecognized character \x{$esc};/,
167           "\\x{$esc} isn't XIDS, illegal as a length-1 variable",
168          )
169   }
170}
171
172{
173    # Bleadperl v5.17.9-109-g3283393 breaks ZEFRAM/Module-Runtime-0.013.tar.gz
174    # https://rt.perl.org/rt3/Public/Bug/Display.html?id=117101
175    no strict;
176
177    local $@;
178    eval <<'EOP';
179    q{$} =~ /(.)/;
180    is($$1, $$, q{$$1 parses as ${$1}});
181
182    $doof = "test";
183    $test = "Got here";
184    $::{+$$} = *doof;
185
186    is( $$$$1, $test, q{$$$$1 parses as ${${${$1}}}} );
187EOP
188    is($@, '', q{$$1 parses correctly});
189
190    for my $chr ( q{@}, "\N{U+FF10}", "\N{U+0300}" ) {
191        my $esc = sprintf("\\x{%x}", ord $chr);
192        local $@;
193        eval <<"    EOP";
194            \$$chr = q{\$};
195            \$\$$chr;
196    EOP
197
198        like($@,
199             qr/syntax error|Unrecognized character/,
200             qq{\$\$$esc is a syntax error}
201        );
202    }
203}
204
205{
206    # bleadperl v5.17.9-109-g3283393 breaks JEREMY/File-Signature-1.009.tar.gz
207    # https://rt.perl.org/rt3/Ticket/Display.html?id=117145
208    local $@;
209    my $var = 10;
210    eval ' ${  var  }';
211
212    is(
213        $@,
214        '',
215        '${  var  } works under strict'
216    );
217
218    {
219        no strict;
220        for my $var ( '$', "\7LOBAL_PHASE", "^GLOBAL_PHASE", "^V" ) {
221            eval "\${ $var}";
222            is($@, '', "\${ $var} works" );
223            eval "\${$var }";
224            is($@, '', "\${$var } works" );
225            eval "\${ $var }";
226            is($@, '', "\${ $var } works" );
227        }
228    }
229}
230