diff options
author | bapt <bapt@FreeBSD.org> | 2014-12-02 23:24:57 +0000 |
---|---|---|
committer | bapt <bapt@FreeBSD.org> | 2014-12-02 23:24:57 +0000 |
commit | 919f2a28755126f55b458d6553ac5e10b76203b3 (patch) | |
tree | 6b285eca5de51692bcaade66a629a2b84eadb8c7 /contrib/mdocml/cgi.c | |
parent | d24ff3fdf2f10c9b05c568b96812b7560b5c652a (diff) | |
parent | e00686f8f18c8c3eb3a800468a031699ed0bbc8f (diff) | |
download | FreeBSD-src-919f2a28755126f55b458d6553ac5e10b76203b3.zip FreeBSD-src-919f2a28755126f55b458d6553ac5e10b76203b3.tar.gz |
Update to mandoc cvs version as of 20141201
- Compatiblity with existing manpages has been improved
- Now support ".so" directive with compressed manpages (which fixes a regression
we have since we have new man(1))
Diffstat (limited to 'contrib/mdocml/cgi.c')
-rw-r--r-- | contrib/mdocml/cgi.c | 133 |
1 files changed, 71 insertions, 62 deletions
diff --git a/contrib/mdocml/cgi.c b/contrib/mdocml/cgi.c index 1e38e3d..65064ab 100644 --- a/contrib/mdocml/cgi.c +++ b/contrib/mdocml/cgi.c @@ -1,4 +1,4 @@ -/* $Id: cgi.c,v 1.92 2014/08/05 15:29:30 schwarze Exp $ */ +/* $Id: cgi.c,v 1.102 2014/11/26 17:55:27 schwarze Exp $ */ /* * Copyright (c) 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2014 Ingo Schwarze <schwarze@usta.de> @@ -15,9 +15,10 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifdef HAVE_CONFIG_H #include "config.h" -#endif + +#include <sys/types.h> +#include <sys/time.h> #include <ctype.h> #include <errno.h> @@ -91,14 +92,14 @@ static const char *const sec_names[] = { "All Sections", "1 - General Commands", "2 - System Calls", - "3 - Subroutines", - "3p - Perl Subroutines", - "4 - Special Files", + "3 - Library Functions", + "3p - Perl Library", + "4 - Device Drivers", "5 - File Formats", "6 - Games", - "7 - Macros and Conventions", - "8 - Maintenance Commands", - "9 - Kernel Interface" + "7 - Miscellaneous Information", + "8 - System Manager\'s Manual", + "9 - Kernel Developer\'s Manual" }; static const int sec_MAX = sizeof(sec_names) / sizeof(char *); @@ -162,8 +163,7 @@ http_printquery(const struct req *req, const char *sep) printf("%sarch=", sep); http_print(req->q.arch); } - if (NULL != req->q.manpath && - strcmp(req->q.manpath, req->p[0])) { + if (strcmp(req->q.manpath, req->p[0])) { printf("%smanpath=", sep); http_print(req->q.manpath); } @@ -297,11 +297,6 @@ next: if (*qs != '\0') qs++; } - - /* Fall back to the default manpath. */ - - if (req->q.manpath == NULL) - req->q.manpath = mandoc_strdup(req->p[0]); } static void @@ -375,13 +370,10 @@ resp_begin_html(int code, const char *msg) resp_begin_http(code, msg); - printf("<!DOCTYPE HTML PUBLIC " - " \"-//W3C//DTD HTML 4.01//EN\"" - " \"http://www.w3.org/TR/html4/strict.dtd\">\n" + printf("<!DOCTYPE html>\n" "<HTML>\n" "<HEAD>\n" - "<META HTTP-EQUIV=\"Content-Type\"" - " CONTENT=\"text/html; charset=utf-8\">\n" + "<META CHARSET=\"UTF-8\" />\n" "<LINK REL=\"stylesheet\" HREF=\"%s/man-cgi.css\"" " TYPE=\"text/css\" media=\"all\">\n" "<LINK REL=\"stylesheet\" HREF=\"%s/man.css\"" @@ -471,8 +463,7 @@ resp_searchform(const struct req *req) puts("<SELECT NAME=\"manpath\">"); for (i = 0; i < (int)req->psz; i++) { printf("<OPTION "); - if (NULL == req->q.manpath ? 0 == i : - 0 == strcmp(req->q.manpath, req->p[i])) + if (strcmp(req->q.manpath, req->p[i]) == 0) printf("SELECTED=\"selected\" "); printf("VALUE=\""); html_print(req->p[i]); @@ -826,6 +817,7 @@ static void format(const struct req *req, const char *file) { struct mparse *mp; + struct mchars *mchars; struct mdoc *mdoc; struct man *man; void *vp; @@ -839,8 +831,9 @@ format(const struct req *req, const char *file) return; } + mchars = mchars_alloc(); mp = mparse_alloc(MPARSE_SO, MANDOCLEVEL_FATAL, NULL, - req->q.manpath); + mchars, req->q.manpath); rc = mparse_readfd(mp, fd, file); close(fd); @@ -866,10 +859,11 @@ format(const struct req *req, const char *file) req->q.manpath, file); pg_error_internal(); mparse_free(mp); + mchars_free(mchars); return; } - vp = html_alloc(opts); + vp = html_alloc(mchars, opts); if (NULL != mdoc) html_mdoc(vp, mdoc); @@ -878,6 +872,7 @@ format(const struct req *req, const char *file) html_free(vp); mparse_free(mp); + mchars_free(mchars); free(opts); } @@ -953,10 +948,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. @@ -973,54 +968,54 @@ pg_search(const struct req *req) search.arch = req->q.arch; search.sec = req->q.sec; - search.deftype = req->q.equal ? TYPE_Nm : (TYPE_Nm | TYPE_Nd); - search.flags = req->q.equal ? MANSEARCH_MAN : 0; + search.outkey = "Nd"; + search.argmode = req->q.equal ? ARG_NAME : ARG_EXPR; + search.firstmatch = 1; paths.sz = 1; paths.paths = mandoc_malloc(sizeof(char *)); 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, "Nd", &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); } @@ -1029,10 +1024,23 @@ int main(void) { struct req req; + struct itimerval itimer; const char *path; const char *querystring; int i; + /* Poor man's ReDoS mitigation. */ + + itimer.it_value.tv_sec = 2; + itimer.it_value.tv_usec = 0; + itimer.it_interval.tv_sec = 2; + itimer.it_interval.tv_usec = 0; + if (setitimer(ITIMER_VIRTUAL, &itimer, NULL) == -1) { + fprintf(stderr, "setitimer: %s\n", strerror(errno)); + pg_error_internal(); + return(EXIT_FAILURE); + } + /* Scan our run-time environment. */ if (NULL == (scriptname = getenv("SCRIPT_NAME"))) @@ -1066,8 +1074,9 @@ main(void) if (NULL != (querystring = getenv("QUERY_STRING"))) http_parse(&req, querystring); - if ( ! (NULL == req.q.manpath || - validate_manpath(&req, req.q.manpath))) { + if (req.q.manpath == NULL) + req.q.manpath = mandoc_strdup(req.p[0]); + else if ( ! validate_manpath(&req, req.q.manpath)) { pg_error_badrequest( "You specified an invalid manpath."); return(EXIT_FAILURE); |