Deparse funny keys/values in hh properly
authorFather Chrysostomos <sprout@cpan.org>
Wed, 7 Dec 2011 07:07:49 +0000 (23:07 -0800)
committerFather Chrysostomos <sprout@cpan.org>
Wed, 7 Dec 2011 14:15:36 +0000 (06:15 -0800)
Simply putting '...' or q(...) around a string is not sufficient to
quote it properly, allowing this sort of ‘fun’:

$ perl -l -MO=Deparse -e'BEGIN{$^H{"'\''.'\''"} = "um);\n    exit("}print'
BEGIN { $/ = "\n"; $\ = "\n"; }
sub BEGIN {
    $^H{q['.']} = "um);\n    exit(";
}
BEGIN {
    $^H{''.''} = q(um);
    exit();
}
print $_;
-e syntax OK

And B::Deparse already has a facility for quoting strings, so why
not use it?

dist/B-Deparse/Deparse.pm
dist/B-Deparse/t/deparse.t

index 24d17af..c7bdec4 100644 (file)
@@ -1511,8 +1511,13 @@ sub declare_hinthash {
     for my $key (keys %$to) {
        next if $ignored_hints{$key};
        if (!exists $from->{$key} or $from->{$key} ne $to->{$key}) {
-           push @decls, qq(\$^H{'$key'} = )
-             . (defined $to->{$key} ? qq(q($to->{$key})) : 'undef')
+           push @decls,
+               qq(\$^H{) . single_delim("q", "'", $key) . qq(} = )
+             . (
+                  defined $to->{$key}
+                       ? single_delim("q", "'", $to->{$key})
+                       : 'undef'
+               )
              . qq(;);
        }
     }
index 7b11ccf..d47498c 100644 (file)
@@ -807,3 +807,5 @@ BEGIN { $^H{'foo'} = undef; }
  }
  print $_;
 }
+BEGIN { $^H{q[']} = '('; }
+print $_;