File Coverage

blib/lib/Perl/Critic/Policy/ValuesAndExpressions/ProhibitUnknownBackslash.pm
Criterion Covered Total %
statement 144 149 96.6
branch 76 90 84.4
condition 40 50 80.0
subroutine 18 19 94.7
pod 2 2 100.0
total 280 310 90.3


line stmt bran cond sub pod time code
1             # Copyright 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2019, 2021 Kevin Ryde
2              
3             # Perl-Critic-Pulp is free software; you can redistribute it and/or modify
4             # it under the terms of the GNU General Public License as published by the
5             # Free Software Foundation; either version 3, or (at your option) any later
6             # version.
7             #
8             # Perl-Critic-Pulp is distributed in the hope that it will be useful, but
9             # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10             # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
11             # for more details.
12             #
13             # You should have received a copy of the GNU General Public License along
14             # with Perl-Critic-Pulp. If not, see <http://www.gnu.org/licenses/>.
15              
16              
17             package Perl::Critic::Policy::ValuesAndExpressions::ProhibitUnknownBackslash;
18 40     40   39934 use 5.006;
  40         171  
19 40     40   1401 use strict;
  40         101  
  40         879  
20 40     40   1703 use version (); # but don't import qv()
  40         2188  
  40         3060  
21 40     40   209 use warnings;
  40         87  
  40         1418  
22              
23             # 1.084 for Perl::Critic::Document highest_explicit_perl_version()
24 40     40   1883 use Perl::Critic::Policy 1.084;
  40         199185  
  40         1150  
25 40     40   274 use base 'Perl::Critic::Policy';
  40         107  
  40         4713  
26 40     40   1355 use Perl::Critic::Utils;
  40         93  
  40         2189  
27              
28 40     40   36757 use Perl::Critic::Pulp;
  40         107  
  40         3695  
29              
30             # uncomment this to run the ### lines
31             # use Smart::Comments;
32              
33             our $VERSION = 99;
34              
35 40         3227 use constant supported_parameters =>
36             ({ name => 'single',
37             description => 'Checking of single-quote strings.',
38             behavior => 'string',
39             default_string => 'none',
40             },
41             { name => 'double',
42             description => 'Checking of double-quote strings.',
43             behavior => 'string',
44             default_string => 'all',
45             },
46             { name => 'heredoc',
47             description => 'Checking of interpolated here-documents.',
48             behavior => 'string',
49             default_string => 'all',
50             },
51             { name => 'charnames',
52             description => 'Checking of character names \\N{}.',
53             behavior => 'string',
54             default_string => 'version',
55 40     40   283 });
  40         93  
56 40     40   274 use constant default_severity => $Perl::Critic::Utils::SEVERITY_MEDIUM;
  40         95  
  40         3428  
57 40     40   261 use constant default_themes => qw(pulp cosmetic);
  40         92  
  40         10156  
58              
59             sub applies_to {
60 290     290 1 1387433 my ($policy) = @_;
61             return (($policy->{'_single'} ne 'none'
62             ? ('PPI::Token::Quote::Single', # ''
63             'PPI::Token::Quote::Literal') # q{}
64             : ()),
65              
66             ($policy->{'_single'} ne 'none'
67             || $policy->{'_double'} ne 'none'
68             ? ('PPI::Token::QuoteLike::Command') # qx{} or qx''
69             : ()),
70              
71             ($policy->{'_double'} ne 'none'
72             ? ('PPI::Token::Quote::Double', # ""
73             'PPI::Token::Quote::Interpolate', # qq{}
74             'PPI::Token::QuoteLike::Backtick') # ``
75             : ()),
76              
77 290 100 66     3738 ($policy->{'_heredoc'} ne 'none'
    50          
    50          
    50          
78             ? ('PPI::Token::HereDoc')
79             : ()));
80             }
81              
82             # for violation messages
83             my %charname = ("\n" => '{newline}',
84             "\r" => '{cr}',
85             "\t" => '{tab}',
86             " " => '{space}');
87              
88 40         2646 use constant _KNOWN => (
89             't' # \t tab
90             . 'n' # \n newline
91             . 'r' # \r carriage return
92             . 'f' # \f form feed
93             . 'b' # \b backspace
94             . 'a' # \a bell
95             . 'e' # \e esc
96             . '0123' # \377 octal
97             . 'x' # \xFF \x{FF} hex
98             . 'c' # \cX control char
99              
100             . 'l' # \l lowercase one char
101             . 'u' # \u uppercase one char
102             . 'L' # \L lowercase string
103             . 'U' # \U uppercase string
104             . 'E' # \E end case or quote
105             . 'Q' # \Q quotemeta
106             . '$' # non-interpolation
107             . '@' # non-interpolation
108 40     40   308 );
  40         88  
