A couple changes in the file `http.c'.

Removed the `scratch_space' variable from the `evhttp_htmlescape'
function since it wasn't actually used; also removed the `buf'
variable from the `evhttp_htmlescape' function since it was only used
by `scratch_space'.

Modified the `html_replace' function so that it returns the length of
the replacement string instead of the string itself. This is used to
easily check for overflows of the `new_size' variable in the first for
loop of the `evhttp_htmlescape' function, and thus potential out of
bounds writes in the second for loop (if an overflow occurs in
new_size, then new_size < old_size). Also check that new_size + 1
doesn't overflow in mm_malloc(new_size + 1).

---
--- http.c.orig 2011-05-23 16:22:16.848374553 -0400
+++ http.c      2011-05-23 17:36:23.000000000 -0400
@@ -219,29 +219,35 @@ strsep(char **s, const char *del)
 }
 #endif

-static const char *
-html_replace(char ch, char *buf)
+static size_t
+html_replace(const char ch, const char **escaped)
 {
        switch (ch) {
        case '<':
-               return "&lt;";
+               if (escaped != NULL)
+                       *escaped = "&lt;";
+               return 4;
        case '>':
-               return "&gt;";
+               if (escaped != NULL)
+                       *escaped = "&gt;";
+               return 4;
        case '"':
-               return "&quot;";
+               if (escaped != NULL)
+                       *escaped = "&quot;";
+               return 6;
        case '\'':
-               return "&#039;";
+               if (escaped != NULL)
+                       *escaped = "&#039;";
+               return 6;
        case '&':
-               return "&amp;";
+               if (escaped != NULL)
+                       *escaped = "&amp;";
+               return 5;
        default:
                break;
        }

-       /* Echo the character back */
-       buf[0] = ch;
-       buf[1] = '\0';
-
-       return buf;
+       return 1;
 }

 /*
@@ -255,21 +261,33 @@ char *
 evhttp_htmlescape(const char *html)
 {
        size_t i;
-       size_t new_size = 0, old_size = strlen(html);
+       size_t new_size = 0, old_size = 0;
        char *escaped_html, *p;
-       char scratch_space[2];

-       for (i = 0; i < old_size; ++i)
-               new_size += strlen(html_replace(html[i], scratch_space));
+       if (html == NULL)
+               return (NULL);
+
+       old_size = strlen(html);
+       for (i = 0; i < old_size; ++i) {
+               const size_t replace_size = html_replace(html[i], NULL);
+               if (replace_size > EV_SIZE_MAX - new_size) {
+                       event_warn("%s: html_replace overflow", __func__);
+                       return (NULL);
+               }
+               new_size += replace_size;
+       }

+       if (new_size == EV_SIZE_MAX)
+               return (NULL);
        p = escaped_html = mm_malloc(new_size + 1);
        if (escaped_html == NULL) {
-               event_warn("%s: malloc(%ld)", __func__, (long)(new_size + 1));
+               event_warn("%s: malloc(%lu)", __func__,
+                          (unsigned long)(new_size + 1));
                return (NULL);
        }
        for (i = 0; i < old_size; ++i) {
-               const char *replaced = html_replace(html[i], scratch_space);
-               size_t len = strlen(replaced);
+               const char *replaced = &html[i];
+               const size_t len = html_replace(html[i], &replaced);
                memcpy(p, replaced, len);
                p += len;
        }
***********************************************************************
To unsubscribe, send an e-mail to majord...@freehaven.net with
unsubscribe libevent-users    in the body.

Reply via email to