NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

bin/51004: apropos html mode doesn't handle especial characters in the short description



>Number:         51004
>Category:       bin
>Synopsis:       apropos html mode doesn't handle especial characters in the short description
>Confidential:   no
>Severity:       serious
>Priority:       low
>Responsible:    bin-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Thu Mar 24 13:30:00 +0000 2016
>Originator:     Abhinav Upadhyay
>Release:        CURRENT
>Organization:
>Environment:
NetBSD abhinavu 7.99.20 NetBSD 7.99.20 (GENERIC.201507122140Z) #0: Sun Jul 12 22:30:59 UTC 2015  builds%b45.netbsd.org@localhost:/home/builds/ab/HEAD/amd64/201507122140Z-obj/home/source/ab/HEAD/src/sys/arch/amd64/compile/GENERIC amd64

>Description:
The HTML mode of apropos(1) does not handle especial characters in the short description in the NAME section. It should convert a " to &quot;, < to &lt;, and so on.
>How-To-Repeat:
Don't have any test man page to demonstrate this.
>Fix:
Index: apropos-utils.c
===================================================================
RCS file: /cvsroot/src/usr.sbin/makemandb/apropos-utils.c,v
retrieving revision 1.20
diff -u -r1.20 apropos-utils.c
--- apropos-utils.c	20 Mar 2016 17:31:09 -0000	1.20
+++ apropos-utils.c	24 Mar 2016 13:22:40 -0000
@@ -625,6 +625,79 @@
 	return *(args->errmsg) == NULL ? 0 : -1;
 }
 
+static char *
+get_escaped_html_string(const char *string, size_t *string_length)
+{
+    /* First scan the string to find out the number of occurrences of {'>', '<'
+     * '"', '&'}.
+     * Then allocate a new buffer with sufficient space to be able to store the
+     * quoted versions of the special characters {&gt;, &lt;, &quot;, &amp;}.
+     * Copy over the characters from the original string into this buffer while
+     * replacing the special characters with their quoted versions.
+     */
+
+    int i = 0;
+    size_t sz;
+    int count = 0;
+    const char *temp = string;
+    while (*temp) {
+        sz = strcspn(temp, "<>\"&\002\003");
+        temp += sz + 1;
+        count++;
+    }
+    size_t new_string_length = *string_length + count * 5 + 1;
+    *string_length = new_string_length;
+    char *new_string = emalloc(new_string_length);
+    sz = 0;
+    while (*string) {
+        sz = strcspn(string, "<>\"&\002\003");
+        if (sz) {
+            memcpy(&new_string[i], string, sz);
+            string += sz;
+            i += sz;
+        }
+
+        switch (*string++) {
+            case '<':
+                memcpy(&new_string[i], "&lt;", 4);
+                i += 4;
+                break;
+            case '>':
+                memcpy(&new_string[i], "&gt;", 4);
+                i += 4;
+                break;
+            case '\"':
+                memcpy(&new_string[i], "&quot;", 6);
+                i += 6;
+                break;
+            case '&':
+                /* Don't perform the quoting if this & is part of an mdoc escape
+                 * sequence, e.g. \&
+                 */
+                if (i && *(string - 2) != '\\') {
+                    memcpy(&new_string[i], "&amp;", 5);
+                    i += 5;
+                } else {
+                    new_string[i++] = '&';
+                }
+                break;
+            case '\002':
+                memcpy(&new_string[i], "<b>", 3);
+                i += 3;
+                break;
+            case '\003':
+                memcpy(&new_string[i], "</b>", 4);
+                i += 4;
+                break;
+            default:
+                break;
+        }
+    }
+    new_string[i] = 0;
+    return new_string;
+}
+
+
 /*
  * callback_html --
  *  Callback function for run_query_html. It builds the html output and then
@@ -634,79 +707,18 @@
 callback_html(void *data, const char *section, const char *name,
 	const char *name_desc, const char *snippet, size_t snippet_length)
 {
-	const char *temp = snippet;
-	int i = 0;
-	size_t sz = 0;
-	int count = 0;
 	struct orig_callback_data *orig_data = (struct orig_callback_data *) data;
 	int (*callback) (void *, const char *, const char *, const char *,
 		const char *, size_t) = orig_data->callback;
-
-	/* First scan the snippet to find out the number of occurrences of {'>', '<'
-	 * '"', '&'}.
-	 * Then allocate a new buffer with sufficient space to be able to store the
-	 * quoted versions of the special characters {&gt;, &lt;, &quot;, &amp;}.
-	 * Copy over the characters from the original snippet to this buffer while
-	 * replacing the special characters with their quoted versions.
-	 */
-
-	while (*temp) {
-		sz = strcspn(temp, "<>\"&\002\003");
-		temp += sz + 1;
-		count++;
-	}
-	size_t qsnippet_length = snippet_length + count * 5;
-	char *qsnippet = emalloc(qsnippet_length + 1);
-	sz = 0;
-	while (*snippet) {
-		sz = strcspn(snippet, "<>\"&\002\003");
-		if (sz) {
-			memcpy(&qsnippet[i], snippet, sz);
-			snippet += sz;
-			i += sz;
-		}
-
-		switch (*snippet++) {
-		case '<':
-			memcpy(&qsnippet[i], "&lt;", 4);
-			i += 4;
-			break;
-		case '>':
-			memcpy(&qsnippet[i], "&gt;", 4);
-			i += 4;
-			break;
-		case '\"':
-			memcpy(&qsnippet[i], "&quot;", 6);
-			i += 6;
-			break;
-		case '&':
-			/* Don't perform the quoting if this & is part of an mdoc escape
-			 * sequence, e.g. \&
-			 */
-			if (i && *(snippet - 2) != '\\') {
-				memcpy(&qsnippet[i], "&amp;", 5);
-				i += 5;
-			} else {
-				qsnippet[i++] = '&';
-			}
-			break;
-		case '\002':
-			memcpy(&qsnippet[i], "<b>", 3);
-			i += 3;
-			break;
-		case '\003':
-			memcpy(&qsnippet[i], "</b>", 4);
-			i += 4;
-			break;
-		default:
-			break;
-		}
-	}
-	qsnippet[i] = 0;
-	(*callback)(orig_data->data, section, name, name_desc,
-		(const char *)qsnippet,	strlen(qsnippet));
-	free(qsnippet);
-	return 0;
+    size_t length = snippet_length;
+    size_t name_description_length = strlen(name_desc);
+    char *qsnippet = get_escaped_html_string(snippet, &length);
+    char *qname_description = get_escaped_html_string(name_desc, &name_description_length);
+    (*callback)(orig_data->data, section, name, qname_description,
+            (const char *)qsnippet, length);
+    free(qsnippet);
+    free(qname_description);
+    return 0;
 }
 
 /*



Home | Main Index | Thread Index | Old Index