This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Return REPLACEMENT for UTF-8 empty malformation
authorKarl Williamson <khw@cpan.org>
Wed, 14 Dec 2016 18:38:42 +0000 (11:38 -0700)
committerKarl Williamson <khw@cpan.org>
Fri, 23 Dec 2016 23:48:35 +0000 (16:48 -0700)
The previous commit no longer allows this so-called malformation under
DEBUGGING builds, except if code explicitly changes to request it (or
already explicitly does, but there are no instances of this in CPAN).

If it is explicitly allowed, prior to this commit it returned NUL.  If
it wasn't allowed, it returned 0.  Most code won't treat these as
different.  When returning NUL, it basically is making nothing into
something, which might be exploitable some way by an attacker.  The
Unicode accepted way of dealing with malformations is to replace them
with the REPLACEMENT CHARACTER, and so this commit changes things to
conform to this.

ext/XS-APItest/t/utf8.t
pod/perldelta.pod
utf8.c

index 7d640b1..e8ed76e 100644 (file)
@@ -1202,7 +1202,7 @@ my @malformations = (
 
 # Now considered a program bug, and asserted against
     #[ "zero length string malformation", "", 0,
-    #    $UTF8_ALLOW_EMPTY, $UTF8_GOT_EMPTY, 0, 0, 0,
+    #    $UTF8_ALLOW_EMPTY, $UTF8_GOT_EMPTY, $REPLACEMENT, 0, 0,
     #    qr/empty string/
     #],
     [ "orphan continuation byte malformation", I8_to_native("${I8c}a"), 2,
index b5f5645..fde4186 100644 (file)
@@ -342,9 +342,9 @@ deprecation warning since Perl v5.18.  They now die.
 =item *
 
 Calling the functions C<utf8n_to_uvchr> and its derivatives, while
-passing a string length of 0, and specifying that this is allowed is now
-asserted against in DEBUGGING builds.  If you have nothing to decode,
-you shouldn't call the decode function.
+passing a string length of 0 is now asserted against in DEBUGGING
+builds, and otherwise returns the Unicode REPLACEMENT CHARACTER.   If
+you have nothing to decode, you shouldn't call the decode function.
 
 =back
 
diff --git a/utf8.c b/utf8.c
index 2312648..d34597b 100644 (file)
--- a/utf8.c
+++ b/utf8.c
@@ -875,10 +875,9 @@ is, when there is a shorter sequence that can express the same code point;
 overlong sequences are expressly forbidden in the UTF-8 standard due to
 potential security issues).  Another malformation example is the first byte of
 a character not being a legal first byte.  See F<utf8.h> for the list of such
-flags.  For allowed 0 length strings, this function returns 0; for allowed
-overlong sequences, the computed code point is returned; for all other allowed
-malformations, the Unicode REPLACEMENT CHARACTER is returned, as these have no
-determinable reasonable value.
+flags.  For allowed overlong sequences, the computed code point is returned;
+for all other allowed malformations, the Unicode REPLACEMENT CHARACTER is
+returned.
 
 The C<UTF8_CHECK_ONLY> flag overrides the behavior when a non-allowed (by other
 flags) malformation is found.  If this flag is set, the routine assumes that
@@ -1123,8 +1122,7 @@ Perl_utf8n_to_uvchr_error(pTHX_ const U8 *s,
     if (UNLIKELY(curlen == 0)) {
         possible_problems |= UTF8_GOT_EMPTY;
         curlen = 0;
-        uv = 0; /* XXX It could be argued that this should be
-                   UNICODE_REPLACEMENT? */
+        uv = UNICODE_REPLACEMENT;
        goto ready_to_handle_errors;
     }