diff options
| author | christos <christos@NetBSD.org> | 2016-03-24 16:07:13 +0000 |
|---|---|---|
| committer | christos <christos@NetBSD.org> | 2016-03-24 16:07:13 +0000 |
| commit | 7dfdf5697d7baa8d00130fc3f86f419cfe4e1bc8 (patch) | |
| tree | f6b9e09f052f45488232e9a6ba231996f9c0bf13 /usr.sbin | |
| parent | dbea98abd806f5d29ea30bd148e2fdcbb4b92c43 (diff) | |
PR/51004: Abhinav Upadhyay: apropos html mode doesn't handle especial
characters in the short description
Diffstat (limited to 'usr.sbin')
| -rw-r--r-- | usr.sbin/makemandb/apropos-utils.c | 128 |
1 files changed, 68 insertions, 60 deletions
diff --git a/usr.sbin/makemandb/apropos-utils.c b/usr.sbin/makemandb/apropos-utils.c index 424ca8a2e1f..fcfa4f20835 100644 --- a/usr.sbin/makemandb/apropos-utils.c +++ b/usr.sbin/makemandb/apropos-utils.c @@ -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 <er.abhinav.upadhyay@gmail.com> * 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 char *snippet_args[3], query_args *args) 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; - while (*temp) { - sz = strcspn(temp, "<>\"&\002\003"); - temp += sz + 1; - count++; + for (count = 0, ssrc = src; *src; count++) { + size_t sz = strcspn(src, trouble); + src += sz + 1; } - 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; } |
