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

[Libevent-users] patch for evhttp_htmlescape() in http.c



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 majordomo@xxxxxxxxxxxxx with
unsubscribe libevent-users    in the body.