utf16_to_utf8_reversed() should croak early when passed an odd byte length.
Nicholas Clark [Sun, 18 Oct 2009 20:30:41 +0000 (21:30 +0100)]
Rather than transposing n + 1 bytes, including 1 it was not passed, before
calling utf16_to_utf8() and having that croak.
e 69422~

ext/XS-APItest/t/utf16_to_utf8.t
pod/perldiag.pod
utf8.c

index 3da3d7d..83add20 100644 (file)
@@ -47,3 +47,10 @@ for (["\xD8\0\0\0", 'NULs'],
         "Malformed surrogate $name croaks for utf16_to_utf8_reversed");
     is($got, undef, 'hence eval returns undef');
 }
+
+my $in = "NA";
+$got = eval {utf16_to_utf8_reversed($in, 1)};
+like($@, qr/^panic: utf16_to_utf8_reversed: odd bytelen 1 at/,
+     'Odd byte length panics');
+is($got, undef, 'hence eval returns undef');
+is($in, "NA", 'and input unchanged');
index 255eb53..f1f081d 100644 (file)
@@ -3220,6 +3220,11 @@ at run time.
 (P) Something tried to call utf16_to_utf8 with an odd (as opposed
 to even) byte length.
 
+=item panic: utf16_to_utf8_reversed: odd bytelen
+
+(P) Something tried to call utf16_to_utf8_reversed with an odd (as opposed
+to even) byte length.
+
 =item panic: yylex
 
 (P) The lexer got into a bad state while processing a case modifier.
diff --git a/utf8.c b/utf8.c
index 7b7fd57..455078d 100644 (file)
--- a/utf8.c
+++ b/utf8.c
@@ -1020,6 +1020,10 @@ Perl_utf16_to_utf8_reversed(pTHX_ U8* p, U8* d, I32 bytelen, I32 *newlen)
 
     PERL_ARGS_ASSERT_UTF16_TO_UTF8_REVERSED;
 
+    if (bytelen & 1)
+       Perl_croak(aTHX_ "panic: utf16_to_utf8_reversed: odd bytelen %"UVuf,
+                  (UV)bytelen);
+
     while (s < send) {
        const U8 tmp = s[0];
        s[0] = s[1];