utf8n_to_uvuni: Avoid reading outside of buffer
authorKarl Williamson <public@khwilliamson.com>
Wed, 18 Apr 2012 22:48:29 +0000 (16:48 -0600)
committerKarl Williamson <public@khwilliamson.com>
Thu, 26 Apr 2012 17:58:57 +0000 (11:58 -0600)
Prior to this patch, if the first byte of a UTF-8 sequence indicated
that the sequence occupied n bytes, but the input parameters indicated
that fewer were available, all n were attempted to be read

utf8.c

diff --git a/utf8.c b/utf8.c
index 7ddd9c7..52563c4 100644 (file)
--- a/utf8.c
+++ b/utf8.c
@@ -573,6 +573,7 @@ Perl_utf8n_to_uvuni(pTHX_ const U8 *s, STRLEN curlen, STRLEN *retlen, U32 flags)
 {
     dVAR;
     const U8 * const s0 = s;
+    U8 * send;
     UV uv = *s, ouv = 0;
     STRLEN len = 1;
     bool dowarn = ckWARN_d(WARN_UTF8);
@@ -644,11 +645,11 @@ Perl_utf8n_to_uvuni(pTHX_ const U8 *s, STRLEN curlen, STRLEN *retlen, U32 flags)
        goto malformed;
     }
 
-    len--;
-    s++;
+    send =  (U8*) s0 + ((expectlen <= curlen) ? expectlen : curlen);
+
     ouv = uv;  /* ouv is the value from the previous iteration */
 
-    while (len--) {
+    for (++s; s < send; s++) {
        if (!UTF8_IS_CONTINUATION(*s) &&
            !(flags & UTF8_ALLOW_NON_CONTINUATION)) {
            s--;
@@ -672,7 +673,6 @@ Perl_utf8n_to_uvuni(pTHX_ const U8 *s, STRLEN curlen, STRLEN *retlen, U32 flags)
                goto malformed;
            }
        }
-       s++;
        ouv = uv;
     }