📜 ⬆️ ⬇️

Interesting Perl Developer Error

Imagine that you have the code:
chomp(my $input = <STDIN>); my $kinda_secret = get_data($input); if (defined $kinda_secret) { print 'Your secret is: ' , $kinda_secret } else { print 'No soup for you' } sub get_data { my $input = shift; open my $fh, '<' , 'data.file' or return ; my $retval; while (<$fh>) { if (/^$input:(.+?)$/) { $retval = $1; last } } close $fh; $retval } * This source code was highlighted with Source Code Highlighter .
  1. chomp(my $input = <STDIN>); my $kinda_secret = get_data($input); if (defined $kinda_secret) { print 'Your secret is: ' , $kinda_secret } else { print 'No soup for you' } sub get_data { my $input = shift; open my $fh, '<' , 'data.file' or return ; my $retval; while (<$fh>) { if (/^$input:(.+?)$/) { $retval = $1; last } } close $fh; $retval } * This source code was highlighted with Source Code Highlighter .
  2. chomp(my $input = <STDIN>); my $kinda_secret = get_data($input); if (defined $kinda_secret) { print 'Your secret is: ' , $kinda_secret } else { print 'No soup for you' } sub get_data { my $input = shift; open my $fh, '<' , 'data.file' or return ; my $retval; while (<$fh>) { if (/^$input:(.+?)$/) { $retval = $1; last } } close $fh; $retval } * This source code was highlighted with Source Code Highlighter .
  3. chomp(my $input = <STDIN>); my $kinda_secret = get_data($input); if (defined $kinda_secret) { print 'Your secret is: ' , $kinda_secret } else { print 'No soup for you' } sub get_data { my $input = shift; open my $fh, '<' , 'data.file' or return ; my $retval; while (<$fh>) { if (/^$input:(.+?)$/) { $retval = $1; last } } close $fh; $retval } * This source code was highlighted with Source Code Highlighter .
  4. chomp(my $input = <STDIN>); my $kinda_secret = get_data($input); if (defined $kinda_secret) { print 'Your secret is: ' , $kinda_secret } else { print 'No soup for you' } sub get_data { my $input = shift; open my $fh, '<' , 'data.file' or return ; my $retval; while (<$fh>) { if (/^$input:(.+?)$/) { $retval = $1; last } } close $fh; $retval } * This source code was highlighted with Source Code Highlighter .
  5. chomp(my $input = <STDIN>); my $kinda_secret = get_data($input); if (defined $kinda_secret) { print 'Your secret is: ' , $kinda_secret } else { print 'No soup for you' } sub get_data { my $input = shift; open my $fh, '<' , 'data.file' or return ; my $retval; while (<$fh>) { if (/^$input:(.+?)$/) { $retval = $1; last } } close $fh; $retval } * This source code was highlighted with Source Code Highlighter .
  6. chomp(my $input = <STDIN>); my $kinda_secret = get_data($input); if (defined $kinda_secret) { print 'Your secret is: ' , $kinda_secret } else { print 'No soup for you' } sub get_data { my $input = shift; open my $fh, '<' , 'data.file' or return ; my $retval; while (<$fh>) { if (/^$input:(.+?)$/) { $retval = $1; last } } close $fh; $retval } * This source code was highlighted with Source Code Highlighter .
  7. chomp(my $input = <STDIN>); my $kinda_secret = get_data($input); if (defined $kinda_secret) { print 'Your secret is: ' , $kinda_secret } else { print 'No soup for you' } sub get_data { my $input = shift; open my $fh, '<' , 'data.file' or return ; my $retval; while (<$fh>) { if (/^$input:(.+?)$/) { $retval = $1; last } } close $fh; $retval } * This source code was highlighted with Source Code Highlighter .
  8. chomp(my $input = <STDIN>); my $kinda_secret = get_data($input); if (defined $kinda_secret) { print 'Your secret is: ' , $kinda_secret } else { print 'No soup for you' } sub get_data { my $input = shift; open my $fh, '<' , 'data.file' or return ; my $retval; while (<$fh>) { if (/^$input:(.+?)$/) { $retval = $1; last } } close $fh; $retval } * This source code was highlighted with Source Code Highlighter .
  9. chomp(my $input = <STDIN>); my $kinda_secret = get_data($input); if (defined $kinda_secret) { print 'Your secret is: ' , $kinda_secret } else { print 'No soup for you' } sub get_data { my $input = shift; open my $fh, '<' , 'data.file' or return ; my $retval; while (<$fh>) { if (/^$input:(.+?)$/) { $retval = $1; last } } close $fh; $retval } * This source code was highlighted with Source Code Highlighter .
  10. chomp(my $input = <STDIN>); my $kinda_secret = get_data($input); if (defined $kinda_secret) { print 'Your secret is: ' , $kinda_secret } else { print 'No soup for you' } sub get_data { my $input = shift; open my $fh, '<' , 'data.file' or return ; my $retval; while (<$fh>) { if (/^$input:(.+?)$/) { $retval = $1; last } } close $fh; $retval } * This source code was highlighted with Source Code Highlighter .
  11. chomp(my $input = <STDIN>); my $kinda_secret = get_data($input); if (defined $kinda_secret) { print 'Your secret is: ' , $kinda_secret } else { print 'No soup for you' } sub get_data { my $input = shift; open my $fh, '<' , 'data.file' or return ; my $retval; while (<$fh>) { if (/^$input:(.+?)$/) { $retval = $1; last } } close $fh; $retval } * This source code was highlighted with Source Code Highlighter .
  12. chomp(my $input = <STDIN>); my $kinda_secret = get_data($input); if (defined $kinda_secret) { print 'Your secret is: ' , $kinda_secret } else { print 'No soup for you' } sub get_data { my $input = shift; open my $fh, '<' , 'data.file' or return ; my $retval; while (<$fh>) { if (/^$input:(.+?)$/) { $retval = $1; last } } close $fh; $retval } * This source code was highlighted with Source Code Highlighter .
  13. chomp(my $input = <STDIN>); my $kinda_secret = get_data($input); if (defined $kinda_secret) { print 'Your secret is: ' , $kinda_secret } else { print 'No soup for you' } sub get_data { my $input = shift; open my $fh, '<' , 'data.file' or return ; my $retval; while (<$fh>) { if (/^$input:(.+?)$/) { $retval = $1; last } } close $fh; $retval } * This source code was highlighted with Source Code Highlighter .
  14. chomp(my $input = <STDIN>); my $kinda_secret = get_data($input); if (defined $kinda_secret) { print 'Your secret is: ' , $kinda_secret } else { print 'No soup for you' } sub get_data { my $input = shift; open my $fh, '<' , 'data.file' or return ; my $retval; while (<$fh>) { if (/^$input:(.+?)$/) { $retval = $1; last } } close $fh; $retval } * This source code was highlighted with Source Code Highlighter .
  15. chomp(my $input = <STDIN>); my $kinda_secret = get_data($input); if (defined $kinda_secret) { print 'Your secret is: ' , $kinda_secret } else { print 'No soup for you' } sub get_data { my $input = shift; open my $fh, '<' , 'data.file' or return ; my $retval; while (<$fh>) { if (/^$input:(.+?)$/) { $retval = $1; last } } close $fh; $retval } * This source code was highlighted with Source Code Highlighter .
  16. chomp(my $input = <STDIN>); my $kinda_secret = get_data($input); if (defined $kinda_secret) { print 'Your secret is: ' , $kinda_secret } else { print 'No soup for you' } sub get_data { my $input = shift; open my $fh, '<' , 'data.file' or return ; my $retval; while (<$fh>) { if (/^$input:(.+?)$/) { $retval = $1; last } } close $fh; $retval } * This source code was highlighted with Source Code Highlighter .
  17. chomp(my $input = <STDIN>); my $kinda_secret = get_data($input); if (defined $kinda_secret) { print 'Your secret is: ' , $kinda_secret } else { print 'No soup for you' } sub get_data { my $input = shift; open my $fh, '<' , 'data.file' or return ; my $retval; while (<$fh>) { if (/^$input:(.+?)$/) { $retval = $1; last } } close $fh; $retval } * This source code was highlighted with Source Code Highlighter .
  18. chomp(my $input = <STDIN>); my $kinda_secret = get_data($input); if (defined $kinda_secret) { print 'Your secret is: ' , $kinda_secret } else { print 'No soup for you' } sub get_data { my $input = shift; open my $fh, '<' , 'data.file' or return ; my $retval; while (<$fh>) { if (/^$input:(.+?)$/) { $retval = $1; last } } close $fh; $retval } * This source code was highlighted with Source Code Highlighter .
  19. chomp(my $input = <STDIN>); my $kinda_secret = get_data($input); if (defined $kinda_secret) { print 'Your secret is: ' , $kinda_secret } else { print 'No soup for you' } sub get_data { my $input = shift; open my $fh, '<' , 'data.file' or return ; my $retval; while (<$fh>) { if (/^$input:(.+?)$/) { $retval = $1; last } } close $fh; $retval } * This source code was highlighted with Source Code Highlighter .
  20. chomp(my $input = <STDIN>); my $kinda_secret = get_data($input); if (defined $kinda_secret) { print 'Your secret is: ' , $kinda_secret } else { print 'No soup for you' } sub get_data { my $input = shift; open my $fh, '<' , 'data.file' or return ; my $retval; while (<$fh>) { if (/^$input:(.+?)$/) { $retval = $1; last } } close $fh; $retval } * This source code was highlighted with Source Code Highlighter .
  21. chomp(my $input = <STDIN>); my $kinda_secret = get_data($input); if (defined $kinda_secret) { print 'Your secret is: ' , $kinda_secret } else { print 'No soup for you' } sub get_data { my $input = shift; open my $fh, '<' , 'data.file' or return ; my $retval; while (<$fh>) { if (/^$input:(.+?)$/) { $retval = $1; last } } close $fh; $retval } * This source code was highlighted with Source Code Highlighter .
