This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
lib/meta_notation: Fix so C1 controls are escaped
authorKarl Williamson <khw@cpan.org>
Tue, 15 Dec 2015 03:23:26 +0000 (20:23 -0700)
committerKarl Williamson <khw@cpan.org>
Tue, 15 Dec 2015 03:28:04 +0000 (20:28 -0700)
Prior to this commit the meta notation for C1 controls included raw C0
controls.

lib/meta_notation.pm
lib/meta_notation.t
pod/perldelta.pod

index a5e9cdd..eea8587 100644 (file)
@@ -22,10 +22,8 @@ sub _meta_notation ($) {
     # On ASCII platforms, the upper-Latin1-range characters are converted to
     # Meta notation, so that \xC1 becomes 'M-A', \xE2 becomes 'M-b', etc.
     # This is how it always has worked, so is continued that way for backwards
-    # compatibility.  XXX Wrong, but the way it has always worked is that \x80
-    # .. \x9F are converted to M- followed by a literal control char.  This
-    # probably has escaped attention due to the limited domains this code has
-    # been applied to.  ext/SDBM_File/dbu.c does this right.
+    # compatibility.  The range \x80 .. \x9F becomes M-^@ .. M-^A, M-^B, ...
+    # M-^Z, M-^[, M-^\, M-^], M-^, M-^_
     #
     # On EBCDIC platforms, the upper-Latin1-range characters are converted
     # into '\x{...}'  Meta notation doesn't make sense on EBCDIC platforms
@@ -40,7 +38,8 @@ sub _meta_notation ($) {
                sprintf("^%c",utf8::unicode_to_native(ord($1)^64))/xeg;
     $string =~ s/\c?/^?/g;
     if (ord("A") == 65) {
-        $string =~ s/([\200-\377])/sprintf("M-%c",ord($1)&0177)/eg;
+        $string =~ s/([\200-\237])/sprintf("M-^%c",(ord($1)&0177)^64)/eg;
+        $string =~ s/([\240-\377])/sprintf("M-%c"  ,ord($1)&0177)/eg;
     }
     else {
         no warnings 'experimental::regex_sets';
index d89d50c..b687dbd 100644 (file)
@@ -15,9 +15,17 @@ if ($@) {
 }
 else {
 
-    is(_meta_notation("\007\010\011\c?Z\x{103}"), "^G^H^I^?Z\x{103}");
+    is(_meta_notation("\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C"),
+                      "^@^A^B^C^D^E^F^G^H^I^J^K^L");
+    is(_meta_notation("\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19"),
+                      "^M^N^O^P^Q^R^S^T^U^V^W^X^Y");
+    is(_meta_notation("\x1A\x1B\x1C\x1D\x1E\x1F\c?"),
+                      "^Z^[^\\^]^^^_^?");
+    is(_meta_notation("09%AZaz\x{103}"), "09%AZaz\x{103}");
 
     if ($::IS_ASCII || $::IS_ASCII) {
+        is(_meta_notation("\x7f\x80\x81\x82\x9A\x9B\x9C\x9D\x9E\x9F\xA0\xA1"),
+                        '^?M-^@M-^AM-^BM-^ZM-^[M-^\\M-^]M-^^M-^_M- M-!');
         is(_meta_notation("\x{c1}\x{e2}"), 'M-AM-b');
         is(_meta_notation("\x{df}"), 'M-_');
     }
index dedeca9..b8deeb3 100644 (file)
@@ -152,6 +152,12 @@ Partly reverted a micro-optimization to F<lib/utf_heavy.pl> that
 caused self-recursion when it was loaded with C<${^ENCODING}> set.
 [perl #126593]
 
+=item *
+
+The modules L<sigtrap>, L<DB>, and the perl debugger could have under
+rare circumstances, without you expecting it, output containing raw
+control characters.  This has been fixed.
+
 =back
 
 =head2 Removed Modules and Pragmata