109              
110 40         72104 use constant _CONTROL_KNOWN =>
111 40     40   275 '?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_abcdefghijklmnopqrstuvwxyz'; ## no critic (RequireInterpolationOfMetachars)
  40         1303  
112              
113             my $quotelike_re = qr/^(?:(q[qrwx]?) # $1 "q" if present
114             (?:(?:\s(?:\s*\#[^\n]*\n)*)\s*)? # possible comments
115             )? # possible "q"
116             (.) # $2 opening quote
117             (.*) # $3 guts
118             (.)$ # $4 closing quote
119             /xs;
120              
121             # extra explanation for double-quote interpolations
122             my %explain = ('%' => ' (hashes are not interpolated)',
123             '&' => ' (function calls are not interpolated)',
124             '4' => ' (until Perl 5.6 octal wide chars)',
125             '5' => ' (until Perl 5.6 octal wide chars)',
126             '6' => ' (until Perl 5.6 octal wide chars)',
127             '7' => ' (until Perl 5.6 octal wide chars)',
128             'N' => ' (without "use charnames" in scope)',
129             );
130              
131             my $v5016 = version->new('5.016');
132             my $v5006 = version->new('5.006');
133              
134             sub violates {
135 278     278 1 11195 my ($self, $elem, $document) = @_;
136              
137 278         658 my $have_perl_516;
138 278 100       900 if (defined (my $doc_version = $document->highest_explicit_perl_version)) {
139 36         8918 $have_perl_516 = ($doc_version >= $v5016);
140             }
141              
142 278         25279 my $content = $elem->content;
143 278         1692 my $close = substr ($content, -1, 1);
144 278         695 my $single = 0;
145 278         647 my ($param, $str);
146              
147 278 100       1325 if ($elem->isa('PPI::Token::HereDoc')) {
148 6 100       27 return if ($close eq "'"); # uninterpolated
149 4         11 $param = $self->{_heredoc};
150 4         14 $str = join ('', $elem->heredoc);
151              
152             } else {
153 272 100       1329 if ($elem->can('string')) {
154 258         1178 $str = $elem->string;
155             } else {
156 14 50       98 $elem =~ $quotelike_re or die "Oops, didn't match quotelike_re";
157 14         196 $str = $3;
158             }
159 272         4681 $str =~ s{((^|\G|[^\\])(\\\\)*)\\\Q$close}{$close}sg;
160              
161 272 100 100     3425 if ($elem->isa('PPI::Token::Quote::Single')
      100        
      100        
162             || $elem->isa('PPI::Token::Quote::Literal')
163             || ($elem->isa('PPI::Token::QuoteLike::Command')
164             && $close eq "'")) {
165 42         123 $single = 1;
166 42         156 $param = $self->{_single};
167              
168             } else {
169 230         828 $param = $self->{_double};
170             }
171             }
172 276 100       1236 return if ($param eq 'none');
173              
174 272         610 my $known = $close;
175              
176 272 100       882 if (! $single) {
177 234         512 $known .= _KNOWN;
178              
179             # Octal chars above \377 are in 5.6 up.
180             # Consider known if no "use 5.x" at all, or if present and 5.6 up,
181             # so only under explicit "use 5.005" or lower are they not allowed.
182 234         706 my $perlver = $document->highest_explicit_perl_version;
183 234 100 100     2951 if (! defined $perlver || $perlver >= $v5006) {
184 210         461 $known .= '4567';
185             }
186             }
187              
188             ### elem: ref $elem
189             ### $content
190             ### $str
191             ### close char: $close
192             ### $known
193             ### perlver: $document->highest_explicit_perl_version
194              
195 272         515 my $have_use_charnames;
196 272         701 my $interpolate_var_end = -1;
197 272         727 my $interpolate_var_colon;
198             my @violations;
199              
200 272         1920 while ($str =~ /(\$. # $ not at end-of-string
201             |\@[[:alnum:]:'\{\$+-]) # @ forms per toke.c S_scan_const()
202             |(\\+) # $2 run of backslashes
203             /sgx) {
204 374 100       3437 if (defined $1) {
205             # $ or @
206 54 50       128 unless ($single) { # no variables in single-quote
207             ### interpolation at: pos($str)
208 54   50     168 my $new_pos = _pos_after_interpolate_variable
209             ($str, pos($str) - length($1))
210             || last;
211 54         4809 pos($str) = $new_pos;
212             ### ends at: pos($str)
213 54 50       337 if (substr($str,pos($str)-1,1) =~ /(\w)|[]}]/) {
214 54         155 $interpolate_var_colon = $1;
215 54         109 $interpolate_var_end = pos($str);
216             ### interpolate_var_end set to: $interpolate_var_end
217             }
218             }
219 54         253 next;
220             }
221              
222 320 100       1246 if ((length($2) & 1) == 0) {
223             # even number of backslashes, not an escape
224 14         72 next;
225             }
226              
227             # shouldn't have \ as the last char in $str, but if that happends then
228             # $c is empty string ''
229              
230 306         839 my $c = substr($str,pos($str),1);
231 306         970 pos($str)++;
232              
233 306 100       1121 if (! $single) {
234 274 100 100     1451 if ($c eq 'N') {
    100          
    100          
    100          
    100          
235 28 100       183 if ($self->{_charnames} eq 'disallow') {
    100          
236 6         39 push @violations,
237             $self->violation ('charnames \\N disallowed by config',
238             '', $elem);
239 6         1522 next;
240              
241             } elsif ($self->{_charnames} eq 'allow') {
242 6         44 next; # ok, allow by config
243              
244             } else { # $self->{_charnames} eq 'version'
245 16 50       77 if (! defined $have_use_charnames) {
246 16         72 $have_use_charnames = _have_use_charnames_in_scope($elem);
247             }
248 16 100 100     208 if ($have_use_charnames || $have_perl_516) {
249 8         60 next; # ok if "use charnames" or perl 5.16 up (which autoloads that)
250             }
251             }
252              
253             } elsif ($c eq 'c') {
254             # \cX control char.
255             # If \c is at end-of-string then new $c is '' and pos() will goes past
256             # length($str). That pos() is ok, the loop regexp gives no-match and
257             # terminates.
258 32         110 $c = substr ($str, pos($str)++, 1);
259 32 100       120 if ($c eq '') {
260 4         17 push @violations,
261             $self->violation ('Control char \\c at end of string', '', $elem);
262 4         699 next;
263             }
264 28 100       87 if (index (_CONTROL_KNOWN, $c) >= 0) {
265 22         83 next; # a known escape
266             }
267 6         24 push @violations,
268             $self->violation ('Unknown control char \\c' . _printable($c),
269             '', $elem);
270 6         1004 next;
271              
272             } elsif ($c eq ':') {
273 34 100       123 if ($interpolate_var_colon) {
274             ### backslash colon, pos: pos($str)
275             ### $interpolate_var_end
276             ### substr: substr ($str, $interpolate_var_end, 2)
277 20 50 33     97 if (pos($str) == $interpolate_var_end+2
      66        
278             || (pos($str) == $interpolate_var_end+4
279             && substr ($str, $interpolate_var_end, 2) eq '\\:')) {
280 20         77 next;
281             }
282             }
283              
284             } elsif ($c eq '[' || $c eq '{') {
285             ### backslash bracket, pos: pos($str)
286             ### $interpolate_var_end
287 26 100       77 if (pos($str) == $interpolate_var_end+2) {
288 18         79 next;
289             }
290              
291             } elsif ($c eq '-') {
292             ### backslash dash: pos($str)
293 10 100       47 if ($str =~ /\G>[[{]/) {
294             ### is for bracket or brace, pos now: pos($str)
295 4         21 next;
296             }
297             }
298             }
299              
300 212 100       775 if ($param eq 'quotemeta') {
    50          
301             # only report on chars quotemeta leaves unchanged
302 2 50       24 next if $c ne quotemeta($c);
303             } elsif ($param eq 'alnum') {
304             # only report unknown alphanumerics, like perl does
305             # believe perl only reports ascii alnums as bad, wide char alphas ok
306 0 0       0 next if $c !~ /[a-zA-Z0-9]/;
307             }
308              
309             # if $c eq '' for end-of-string then index() returns 0, for no violation
310 210 100       688 if (index ($known, $c) >= 0) {
311             # a known escape
312 86         354 next;
313             }
314              
315 124   100     658 my $explain = !$single && ($explain{$c} || '');
316 124         457 my $message = ('Unknown or unnecessary backslash \\'._printable($c)
317             . $explain);
318 124         657 push @violations, $self->violation ($message, '', $elem);
319              
320             # would have to take into account HereDoc begins on next line ...
321             # _violation_elem_offset ($violation, $elem, pos($str)-2);
322             }
323 272         23568 return @violations;
324             }
325              
326             # $pos is a position within $str of a "$" or "@" interpolation.
327             # Return the position within $str after that variable or expression.
328             #
329             # FIXME: Would like PPI to do this. Its PPI::Token::Quote::Double version
330             # 1.236 interpolations() has a comment that returning the expressions would
331             # be good.
332             #
333             sub _pos_after_interpolate_variable {
334 72     72   16127 my ($str, $pos) = @_;
335 72         218 $str = substr ($str, $pos);
336             ### _pos_after_interpolate_variable() ...
337             ### $str
338              
339             # PPI circa 1.236 doesn't like to parse non-ascii as program code
340             # identifiers etc, try changing to spaces for measuring.
341             #
342             # Might be happy for it to parse the interpolate expression and ignore
343             # anything bad after, but PPI::Tokenizer crunches a whole line at a time
344             # or something like that.
345             #
346 72         216 $str =~ s/[^[:print:]\t\r\n]/ /g;
347              
348 72         1116 require PPI::Document;
349 72         43516 my $doc = PPI::Document->new(\$str);
350 72   33     110531 my $elem = $doc && $doc->child(0);
351 72   33     886 $elem = $elem && $elem->child(0);
352 72 50       600 if (! $elem) {
353 0         0 warn "ProhibitUnknownBackslash: oops, cannot parse interpolation, skipping string";
354 0         0 return undef;
355             }
356             ### elem: ref $elem
357             ### length: length($elem->content)
358 72         226 $pos += length($elem->content);
359              
360 72 100       593 if ($elem->isa('PPI::Token::Cast')) {
    100          
361             # get the PPI::Structure::Block following "$" or "@", can have
362             # whitespace before it too
363 10         55 while ($elem = $elem->next_sibling) {
364             ### and: "$elem"
365             ### length: length($elem->content)
366 10         368 $pos += length($elem->content);
367 10 50       517 last if $elem->isa('PPI::Structure::Block');
368             }
369              
370             } elsif ($elem->isa('PPI::Token::Symbol')) {
371             # any subscripts 'PPI::Structure::Subscript' following, like "$hash{...}"
372             # whitespace stops the subscripts, so that Struct alone
373 58         121 for (;;) {
374 92   100     1219 $elem = $elem->next_sibling || last;
375 87 100       2116 $elem->isa('PPI::Structure::Subscript') || last;
376             ### and: "$elem"
377             ### length: length($elem->content)
378 34         110 $pos += length($elem->content);
379             }
380             }
381              
382 72         384 return $pos;
383             }
384              
385             # use Perl::Critic::Policy::Compatibility::PodMinimumVersion;
386             sub _violation_elem_offset {
387 0     0   0 my ($violation, $elem, $offset) = @_;
388 0         0 return $violation;
389              
390             #
391             # my $pre = substr ($elem->content, 0, $offset);
392             # my $newlines = ($pre =~ tr/\n//);
393             #
394             # my $document = $elem->document;
395             # my $doc_str = $document->content;
396             #
397             # return Perl::Critic::Pulp::Utils::_violation_override_linenum ($violation, $doc_str, $newlines - 1);
398             }
399              
400             sub _printable {
401 130     130   408 my ($c) = @_;
402 130 100       493 $c =~ s{([^[:graph:]]|[^[:ascii:]])}
  12         137  
403 130         504 { $charname{$1} || sprintf('{0x%X}',ord($1)) }e;
404             return $c;
405             }
406              
407             # return true if $elem has a 'use charnames' in its lexical scope
408 16     16   57 sub _have_use_charnames_in_scope {
409 16         46 my ($elem) = @_;
410 48   100     330 for (;;) {
411             $elem = $elem->sprevious_sibling || $elem->parent
412 36 100 66     1458 || return 0;
      100        
      100        
413             if ($elem->isa ('PPI::Statement::Include')
414             && $elem->type eq 'use'
415 4         239 && ($elem->module || '') eq 'charnames') {
416             return 1;
417             }
418             }
419             }
420              
421              
422             #-----------------------------------------------------------------------------
423             # unused bits
424              
425             # # $elem is a PPI::Token::Quote, PPI::Token::QuoteLike or PPI::Token::HereDoc
426             # sub _string {
427             # my ($elem) = @_;
428             # if ($elem->can('heredoc')) {
429             # return join ('', $elem->heredoc);
430             # }
431             # if ($elem->can('string')) {
432             # return $elem->string;
433             # }
434             # $elem =~ $quotelike_re
435             # or die "Oops, didn't match quote_re";
436             # return $3;
437             # }
438              
439             # # $elem is a PPI::Token::Quote or PPI::Token::QuoteLike
440             # # return ($q, $open, $close) where $q is the "q" intro or empty string if
441             # # none, and $open and $close are the quote chars
442             # sub _quote_delims {
443             # my ($elem) = @_;
444             # if ($elem->can('heredoc')) {
445             # return '"', '"';
446             # }
447             # $elem =~ $quotelike_re
448             # or die "Oops, didn't match quote_re";
449             # return ($1||'', $2, $4);
450             # }
451              
452             # perlop "Quote and Quote-like Operators"
453             # my $known = '';
454             # if ($elem->isa ('PPI::Token::Quote::Double')
455             # || $elem->isa ('PPI::Token::Quote::Interpolate')
456             # || $elem->isa ('PPI::Token::QuoteLike::Backtick')
457             # || ($elem->isa ('PPI::Token::QuoteLike::Command')
458             # && $close ne '\'') # no interpolation in qx'echo hi'
459             # ) {
460             # $known = 'tnrfbae0123xcluLUQE$@';
461             #
462             # # \N and octals bigger than 8-bits are in 5.6 up, and allow them if no
463             # # "use 5.x" at all too
464             # my $perlver = $document->highest_explicit_perl_version;
465             # if (! defined $perlver || $perlver >= 5.006) {
466             # $known .= 'N456789';
467             # }
468             # }
469             # $known .= $close;
470             #
471             # my $re = qr/\\+[^\\$known$close]/;
472             # my $unknown = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
473             # $unknown =~ s{(.)}
474             # {index($known,$1) >= 0 ? '' : $1}eg;
475              
476             1;
477             __END__
478              
479             =for stopwords backslashed upcase FS unicode ascii non-ascii ok alnum quotemeta backslashing backticks Ryde coderef alphanumerics arrowed
480              
481             =head1 NAME
482              
483             Perl::Critic::Policy::ValuesAndExpressions::ProhibitUnknownBackslash - don't use undefined backslash forms
484              
485             =head1 DESCRIPTION
486              
487             This policy is part of the L<C<Perl::Critic::Pulp>|Perl::Critic::Pulp>
488             add-on. It checks for unknown backslash escapes like
489              
490             print "\*.c"; # bad
491              
492             This is harmless, assuming the intention is a literal "*" (which it gives),
493             but unnecessary, and on that basis this policy is under the C<cosmetic>
494             theme (see L<Perl::Critic/POLICY THEMES>). Sometimes it can be a
495             misunderstanding or a typo though, for instance a backslashed newline is a
496             newline, but perhaps you thought it meant a continuation.
497              
498             print "this\ # bad
499             is a newline";
500              
501             Perl already warns about unknown escaped alphanumerics like C<\v> under
502             C<perl -w> or C<use warnings> (see L<perldiag/Unrecognized escape \%c passed
503             through>).
504              
505             print "\v"; # bad, and provokes Perl warning
506              
507             This policy extends to report on any unknown escape, with options below to
508             vary the strictness and to check single-quote strings too if desired.
509              
510             =head2 Control Characters \c
511              
512             Control characters C<\cX> are checked and only the conventional A-Z a-z @ [
513             \ ] ^ _ ? are considered known.
514              
515             print "\c*"; # bad
516              
517             Perl accepts any C<\c> and does an upcase xor 0x40, so C<\c*> is letter "j",
518             at least on an ASCII system. But that's obscure and likely to be a typo or
519             error.
520              
521             For reference, C<\c\> is the ASCII FS "file separator" and the second
522             backslash is not an escape, except for a closing quote character, which it
523             does escape (basically because Perl scans for a closing quote before
524             considering interpolations). Thus,
525              
526             print " \c\ "; # ok, control-\ FS
527             print " \c\" "; # bad, control-" is unknown
528             print qq[ \c\] ]; # ok, control-] GS
529              
530             =head2 Ending Interpolation
531              
532             A backslashed colon, bracket, brace or dash is allowed after an interpolated
533             variable or element, since this stops interpolation at that point.
534              
535             print "$foo\::bar"; # ok, $foo
536             print "@foo\::"; # ok, @foo
537              
538             print "$foo[0]\[1]"; # ok, is $foo[0]
539             print "$esc\[1m"; # ok
540              
541             print "$foo\{k}"; # ok
542             print "$foo\{k}"; # ok
543             print "$foo{k}\[0]"; # ok, is $foo{k}
544             print "@foo\{1,2}"; # ok, is @foo
545              
546             print "$foo\->[0]"; # ok, is $foo
547             print "$foo\->{zz}"; # ok
548              
549             A single backslash like C<"\::"> is enough for the colon case, but
550             backslashing the second too as C<"\:\:"> is quite common and is allowed.
551              
552             print "$#foo\:\:bar"; # ok
553              
554             Only an array or hash C<-E<gt>[]> or C<-E<gt>{}> need C<\-> to stop
555             interpolation. Other cases such as an apparent method call or arrowed
556             coderef call don't interpolate and the backslash is treated as unknown since
557             unnecessary.
558              
559             print "$coderef\->(123)"; # bad, unnecessary
560             print "Usage: $class\->foo()"; # bad, unnecessary
561              
562             For reference, the alternative in all the above is to write C<{}> braces
563             around the variable or element to delimit from anything following. Doing so
564             may be clearer than backslashing,
565              
566             print "${foo}::bar"; # alternatives
567             print "@{foo}::bar";
568             print "$#{foo}th";
569             print "${foo[0]}[1]"; # array element $foo[0]
570              
571             The full horror story of backslashing interpolations can be found in
572             L<perlop/Gory details of parsing quoted constructs>.
573              
574             =head2 Octal Wide Chars
575              
576             Octal escapes C<\400> to C<\777> for wide chars 256 to 511 are new in Perl
577             5.6. They're considered unknown in 5.005 and earlier (where they end up
578             chopped to 8-bits 0 to 255). Currently if there's no C<use> etc Perl
579             version then it's presumed a high octal is intentional and is allowed.
580              
581             print "\400"; # ok
582              
583             use 5.006;
584             print "\777"; # ok
585              
586             use 5.005;
587             print "\777"; # bad in 5.005 and earlier
588              
589              
590             =head2 Named Chars
591              
592             Named chars C<\N{SOME THING}> are added by L<charnames>, new in Perl 5.6.
593             In Perl 5.16 up, that module is automatically loaded when C<\N> is used.
594             C<\N> is considered known when C<use 5.016> or higher,
595              
596             use 5.016;
597             print "\N{EQUALS SIGN}"; # ok with 5.16 automatic charnames
598              
599             or if C<use charnames> is in the lexical scope,
600              
601             { use charnames ':full';
602             print "\N{APOSTROPHE}"; # ok
603             }
604             print "\N{COLON}"; # bad, no charnames in lexical scope
605              
606             In Perl 5.6 through 5.14, a C<\N> without C<charnames> is a compile error so
607             would be seen in those versions immediately anyway. There's no check of the
608             character name appearing in the C<\N>. C<charnames> gives an error for
609             unknown names.
610              
611             The C<charnames> option (L</CONFIGURATION> below) can be allow to always
612             allow named characters. This can be used for instance if you always have
613             Perl 5.16 up but without declaring that in a C<use> statement.
614              
615             The C<charnames> option can be disallow to always disallow named characters.
616             This is a blanket prohibition rather than an UnknownBackslash as such, but
617             matches the allow option. Disallowing can be matter of personal preference
618             or perhaps aim to save a little memory or startup time.
619              
620             =head2 Other Notes
621              
622             In the violation messages, a non-ascii or non-graphical escaped char is
623             shown as hex like C<\{0x263A}>, to ensure the message is printable and
624             unambiguous.
625              
626             Interpolated C<$foo> or C<@{expr}> variables and expressions are parsed like
627             Perl does, so backslashes for refs within are ok, in particular tricks like
628             C<${\scalar ...}> are fine (see L<perlfaq4/How do I expand function calls in
629             a string?>).
630              
631             print "this ${\(some()+thing())}"; # ok
632              
633             =head2 Disabling
634              
635             As always, if you're not interested in any of this then you can disable
636             C<ProhibitUnknownBackslash> from your F<.perlcriticrc> in the usual way (see
637             L<Perl::Critic/CONFIGURATION>),
638              
639             [-ValuesAndExpressions::ProhibitUnknownBackslash]
640              
641             =head1 CONFIGURATION
642              
643             =over 4
644              
645             =item C<double> (string, default "all")
646              
647             =item C<heredoc> (string, default "all")
648              
649             C<double> applies to double-quote strings C<"">, C<qq{}>, C<qx{}>, etc.
650             C<heredoc> applies to interpolated here-documents C<E<lt>E<lt>HERE> etc.
651             The possible values are
652              
653             none don't report anything
654             alnum report unknown alphanumerics, like Perl's warning
655             quotemeta report anything quotemeta() doesn't escape
656             all report all unknowns
657              
658             "alnum" does no more than compiling with C<perl -w>, but might be good for
659             checking code you don't want to run.
660              
661             "quotemeta" reports escapes not produced by C<quotemeta()>. For example
662             C<quotemeta> escapes a C<*>, so C<\*> is not reported, but it doesn't escape
663             an underscore C<_>, so C<\_> is reported. The effect is to prohibit a few
664             more escapes than "alnum". One use is to check code generated by other code
665             where you've used C<quotemeta> to produce double-quoted strings and thus may
666             have escaping which is unnecessary but works fine.
667              
668             =item C<single> (string, default "none")
669              
670             C<single> applies to single-quote strings C<''>, C<q{}>, C<qx''>, etc. The
671             possible values are as above, though only "all" or "none" make much sense.
672              
673             none don't report anything
674             all report all unknowns
675              
676             The default is "none" because literal backslashes in single-quotes are
677             usually both what you want and quite convenient. Setting "all" effectively
678             means you must write backslashes as C<\\>.
679              
680             print 'c:\my\msdos\filename'; # bad under "single=all"
681             print 'c:\\my\\msdos\\filename'; # ok
682              
683             Doubled backslashing like this is correct, and can emphasize that you really
684             did want a backslash, but it's tedious and not easy on the eye and so left
685             only as an option.
686              
687             For reference, single-quote here-documents C<E<lt>E<lt>'HERE'> don't have
688             any backslash escapes and so are not considered by this policy. C<qx{}>
689             command backticks are double-quote but C<qx''> is single-quote. They are
690             treated per the corresponding C<single> or C<double> option.
691              
692             =item C<charnames> (string, default "version")
693              
694             Whether to treat named characters C<\N{}> in double-quote strings as known
695             or unknown,
696              
697             version known if use charnames or use 5.016
698             allow always allow
699             disallow always disallow
700              
701             =back
702              
703             =head1 BUGS
704              
705             Interpolations in double-quote strings are found by some code here in
706             C<ProhibitUnknownBackslash> (re-parse the string content as Perl code
707             starting from the C<$> or C<@>). If this fails for some reason then a
708             warning is given and the rest of the string is unchecked. In the future
709             would like PPI to parse interpolations, for the benefit of string chopping
710             like here or checking of code in an interpolation.
711              
712             =head1 SEE ALSO
713              
714             L<Perl::Critic::Pulp>,
715             L<Perl::Critic>
716              
717             L<perlop/Quote and Quote-like Operators>
718              
719             =head1 HOME PAGE
720              
721             http://user42.tuxfamily.org/perl-critic-pulp/index.html
722              
723             =head1 COPYRIGHT
724              
725             Copyright 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2019, 2021 Kevin Ryde
726              
727             Perl-Critic-Pulp is free software; you can redistribute it and/or modify it
728             under the terms of the GNU General Public License as published by the Free
729             Software Foundation; either version 3, or (at your option) any later
730             version.
731              
732             Perl-Critic-Pulp is distributed in the hope that it will be useful, but
733             WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
734             or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
735             more details.
736              
737             You should have received a copy of the GNU General Public License along with
738             Perl-Critic-Pulp. If not, see <http://www.gnu.org/licenses>.
739              
740             =cut