[libxslt] Improve handling of invalid UTF-8 in format-number



commit 4fcf6f564cf7ec300be5d47aa82bb168916a64b0
Author: Nick Wellnhofer <wellnhofer aevum de>
Date:   Sun Sep 15 13:12:36 2019 +0200

    Improve handling of invalid UTF-8 in format-number
    
    Output prefixes and suffixes codepoint by codepoint instead of byte by
    byte, like they were parsed before. Otherwise quote characters found in
    continuation bytes of invalid UTF-8 could mess up the character count
    which excludes quote characters.

 libxslt/numbers.c | 34 ++++++++++++++++------------------
 tests/fuzz/fuzz.c | 10 ----------
 2 files changed, 16 insertions(+), 28 deletions(-)
---
diff --git a/libxslt/numbers.c b/libxslt/numbers.c
index 20b99d5a..ad900e1f 100644
--- a/libxslt/numbers.c
+++ b/libxslt/numbers.c
@@ -859,7 +859,8 @@ XSLT_NUMBER_FORMAT_END:
 static int
 xsltFormatNumberPreSuffix(xsltDecimalFormatPtr self, xmlChar **format, xsltFormatNumberInfoPtr info)
 {
-    int        count=0;        /* will hold total length of prefix/suffix */
+    /* will hold total length of prefix/suffix without quote characters */
+    int        count=0;
     int len;
 
     while (1) {
@@ -957,7 +958,6 @@ xsltFormatNumberConversion(xsltDecimalFormatPtr self,
     xmlBufferPtr buffer;
     xmlChar *the_format, *prefix = NULL, *suffix = NULL;
     xmlChar *nprefix, *nsuffix = NULL;
-    xmlChar pchar;
     int            prefix_length, suffix_length = 0, nprefix_length, nsuffix_length;
     double  scale;
     int            j, len;
@@ -1282,14 +1282,13 @@ OUTPUT_NUMBER:
        xmlBufferAdd(buffer, self->minusSign, xmlUTF8Strsize(self->minusSign, 1));
 
     /* Put the prefix into the buffer */
-    for (j = 0; j < prefix_length; j++) {
-       if ((pchar = *prefix++) == SYMBOL_QUOTE) {
-           len = xmlUTF8Strsize(prefix, 1);
-           xmlBufferAdd(buffer, prefix, len);
-           prefix += len;
-           j += len - 1;       /* length of symbol less length of quote */
-       } else
-           xmlBufferAdd(buffer, &pchar, 1);
+    for (j = 0; j < prefix_length; ) {
+       if (*prefix == SYMBOL_QUOTE)
+            prefix++;
+        len = xmlUTF8Strsize(prefix, 1);
+        xmlBufferAdd(buffer, prefix, len);
+        prefix += len;
+        j += len;
     }
 
     /* Next do the integer part of the number */
@@ -1348,14 +1347,13 @@ OUTPUT_NUMBER:
        }
     }
     /* Put the suffix into the buffer */
-    for (j = 0; j < suffix_length; j++) {
-       if ((pchar = *suffix++) == SYMBOL_QUOTE) {
-            len = xmlUTF8Strsize(suffix, 1);
-           xmlBufferAdd(buffer, suffix, len);
-           suffix += len;
-           j += len - 1;       /* length of symbol less length of escape */
-       } else
-           xmlBufferAdd(buffer, &pchar, 1);
+    for (j = 0; j < suffix_length; ) {
+       if (*suffix == SYMBOL_QUOTE)
+            suffix++;
+        len = xmlUTF8Strsize(suffix, 1);
+        xmlBufferAdd(buffer, suffix, len);
+        suffix += len;
+        j += len;
     }
 
     *result = xmlStrdup(xmlBufferContent(buffer));
diff --git a/tests/fuzz/fuzz.c b/tests/fuzz/fuzz.c
index 01c653f4..d862242c 100644
--- a/tests/fuzz/fuzz.c
+++ b/tests/fuzz/fuzz.c
@@ -209,16 +209,6 @@ xsltFuzzXPath(const char *data, size_t size) {
     memcpy(xpathExpr, data, size);
     xpathExpr[size] = 0;
 
-    /*
-     * format-number() can still cause memory errors with invalid UTF-8 in
-     * prefixes or suffixes. This shouldn't be exploitable in practice, but
-     * should be fixed. Check UTF-8 validity for now.
-     */
-    if (xmlCheckUTF8(xpathExpr) == 0) {
-        free(xpathExpr);
-        return NULL;
-    }
-
     /* Compile and return early if the expression is invalid */
     xmlXPathCompExprPtr compExpr = xmlXPathCtxtCompile(xpctxt, xpathExpr);
     free(xpathExpr);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]