Module Name: src
Committed By: christos
Date: Thu Mar 24 16:07:13 UTC 2016
Modified Files:
src/usr.sbin/makemandb: apropos-utils.c
Log Message:
PR/51004: Abhinav Upadhyay: apropos html mode doesn't handle especial
characters in the short description
To generate a diff of this commit:
cvs rdiff -u -r1.20 -r1.21 src/usr.sbin/makemandb/apropos-utils.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/usr.sbin/makemandb/apropos-utils.c
diff -u src/usr.sbin/makemandb/apropos-utils.c:1.20 src/usr.sbin/makemandb/apropos-utils.c:1.21
--- src/usr.sbin/makemandb/apropos-utils.c:1.20 Sun Mar 20 13:31:09 2016
+++ src/usr.sbin/makemandb/apropos-utils.c Thu Mar 24 12:07:13 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: apropos-utils.c,v 1.20 2016/03/20 17:31:09 christos Exp $ */
+/* $NetBSD: apropos-utils.c,v 1.21 2016/03/24 16:07:13 christos Exp $ */
/*-
* Copyright (c) 2011 Abhinav Upadhyay <[email protected]>
* All rights reserved.
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__RCSID("$NetBSD: apropos-utils.c,v 1.20 2016/03/20 17:31:09 christos Exp $");
+__RCSID("$NetBSD: apropos-utils.c,v 1.21 2016/03/24 16:07:13 christos Exp $");
#include <sys/queue.h>
#include <sys/stat.h>
@@ -625,87 +625,95 @@ run_query_internal(sqlite3 *db, const ch
return *(args->errmsg) == NULL ? 0 : -1;
}
-/*
- * callback_html --
- * Callback function for run_query_html. It builds the html output and then
- * calls the actual user supplied callback function.
- */
-static int
-callback_html(void *data, const char *section, const char *name,
- const char *name_desc, const char *snippet, size_t snippet_length)
+static char *
+get_escaped_html_string(const char *src, size_t *slen)
{
- 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 {>, <, ", &}.
- * Copy over the characters from the original snippet to this buffer while
- * replacing the special characters with their quoted versions.
+ static const char trouble[] = "<>\"&\002\003";
+ /*
+ * First scan the src 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 {>, <, ", &}.
+ * Copy over the characters from the original src into
+ * this buffer while replacing the special characters with
+ * their quoted versions.
*/
+ char *dst, *ddst;
+ size_t count;
+ const char *ssrc;
+
+ for (count = 0, ssrc = src; *src; count++) {
+ size_t sz = strcspn(src, trouble);
+ src += sz + 1;
+ }
- 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++) {
+#define append(a) do { \
+ memcpy(dst, (a), sizeof(a) - 1); \
+ dst += sizeof(a) - 1; \
+ } while (/*CONSTCOND*/0)
+
+ ddst = dst = emalloc(*slen + count * 5 + 1);
+ for (src = ssrc; *src; src++) {
+ switch (*src) {
case '<':
- memcpy(&qsnippet[i], "<", 4);
- i += 4;
+ append("<");
break;
case '>':
- memcpy(&qsnippet[i], ">", 4);
- i += 4;
+ append(">");
break;
case '\"':
- memcpy(&qsnippet[i], """, 6);
- i += 6;
+ append(""");
break;
case '&':
- /* Don't perform the quoting if this & is part of an mdoc escape
- * sequence, e.g. \&
+ /*
+ * Don't perform the quoting if this & is part of
+ * an mdoc escape sequence, e.g. \&
*/
- if (i && *(snippet - 2) != '\\') {
- memcpy(&qsnippet[i], "&", 5);
- i += 5;
- } else {
- qsnippet[i++] = '&';
- }
+ if (src != ssrc && src[-1] != '\\')
+ append("&");
+ else
+ append("&");
break;
case '\002':
- memcpy(&qsnippet[i], "<b>", 3);
- i += 3;
+ append("<b>");
break;
case '\003':
- memcpy(&qsnippet[i], "</b>", 4);
- i += 4;
+ append("</b>");
break;
default:
+ *dst++ = *src;
break;
}
}
- qsnippet[i] = 0;
- (*callback)(orig_data->data, section, name, name_desc,
- (const char *)qsnippet, strlen(qsnippet));
+ *dst = '\0';
+ *slen = dst - ddst;
+ return ddst;
+}
+
+
+/*
+ * callback_html --
+ * Callback function for run_query_html. It builds the html output and then
+ * calls the actual user supplied callback function.
+ */
+static int
+callback_html(void *data, const char *section, const char *name,
+ const char *name_desc, const char *snippet, size_t snippet_length)
+{
+ struct orig_callback_data *orig_data = data;
+ int (*callback)(void *, const char *, const char *, const char *,
+ const char *, size_t) = orig_data->callback;
+ 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,
+ qsnippet, length);
free(qsnippet);
+ free(qname_description);
return 0;
}