diff options
author | Ingo Schwarze <schwarze@openbsd.org> | 2016-07-11 22:48:37 +0000 |
---|---|---|
committer | Ingo Schwarze <schwarze@openbsd.org> | 2016-07-11 22:48:37 +0000 |
commit | 7c248f50d315de6e082833a448c2ce9d69b6773b (patch) | |
tree | 1455a1fc42c0b1b1082a066a597684c36bfe20d0 | |
parent | 95e4e9c963ecf42fd1eb5ad91d0867abc031fbaa (diff) | |
download | mandoc-7c248f50d315de6e082833a448c2ce9d69b6773b.tar.gz |
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.
-rw-r--r-- | cgi.c | 57 | ||||
-rw-r--r-- | man.cgi.8 | 4 |
2 files changed, 44 insertions, 17 deletions
@@ -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]; } /* @@ -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 |