chomp(my $input = <STDIN>); my $kinda_secret = get_data($input); if (defined $kinda_secret) { print 'Your secret is: ' , $kinda_secret } else { print 'No soup for you' } sub get_data { my $input = shift; open my $fh, '<' , 'data.file' or return ; my $retval; while (<$fh>) { if (/^$input:(.+?)$/) { $retval = $1; last } } close $fh; $retval } * This source code was highlighted with Source Code Highlighter .

Nothing exotic. Variations of such a code can occur anywhere. The meaning of the code, I hope, is clear (I do not mean its practical value).

Have you already seen the error? If so, then you can not read further.

And I confess, I did not immediately understand what was happening (Here is a vivid example:

 ksurent @ desktop: ~> cat data.file 
 password1: hello1
 password2: hello2
 ksurent @ desktop: ~> perl -l t.pl
 password1
 Your secret is: hello1
 ksurent @ desktop: ~> perl -l t.pl
 password
 No soup for you
 ksurent @ desktop: ~> perl -l t.pl
 . +
 Your secret is: hello1
 ksurent @ desktop: ~> 

')
Of course, you have already paid attention to the last attempt. And understand what happened - the introduction of a regular expression leading to the disclosure of data. The error is as rare as it is interesting.
The fact is that variables inside regular expressions are interpreted by default. Because of this, you can embed an expression that will always match.

There is of course a safe way out: the \ Q and \ E metacharacters. \ Q disables the interpretation of meta-characters up to \ E (or until the end of the regular expression, if \ E is omitted).
Make it a rule to frame variables with unverified data in \ Q \ E when substituting into regulars.

Small addition


Practical value does not carry due to very exotic conditions for implementation. Just wondering.
Imagine that for some reason the script has the line
  use re 'eval'; 
. Well, you never know, for example, complex dynamic regulars are used somewhere. This will lead to the introduction of the code:
 ksurent @ desktop: ~> perl -l t.pl
 (?? {system'id '})
 uid = 1000 (ksurent) gid = 100 (users) groups = 16 (dialout), 33 (video), 100 (users)
 uid = 1000 (ksurent) gid = 100 (users) groups = 16 (dialout), 33 (video), 100 (users)
 No soup for you
 ksurent @ desktop: ~>

That's it. The benefit of the interpreter developers foresaw this: by default, such things do not roll. But! Even
  use re 'eval'; 
in the script there is no, you can get a small piece of code that also does not play into the hands of the developer.

 ksurent @ desktop: ~> perl -l t.pl
 (?? {system'id '})
 Eval-group not allowed at runtime, use re 'eval' in regex m / ^ (?? {system'id '}): (. +?) $ / At t.pl line 15, <$ fh> line 1.
 ksurent @ desktop: ~>

Source: https://habr.com/ru/post/67143/


All Articles