aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--cgi.c67
-rw-r--r--man.cgi.810
2 files changed, 41 insertions, 36 deletions
diff --git a/cgi.c b/cgi.c
index cbef30ef..81503081 100644
--- a/cgi.c
+++ b/cgi.c
@@ -1,4 +1,4 @@
-/* $Id: cgi.c,v 1.96 2014/08/26 11:21:40 schwarze Exp $ */
+/* $Id: cgi.c,v 1.97 2014/09/14 19:44:28 schwarze Exp $ */
/*
* Copyright (c) 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2014 Ingo Schwarze <schwarze@usta.de>
@@ -954,10 +954,10 @@ pg_search(const struct req *req)
struct mansearch search;
struct manpaths paths;
struct manpage *res;
- char **cp;
- const char *ep, *start;
+ char **argv;
+ char *query, *rp, *wp;
size_t ressz;
- int i, sz;
+ int argc;
/*
* Begin by chdir()ing into the root of the manpath.
@@ -982,46 +982,45 @@ pg_search(const struct req *req)
paths.paths[0] = mandoc_strdup(".");
/*
- * Poor man's tokenisation: just break apart by spaces.
- * Yes, this is half-ass. But it works for now.
+ * Break apart at spaces with backslash-escaping.
*/
- ep = req->q.query;
- while (ep && isspace((unsigned char)*ep))
- ep++;
-
- sz = 0;
- cp = NULL;
- while (ep && '\0' != *ep) {
- cp = mandoc_reallocarray(cp, sz + 1, sizeof(char *));
- start = ep;
- while ('\0' != *ep && ! isspace((unsigned char)*ep))
- ep++;
- cp[sz] = mandoc_malloc((ep - start) + 1);
- memcpy(cp[sz], start, ep - start);
- cp[sz++][ep - start] = '\0';
- while (isspace((unsigned char)*ep))
- ep++;
+ argc = 0;
+ argv = NULL;
+ rp = query = mandoc_strdup(req->q.query);
+ for (;;) {
+ while (isspace((unsigned char)*rp))
+ rp++;
+ if (*rp == '\0')
+ break;
+ argv = mandoc_reallocarray(argv, argc + 1, sizeof(char *));
+ argv[argc++] = wp = rp;
+ for (;;) {
+ if (isspace((unsigned char)*rp)) {
+ *wp = '\0';
+ rp++;
+ break;
+ }
+ if (rp[0] == '\\' && rp[1] != '\0')
+ rp++;
+ if (wp != rp)
+ *wp = *rp;
+ if (*rp == '\0')
+ break;
+ wp++;
+ rp++;
+ }
}
- if (0 == mansearch(&search, &paths, sz, cp, &res, &ressz))
+ if (0 == mansearch(&search, &paths, argc, argv, &res, &ressz))
pg_noresult(req, "You entered an invalid query.");
else if (0 == ressz)
pg_noresult(req, "No results found.");
else
pg_searchres(req, res, ressz);
- for (i = 0; i < sz; i++)
- free(cp[i]);
- free(cp);
-
- for (i = 0; i < (int)ressz; i++) {
- free(res[i].file);
- free(res[i].names);
- free(res[i].output);
- }
- free(res);
-
+ free(query);
+ mansearch_free(res, ressz);
free(paths.paths[0]);
free(paths.paths);
}
diff --git a/man.cgi.8 b/man.cgi.8
index d50f3fad..4d3588b0 100644
--- a/man.cgi.8
+++ b/man.cgi.8
@@ -1,4 +1,4 @@
-.\" $Id: man.cgi.8,v 1.10 2014/08/22 15:49:50 schwarze Exp $
+.\" $Id: man.cgi.8,v 1.11 2014/09/14 19:44:28 schwarze Exp $
.\"
.\" Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org>
.\"
@@ -14,7 +14,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: August 22 2014 $
+.Dd $Mdocdate: September 14 2014 $
.Dt MAN.CGI 8
.Os
.Sh NAME
@@ -43,6 +43,12 @@ either a name of a manual page or an
using the syntax described in the
.Xr apropos 1
manual; filling this in is required for each search.
+.Pp
+The expression is broken into words at whitespace.
+Whitespace characters and backslashes can be escaped
+by prepending a backslash.
+The effect of prepending a backslash to another character is undefined;
+in the current implementation, it has no effect.
.It
A
.Dq Submit