Skip to content

Commit

Permalink
[perl #119123] disallow literal control character variables
Browse files Browse the repository at this point in the history
This introduces a deprecation warning on things like $^T, where ^T
is a literal control character in the source code.
  • Loading branch information
Hugmeir committed Sep 18, 2013
1 parent f7bd557 commit b29f65f
Show file tree
Hide file tree
Showing 8 changed files with 93 additions and 13 deletions.
3 changes: 3 additions & 0 deletions pod/perldata.pod
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,9 @@ property, like C<$!> or C<%+>.

=back

Note that as of Perl 5.20, literal control characters in variable names
are deprecated.

=head2 Context
X<context> X<scalar context> X<list context>

Expand Down
13 changes: 12 additions & 1 deletion pod/perldelta.pod
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,18 @@ numeric values under the hood.)

=head1 Deprecations

XXX Any deprecated features, syntax, modules etc. should be listed here.
=head2 Literal control characters in variable names

This deprecation affects things like C<$\cT>, where \cT is a literal
control in the source code. Surprisingly, it appears that originally
this was intended as the canonical way of accessing variables like
C<$^T>, with the caret form only being added as an alternative.

The literal control form is being deprecated for two main reasons: It
has what are likely unfixable bugs, such as C<$\cI> not working as an
alias for C<$^I>, and their usage not being portable to non-ASCII
platforms: While C<$^T> will work everywhere, C<\cT> is whitespace in
EBCDIC.

=head2 Module removals

Expand Down
7 changes: 7 additions & 0 deletions pod/perldiag.pod
Original file line number Diff line number Diff line change
Expand Up @@ -6077,6 +6077,13 @@ startup.
In code that currently says C<use AutoLoader; @ISA = qw(AutoLoader);>
you should remove AutoLoader from @ISA and change C<use AutoLoader;> to
C<use AutoLoader 'AUTOLOAD';>.

=item Use of literal control characters in variable names is deprecated

(D deprecated) Using literal control characters in the source to refer
to the ^FOO variables, like C<$^X> and C<${^GLOBAL_PHASE}> is now
deprecated. This only affects code like C<$\cT>, where \cT is a control in
the source code: C<${"\cT"}> and C<$^T> remain valid.

=item Use of %s in printf format not supported

Expand Down
12 changes: 1 addition & 11 deletions t/base/lex.t
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!./perl

print "1..94\n";
print "1..91\n";

$x = 'x';

Expand Down Expand Up @@ -129,16 +129,6 @@ my $test = 31;
if ($ {^XY} != 23) { print "not " }
print "ok $test\n"; $test++;

# Does the syntax where we use the literal control character still work?
if (eval "\$ {\cX}" != 17 or $@) { print "not " }
print "ok $test\n"; $test++;

eval "\$\cQ = 24"; # Literal control character
if ($@ or ${"\cQ"} != 24) { print "not " }
print "ok $test\n"; $test++;
if ($^Q != 24) { print "not " } # Control character escape sequence
print "ok $test\n"; $test++;

# Does the old UNBRACED syntax still do what it used to?
if ("$^XY" ne "17Y") { print "not " }
print "ok $test\n"; $test++;
Expand Down
37 changes: 37 additions & 0 deletions t/lib/warnings/toke
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,32 @@ EXPECT
Use of bare << to mean <<"" is deprecated at - line 2.
########
# toke.c
eval "\$\cT";
eval "\${\7LOBAL_PHASE}";
eval "\${\cT}";
eval "\${\n\cT}";
eval "\${\cT\n}";
my $ret = eval "\${\n\cT\n}";
print "ok\n" if $ret == $^T;

no warnings 'deprecated' ;
eval "\$\cT";
eval "\${\7LOBAL_PHASE}";
eval "\${\cT}";
eval "\${\n\cT}";
eval "\${\cT\n}";
eval "\${\n\cT\n}";

EXPECT
Use of literal control characters in variable names is deprecated at (eval 1) line 1.
Use of literal control characters in variable names is deprecated at (eval 2) line 1.
Use of literal control characters in variable names is deprecated at (eval 3) line 1.
Use of literal control characters in variable names is deprecated at (eval 4) line 1.
Use of literal control characters in variable names is deprecated at (eval 5) line 1.
Use of literal control characters in variable names is deprecated at (eval 6) line 1.
ok
########
# toke.c
$a =~ m/$foo/eq;
$a =~ s/$foo/fool/seq;

Expand Down Expand Up @@ -1379,3 +1405,14 @@ q
1
1
q
########
# toke.c
#[perl #119123] disallow literal control character variables
eval "\$\cQ = 25";
eval "\${ \cX } = 24";
*{
Foo
}; # shouldn't warn on {\n, even though \n is a control character
EXPECT
Use of literal control characters in variable names is deprecated at (eval 1) line 1.
Use of literal control characters in variable names is deprecated at (eval 2) line 1.
1 change: 1 addition & 0 deletions t/op/svleak.t
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ sub leak {
# if the name is absent.
sub eleak {
my ($n,$delta,$code,@rest) = @_;
no warnings 'deprecated'; # Silence the literal control character warning
leak $n, $delta, sub { eval $code },
@rest ? @rest : $code
}
Expand Down
29 changes: 28 additions & 1 deletion t/uni/variables.t
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use utf8;
use open qw( :utf8 :std );
no warnings qw(misc reserved);

plan (tests => 65873);
plan (tests => 65878);

# ${single:colon} should not be valid syntax
{
Expand Down Expand Up @@ -217,6 +217,9 @@ EOP

{
no strict;
# Silence the deprecation warning for literal controls
no warnings 'deprecated';

for my $var ( '$', "\7LOBAL_PHASE", "^GLOBAL_PHASE", "^V" ) {
eval "\${ $var}";
is($@, '', "\${ $var} works" );
Expand All @@ -242,7 +245,31 @@ EOP
"...but \$^J is still legal"
);

no warnings 'deprecated';
my $ret = eval "\${\cT\n}";
is($@, "", 'No errors from using ${\n\cT\n}');
is($ret, $^T, "...and we got the right value");
}

{
# Originally from t/base/lex.t, moved here since we can't
# turn deprecation warnings off in that file.
no strict;
no warnings 'deprecated';

my $CX = "\cX";
$ {$CX} = 17;

# Does the syntax where we use the literal control character still work?
is(
eval "\$ {\cX}",
17,
"Literal control character variables work"
);

eval "\$\cQ = 24"; # Literal control character
is($@, "", "...and they can be assigned to without error");
is(${"\cQ"}, 24, "...and the assignment works");
is($^Q, 24, "...even if we access the variable through the caret name");
is(\${"\cQ"}, \$^Q, '\${\cQ} == \$^Q');
}
4 changes: 4 additions & 0 deletions toke.c
Original file line number Diff line number Diff line change
Expand Up @@ -9437,6 +9437,10 @@ S_scan_ident(pTHX_ char *s, const char *send, char *dest, STRLEN destlen, I32 ck
if (s < send
&& (isIDFIRST_lazy_if(s, is_utf8) || VALID_LEN_ONE_IDENT(*s, is_utf8)))
{
if ( isCNTRL_A((U8)*s) ) {
deprecate("literal control characters in variable names");
}

if (is_utf8) {
const STRLEN skip = UTF8SKIP(s);
STRLEN i;
Expand Down

0 comments on commit b29f65f

Please sign in to comment.