This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
utf8.c: Make safer a deprecated function
authorKarl Williamson <khw@cpan.org>
Tue, 24 Jul 2018 23:20:08 +0000 (17:20 -0600)
committerKarl Williamson <khw@cpan.org>
Fri, 3 Aug 2018 18:55:11 +0000 (12:55 -0600)
This function is only called from deprecated functions, but they may be
moved to ppport.h.  It is lacking a length parameter, so malformed UTF-8
may cause it to read beyond the buffer.  This commit causes it to not
read beyond a NUL character, which makes it safe for the common case
that the input is a C string.

utf8.c

diff --git a/utf8.c b/utf8.c
index 8471fb8..3062f58 100644 (file)
--- a/utf8.c
+++ b/utf8.c
@@ -3100,7 +3100,9 @@ S_is_utf8_common(pTHX_ const U8 *const p, SV **swash,
      * Note that it is assumed that the buffer length of <p> is enough to
      * contain all the bytes that comprise the character.  Thus, <*p> should
      * have been checked before this call for mal-formedness enough to assure
-     * that. */
+     * that.  This function, does make sure to not look past any NUL, so it is
+     * safe to use on C, NUL-terminated, strings */
+    STRLEN len = my_strnlen((char *) p, UTF8SKIP(p));
 
     PERL_ARGS_ASSERT_IS_UTF8_COMMON;
 
@@ -3109,9 +3111,8 @@ S_is_utf8_common(pTHX_ const U8 *const p, SV **swash,
      * as far as there being enough bytes available in it to accommodate the
      * character without reading beyond the end, and pass that number on to the
      * validating routine */
-    if (! isUTF8_CHAR(p, p + UTF8SKIP(p))) {
-        _force_out_malformed_utf8_message(p, p + UTF8SKIP(p),
-                                          _UTF8_NO_CONFIDENCE_IN_CURLEN,
+    if (! isUTF8_CHAR(p, p + len)) {
+        _force_out_malformed_utf8_message(p, p + len, _UTF8_NO_CONFIDENCE_IN_CURLEN,
                                           1 /* Die */ );
         NOT_REACHED; /* NOTREACHED */
     }