File Coverage

blib/lib/Perl/Critic/Policy/ValuesAndExpressions/ProhibitUnknownBackslash.pm
Criterion Covered Total %
statement 146 151 96.6
branch 78 92 84.7
condition 46 56 82.1
subroutine 18 19 94.7
pod 2 2 100.0
total 290 320 90.6


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