version 1.160, 2018/10/02 19:41:23 |
version 1.161, 2018/10/19 21:10:56 |
|
|
} |
} |
|
|
/* |
/* |
* If PATH_INFO is not a file name, translate it to a query. |
* Translate PATH_INFO to a query. |
*/ |
*/ |
static void |
static void |
parse_path_info(struct req *req, const char *path) |
parse_path_info(struct req *req, const char *path) |
{ |
{ |
char *dir[4]; |
const char *name, *sec, *end; |
int i; |
|
|
|
req->isquery = 0; |
req->isquery = 0; |
req->q.equal = 1; |
req->q.equal = 1; |
req->q.manpath = mandoc_strdup(path); |
req->q.manpath = NULL; |
req->q.arch = NULL; |
req->q.arch = NULL; |
|
|
/* Mandatory manual page name. */ |
/* Mandatory manual page name. */ |
if ((req->q.query = strrchr(req->q.manpath, '/')) == NULL) { |
if ((name = strrchr(path, '/')) == NULL) |
req->q.query = req->q.manpath; |
name = path; |
req->q.manpath = NULL; |
else |
} else |
name++; |
*req->q.query++ = '\0'; |
|
|
|
/* Optional trailing section. */ |
/* Optional trailing section. */ |
if ((req->q.sec = strrchr(req->q.query, '.')) != NULL) { |
sec = strrchr(name, '.'); |
if(isdigit((unsigned char)req->q.sec[1])) { |
if (sec != NULL && isdigit((unsigned char)*++sec)) { |
*req->q.sec++ = '\0'; |
req->q.query = mandoc_strndup(name, sec - name - 1); |
req->q.sec = mandoc_strdup(req->q.sec); |
req->q.sec = mandoc_strdup(sec); |
} else |
} else { |
req->q.sec = NULL; |
req->q.query = mandoc_strdup(name); |
|
req->q.sec = NULL; |
} |
} |
|
|
/* Handle the case of name[.section] only. */ |
/* Handle the case of name[.section] only. */ |
if (req->q.manpath == NULL) |
if (name == path) |
return; |
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. */ |
/* 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; |
req->q.manpath = NULL; |
else if (dir[1] == NULL) |
} |
return; |
|
|
|
/* Optional section. */ |
/* Optional section. */ |
if (strncmp(dir[i], "man", 3) == 0) { |
if (strncmp(path, "man", 3) == 0) { |
|
path += 3; |
|
end = strchr(path, '/'); |
free(req->q.sec); |
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) |
/* Optional architecture. */ |
free(dir[0]); |
end = strchr(path, '/'); |
return; |
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( |
pg_error_badrequest( |
"You specified an invalid directory component."); |
"You specified an invalid directory component."); |
exit(EXIT_FAILURE); |
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]; |
|
} |
} |
|
|
/* |
/* |