=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/mandoc/cgi.c,v retrieving revision 1.73 retrieving revision 1.74 diff -c -r1.73 -r1.74 *** src/usr.bin/mandoc/cgi.c 2016/07/10 10:03:15 1.73 --- src/usr.bin/mandoc/cgi.c 2016/07/11 22:46:57 1.74 *************** *** 1,4 **** ! /* $OpenBSD: cgi.c,v 1.73 2016/07/10 10:03:15 schwarze Exp $ */ /* * Copyright (c) 2011, 2012 Kristaps Dzonsons * Copyright (c) 2014, 2015, 2016 Ingo Schwarze --- 1,4 ---- ! /* $OpenBSD: cgi.c,v 1.74 2016/07/11 22:46:57 schwarze Exp $ */ /* * Copyright (c) 2011, 2012 Kristaps Dzonsons * Copyright (c) 2014, 2015, 2016 Ingo Schwarze *************** *** 1062,1072 **** static void parse_path_info(struct req *req, const char *path) { ! char *dir; req->isquery = 0; req->q.equal = 1; req->q.manpath = mandoc_strdup(path); /* Mandatory manual page name. */ if ((req->q.query = strrchr(req->q.manpath, '/')) == NULL) { --- 1062,1074 ---- static void parse_path_info(struct req *req, const char *path) { ! 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) { *************** *** 1085,1111 **** } /* Handle the case of name[.section] only. */ ! if (req->q.manpath == NULL) { ! req->q.arch = 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; ! /* Optional directory name. */ ! if (dir != NULL && strncmp(dir + 1, "man", 3) == 0) { ! *dir++ = '\0'; free(req->q.sec); ! req->q.sec = mandoc_strdup(dir + 3); } } /* --- 1087,1136 ---- } /* Handle the case of name[.section] only. */ ! if (req->q.manpath == NULL) 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) ! req->q.manpath = NULL; ! else if (dir[1] == NULL) ! return; ! ! /* Optional section. */ ! if (strncmp(dir[i], "man", 3) == 0) { free(req->q.sec); ! 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]; } /*