diff options
author | Yves Orton <demerphq@gmail.com> | 2022-07-27 13:35:38 +0200 |
---|---|---|
committer | Yves Orton <demerphq@gmail.com> | 2022-07-30 08:24:48 +0200 |
commit | c432f9f481035e7fd99dbaa182996c34f312fc9d (patch) | |
tree | 0cefcdf8bf735fe0835ed48e03c7e5b7212b91c0 /t/re | |
parent | 5d7d8ffc298134400c054265830d47abb6ee7845 (diff) | |
download | perl-c432f9f481035e7fd99dbaa182996c34f312fc9d.tar.gz |
toke.c - consistently refuse octal digit vars, and allow ${10} under strict.
Executive summary: in ${ .. } style notation consistently forbid octal
and allow multi-digit longer decimal values under strict. The vars
${1} through ${9} have always been allowed under strict, but ${10} threw
an error unlike its equivalent variable $10.
In 60267e1d0e12bb5bdc88c62a18294336ab03d4b8 I patched toke.c to refuse
octal like $001 but did not properly handle ${001} and related cases when
the code was under 'use utf8'. Part of the reason was the confusing macro
VALID_LEN_ONE_IDENT() which despite its name does not restrict what it
matches to things which are one character long.
Since the VALID_LEN_ONE_IDENT() macro is used in only one place and its
name and placement is confusing I have moved it back into the code
inline as part of this fix. I have also added more comments about what
is going on, and moved the related comment directly next to the code
that it affects. If it moved out of this code then we should think of a
better name and be more careful and clear about checking things like
length. I would argue the logic is used to parse what might be called a
variable "description", and thus it is not identical to code which might
validate an actual parsed variable name. Eg, ${^Var} is a description of
the variable whose "name" is "\026ar". The exception of course is $^
whose name actually is "^".
This includes more tests for allowed vars and forbidden var names.
See Issue #12948, Issue #19986, and Issue #19989.
Diffstat (limited to 't/re')
-rw-r--r-- | t/re/pat.t | 30 |
1 files changed, 29 insertions, 1 deletions
diff --git a/t/re/pat.t b/t/re/pat.t index 7292e4625a..2ce4ca8764 100644 --- a/t/re/pat.t +++ b/t/re/pat.t @@ -27,7 +27,7 @@ skip_all_without_unicode_tables(); my $has_locales = locales_enabled('LC_CTYPE'); -plan tests => 1046; # Update this when adding/deleting tests. +plan tests => 1214; # Update this when adding/deleting tests. run_tests() unless caller; @@ -35,6 +35,34 @@ run_tests() unless caller; # Tests start here. # sub run_tests { + { + # see https://github.com/Perl/perl5/issues/12948 + my $string="ABCDEFGHIJKL"; + my $pat= "(.)" x length($string); + my $ok= $string=~/^$pat\z/; + foreach my $n (1 .. length($string)) { + $ok= eval sprintf 'is $%d, "%s", q($%d = %s); 1', ($n, substr($string,$n-1,1))x2; + ok($ok, "eval for \$$n test"); + $ok= eval sprintf 'is ${%d}, "%s", q(${%d} = %s); 1', ($n, substr($string,$n-1,1))x2; + ok($ok, "eval for \${$n} test"); + + $ok= eval sprintf 'is $0%d, "%s", q($0%d = %s); 1', ($n, substr($string,$n-1,1))x2; + ok(!$ok, "eval failed as expected for \$0$n test"); + $ok= eval sprintf 'is ${0%d}, "%s", q(${0%d} = %s); 1', ($n, substr($string,$n-1,1))x2; + ok(!$ok, "eval failed as expected for \${0$n} test"); + + no strict 'refs'; + $ok= eval sprintf 'is ${0b%b}, "%s", q(${0b%b} = %s); 1', ($n, substr($string,$n-1,1))x2; + ok($ok, sprintf "eval for \${0b%b} test", $n); + $ok= eval sprintf 'is ${0x%x}, "%s", q(${0x%x} = %s); 1', ($n, substr($string,$n-1,1))x2; + ok($ok, sprintf "eval for \${0x%x} test", $n); + $ok= eval sprintf 'is ${0b%08b}, "%s", q(${0b%08b} = %s); 1', ($n, substr($string,$n-1,1))x2; + ok($ok, sprintf "eval for \${0b%b} test", $n); + $ok= eval sprintf 'is ${0x%04x}, "%s", q(${0x%04x} = %s); 1', ($n, substr($string,$n-1,1))x2; + ok($ok, sprintf "eval for \${0x%04x} test", $n); + } + } + my $sharp_s = uni_to_native("\xdf"); { |