From af7a169637d40943e8d31fa35588170dabefcb23 Mon Sep 17 00:00:00 2001 From: Ingo Schwarze Date: Mon, 11 Jul 2016 22:48:37 +0000 Subject: Make all components of the URI individually optional, independent of each other, as in: http://man.openbsd.org[/manpath][/mansec][/arch]/name[.sec] The restrictions in the past kept confusing people. Triggered by a question from RafaelNeves at gmail dot com. --- cgi.c | 59 ++++++++++++++++++++++++++++++++++++++++++----------------- man.cgi.8 | 8 +++++--- 2 files changed, 47 insertions(+), 20 deletions(-) diff --git a/cgi.c b/cgi.c index 720dbc7d..f8497b58 100644 --- a/cgi.c +++ b/cgi.c @@ -1,4 +1,4 @@ -/* $Id: cgi.c,v 1.134 2016/07/10 10:05:33 schwarze Exp $ */ +/* $Id: cgi.c,v 1.135 2016/07/11 22:48:37 schwarze Exp $ */ /* * Copyright (c) 2011, 2012 Kristaps Dzonsons * Copyright (c) 2014, 2015, 2016 Ingo Schwarze @@ -1064,11 +1064,13 @@ main(void) static void parse_path_info(struct req *req, const char *path) { - char *dir; + char *dir[4]; + int i; req->isquery = 0; req->q.equal = 1; req->q.manpath = mandoc_strdup(path); + req->q.arch = NULL; /* Mandatory manual page name. */ if ((req->q.query = strrchr(req->q.manpath, '/')) == NULL) { @@ -1087,27 +1089,50 @@ parse_path_info(struct req *req, const char *path) } /* Handle the case of name[.section] only. */ - if (req->q.manpath == NULL) { - req->q.arch = NULL; + if (req->q.manpath == NULL) return; - } req->q.query = mandoc_strdup(req->q.query); - /* Optional architecture. */ - dir = strrchr(req->q.manpath, '/'); - if (dir != NULL && strncmp(dir + 1, "man", 3) != 0) { - *dir++ = '\0'; - req->q.arch = mandoc_strdup(dir); - dir = strrchr(req->q.manpath, '/'); - } else - req->q.arch = NULL; + /* Split directory components. */ + dir[i = 0] = req->q.manpath; + while ((dir[i + 1] = strchr(dir[i], '/')) != NULL) { + if (++i == 3) { + pg_error_badrequest( + "You specified too many directory components."); + exit(EXIT_FAILURE); + } + *dir[i]++ = '\0'; + } + + /* Optional manpath. */ + if ((i = validate_manpath(req, req->q.manpath)) == 0) + req->q.manpath = NULL; + else if (dir[1] == NULL) + return; - /* Optional directory name. */ - if (dir != NULL && strncmp(dir + 1, "man", 3) == 0) { - *dir++ = '\0'; + /* Optional section. */ + if (strncmp(dir[i], "man", 3) == 0) { free(req->q.sec); - req->q.sec = mandoc_strdup(dir + 3); + req->q.sec = mandoc_strdup(dir[i++] + 3); } + if (dir[i] == NULL) { + if (req->q.manpath == NULL) + free(dir[0]); + return; + } + if (dir[i + 1] != NULL) { + pg_error_badrequest( + "You specified an invalid directory component."); + exit(EXIT_FAILURE); + } + + /* Optional architecture. */ + if (i) { + req->q.arch = mandoc_strdup(dir[i]); + if (req->q.manpath == NULL) + free(dir[0]); + } else + req->q.arch = dir[0]; } /* diff --git a/man.cgi.8 b/man.cgi.8 index 7ed39794..0e1b60d6 100644 --- a/man.cgi.8 +++ b/man.cgi.8 @@ -1,4 +1,4 @@ -.\" $Id: man.cgi.8,v 1.19 2016/07/10 10:05:33 schwarze Exp $ +.\" $Id: man.cgi.8,v 1.20 2016/07/11 22:48:37 schwarze Exp $ .\" .\" Copyright (c) 2014, 2015, 2016 Ingo Schwarze .\" @@ -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: July 10 2016 $ +.Dd $Mdocdate: July 11 2016 $ .Dt MAN.CGI 8 .Os .Sh NAME @@ -252,7 +252,9 @@ and the name of the requested file, for example .Pa /OpenBSD-current/man1/mandoc.1 . This can be abbreviated according to the following syntax: .Sm off -.Op / Ar manpath Oo / Cm man Ar sec Oc Op / Ar arch +.Op / Ar manpath +.Op / Cm man Ar sec +.Op / Ar arch .Pf / Ar name Op \&. Ar sec .Sm on .It -- cgit v1.2.3-56-ge451