aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@openbsd.org>2018-10-19 21:10:56 +0000
committerIngo Schwarze <schwarze@openbsd.org>2018-10-19 21:10:56 +0000
commite8c53adcb6405ea27097b4c2b26b557e8a9f6064 (patch)
tree4e5ee0d6759a89e063650a5b3c0f2143633d9171
parent5f5498f2abb44874721f0c7cfa0a0b396eea3c00 (diff)
downloadmandoc-e8c53adcb6405ea27097b4c2b26b557e8a9f6064.tar.gz
mandoc-e8c53adcb6405ea27097b4c2b26b557e8a9f6064.tar.zst
mandoc-e8c53adcb6405ea27097b4c2b26b557e8a9f6064.zip
Rewrite parse_path_info() to be four lines shorter, simplify ownership
of allocated strings, do not write to the input string, and improve diagnostic output. The confusing error message "invalid arch" as a reaction to mistyping the release name was noticed by tb@, who likes the new code and message.
-rw-r--r--cgi.c88
1 files changed, 41 insertions, 47 deletions
diff --git a/cgi.c b/cgi.c
index afb38f1d..ccda87a7 100644
--- a/cgi.c
+++ b/cgi.c
@@ -1,4 +1,4 @@
-/* $Id: cgi.c,v 1.160 2018/10/02 19:41:23 schwarze Exp $ */
+/* $Id: cgi.c,v 1.161 2018/10/19 21:10:56 schwarze Exp $ */
/*
* Copyright (c) 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2014, 2015, 2016, 2017, 2018 Ingo Schwarze <schwarze@usta.de>
@@ -1144,80 +1144,74 @@ main(void)
}
/*
- * If PATH_INFO is not a file name, translate it to a query.
+ * Translate PATH_INFO to a query.
*/
static void
parse_path_info(struct req *req, const char *path)
{
- char *dir[4];
- int i;
+ const char *name, *sec, *end;
req->isquery = 0;
req->q.equal = 1;
- req->q.manpath = mandoc_strdup(path);
+ req->q.manpath = NULL;
req->q.arch = NULL;
/* Mandatory manual page name. */
- if ((req->q.query = strrchr(req->q.manpath, '/')) == NULL) {
- req->q.query = req->q.manpath;
- req->q.manpath = NULL;
- } else
- *req->q.query++ = '\0';
+ if ((name = strrchr(path, '/')) == NULL)
+ name = path;
+ else
+ name++;
/* Optional trailing section. */
- if ((req->q.sec = strrchr(req->q.query, '.')) != NULL) {
- if(isdigit((unsigned char)req->q.sec[1])) {
- *req->q.sec++ = '\0';
- req->q.sec = mandoc_strdup(req->q.sec);
- } else
- req->q.sec = NULL;
+ sec = strrchr(name, '.');
+ if (sec != NULL && isdigit((unsigned char)*++sec)) {
+ req->q.query = mandoc_strndup(name, sec - name - 1);
+ req->q.sec = mandoc_strdup(sec);
+ } else {
+ req->q.query = mandoc_strdup(name);
+ req->q.sec = NULL;
}
/* Handle the case of name[.section] only. */
- if (req->q.manpath == NULL)
+ if (name == path)
return;
- req->q.query = mandoc_strdup(req->q.query);
-
- /* 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)
+ end = strchr(path, '/');
+ req->q.manpath = mandoc_strndup(path, end - path);
+ if (validate_manpath(req, req->q.manpath)) {
+ path = end + 1;
+ if (name == path)
+ return;
+ } else {
+ free(req->q.manpath);
req->q.manpath = NULL;
- else if (dir[1] == NULL)
- return;
+ }
/* Optional section. */
- if (strncmp(dir[i], "man", 3) == 0) {
+ if (strncmp(path, "man", 3) == 0) {
+ path += 3;
+ end = strchr(path, '/');
free(req->q.sec);
- req->q.sec = mandoc_strdup(dir[i++] + 3);
+ req->q.sec = mandoc_strndup(path, end - path);
+ path = end + 1;
+ if (name == path)
+ return;
}
- if (dir[i] == NULL) {
- if (req->q.manpath == NULL)
- free(dir[0]);
- return;
+
+ /* Optional architecture. */
+ end = strchr(path, '/');
+ if (end + 1 != name) {
+ pg_error_badrequest(
+ "You specified too many directory components.");
+ exit(EXIT_FAILURE);
}
- if (dir[i + 1] != NULL) {
+ req->q.arch = mandoc_strndup(path, end - path);
+ if (validate_arch(req->q.arch) == 0) {
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];
}
/*