utf8.h: Use correct UTF-8 downgradeable definition
authorChristian Hansen <chansen@cpan.org>
Wed, 18 Apr 2012 20:32:16 +0000 (14:32 -0600)
committerKarl Williamson <public@khwilliamson.com>
Thu, 26 Apr 2012 17:58:56 +0000 (11:58 -0600)
Previously, the macro changed by this commit would accept overlong
sequences.

This patch was changed by the committer to to include EBCDIC changes;
and in the non-EBCDIC case, to save a test, by using a mask instead, in
keeping with the prior version of the code

AUTHORS
t/op/print.t
utf8.h
utfebcdic.h

diff --git a/AUTHORS b/AUTHORS
index 0369b91..88342aa 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -207,6 +207,7 @@ Chris Tubutis                       <chris@broadband.att.com>
 Chris Wick                     <cwick@lmc.com>
 Chris Williams                 <chrisw@netinfo.com.au>
 Christian Burger               <burger@terra.mpikg-teltow.mpg.de>
+Christian Hansen               <chansen@cpan.org>
 Christian Kirsch               <ck@held.mind.de>
 Christian Winter               <bitpoet@linux-config.de>
 Christoph Lamprecht            <ch.l.ngre@online.de>
index 3752251..5e508f6 100644 (file)
@@ -4,9 +4,25 @@ BEGIN {
     require "test.pl";
 }
 
-plan(2);
+plan(3);
 
 fresh_perl_is('$_ = qq{OK\n}; print;', "OK\n",
               'print without arguments outputs $_');
 fresh_perl_is('$_ = qq{OK\n}; print STDOUT;', "OK\n",
               'print with only a filehandle outputs $_');
+SKIP: {
+    skip_if_miniperl('no dynamic loading of PerlIO::scalar in miniperl');
+fresh_perl_is(<<'EOF', "\xC1\xAF\xC1\xAF\xC1\xB0\xC1\xB3", "", "print doesn't launder utf8 overlongs");
+use strict;
+use warnings;
+
+no warnings 'utf8';
+
+# These form overlong "oops"
+open my $fh, "<:utf8", \"\xC1\xAF\xC1\xAF\xC1\xB0\xC1\xB3"
+    or die "Could not open\n";
+read($fh, my $s, 10) or die "Could not read\n";
+print $s;
+EOF
+
+}
diff --git a/utf8.h b/utf8.h
index e558bb6..152a937 100644 (file)
--- a/utf8.h
+++ b/utf8.h
@@ -144,7 +144,9 @@ Perl's extended UTF-8 means we can have start bytes up to FF.
 #define UTF8_IS_START(c)               (((U8)c) >= 0xc0)
 #define UTF8_IS_CONTINUATION(c)                (((U8)c) >= 0x80 && (((U8)c) <= 0xbf))
 #define UTF8_IS_CONTINUED(c)           (((U8)c) &  0x80)
-#define UTF8_IS_DOWNGRADEABLE_START(c) (((U8)c & 0xfc) == 0xc0)
+
+/* Masking with 0xfe allows low bit to be 0 or 1; thus this matches 0xc[23] */
+#define UTF8_IS_DOWNGRADEABLE_START(c) (((U8)c & 0xfe) == 0xc2)
 
 #define UTF_START_MARK(len) (((len) >  7) ? 0xFF : (0xFE << (7-(len))))
 #define UTF_START_MASK(len) (((len) >= 7) ? 0x00 : (0x1F >> ((len)-2)))
index aa3304b..b3b767d 100644 (file)
@@ -587,7 +587,7 @@ END_EXTERN_C
 #define UTF8_IS_START(c)               (NATIVE_TO_UTF(c) >= 0xA0 && (NATIVE_TO_UTF(c) & 0xE0) != 0xA0)
 #define UTF8_IS_CONTINUATION(c)                ((NATIVE_TO_UTF(c) & 0xE0) == 0xA0)
 #define UTF8_IS_CONTINUED(c)           (NATIVE_TO_UTF(c) >= 0xA0)
-#define UTF8_IS_DOWNGRADEABLE_START(c) (NATIVE_TO_UTF(c) >= 0xA0 && (NATIVE_TO_UTF(c) & 0xF8) == 0xC0)
+#define UTF8_IS_DOWNGRADEABLE_START(c) (NATIVE_TO_UTF(c) >= 0xC5 && NATIVE_TO_UTF(c) <= 0xC7)
 
 #define UTF_START_MARK(len) (((len) >  7) ? 0xFF : ((U8)(0xFE << (7-(len)))))
 #define UTF_START_MASK(len) (((len) >= 6) ? 0x01 : (0x1F >> ((len)-2)))