| Fix relative printelem with ? in name. - geomyidae - A small C-based gopherd. | |
| git clone git://bitreich.org/geomyidae/ git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfri… | |
| Log | |
| Files | |
| Refs | |
| Tags | |
| README | |
| LICENSE | |
| --- | |
| commit 6f22091df20685c8b7a8a89823aa31606bea2be0 | |
| parent 42b52f54ede822d8e937025394d69702d5f910d3 | |
| Author: Christoph Lohmann <[email protected]> | |
| Date: Sun, 4 Apr 2021 20:57:28 +0200 | |
| Fix relative printelem with ? in name. | |
| * Thanks adc for reporting. | |
| * Add more comments in special selector request casing. | |
| Diffstat: | |
| M ind.c | 36 +++++++++++++++++++++--------… | |
| M main.c | 12 ++++++++++-- | |
| 2 files changed, 34 insertions(+), 14 deletions(-) | |
| --- | |
| diff --git a/ind.c b/ind.c | |
| @@ -403,8 +403,8 @@ scanfile(char *fname) | |
| int | |
| printelem(int fd, Elems *el, char *file, char *base, char *addr, char *port) | |
| { | |
| - char *path, *p, buf[PATH_MAX+1]; | |
| - int len; | |
| + char *path, *p, *argbase, buf[PATH_MAX+1]; | |
| + int len, blen; | |
| if (!strcmp(el->e[3], "server")) { | |
| free(el->e[3]); | |
| @@ -417,24 +417,36 @@ printelem(int fd, Elems *el, char *file, char *base, char… | |
| /* | |
| * Ignore if the path is from base, if it might be some h type with | |
| - * some URL and ignore various types that have different semantics but | |
| - * to point to some file or directory. | |
| + * some URL and ignore various types that have different semantics, | |
| + * do not point to some file or directory. | |
| + */ | |
| + /* | |
| + * FUTURE: If ever special requests with no beginning '/' are used in | |
| + * geomyidae, this is the place to control this. | |
| */ | |
| if ((el->e[2][0] != '\0' | |
| - && el->e[2][0] != '/' | |
| - && el->e[0][0] != 'i' | |
| - && el->e[0][0] != '2' | |
| - && el->e[0][0] != '3' | |
| - && el->e[0][0] != '8' | |
| - && el->e[0][0] != 'w' | |
| - && el->e[0][0] != 'T') && | |
| + && el->e[2][0] != '/' /* Absolute Request. */ | |
| + && el->e[0][0] != 'i' /* Informational item. */ | |
| + && el->e[0][0] != '2' /* CSO server */ | |
| + && el->e[0][0] != '3' /* Error */ | |
| + && el->e[0][0] != '8' /* Telnet */ | |
| + && el->e[0][0] != 'w' /* Selector is direct URI. */ | |
| + && el->e[0][0] != 'T') && /* tn3270 */ | |
| !(el->e[0][0] == 'h' && !strncmp(el->e[2], "URL:", 4))) { | |
| path = file + strlen(base); | |
| if ((p = strrchr(path, '/'))) | |
| len = p - path; | |
| else | |
| len = strlen(path); | |
| - snprintf(buf, sizeof(buf), "%s%.*s/%s", base, len, path, el->e… | |
| + | |
| + argbase = strchr(el->e[2], '?'); | |
| + if (argbase != NULL) | |
| + blen = argbase - el->e[2]; | |
| + else | |
| + blen = strlen(el->e[2]); | |
| + | |
| + snprintf(buf, sizeof(buf), "%s%.*s/%.*s", base, len, | |
| + path, blen, el->e[2]); | |
| if ((path = realpath(buf, NULL)) && | |
| !strncmp(base, path, strlen(base))) { | |
| diff --git a/main.c b/main.c | |
| @@ -177,6 +177,7 @@ handlerequest(int sock, char *req, int rlen, char *base, ch… | |
| memmove(recvc, recvb, rlen+1); | |
| + /* Redirect to HTML redirecting to the specified URI. */ | |
| if (!strncmp(recvb, "URL:", 4)) { | |
| len = snprintf(path, sizeof(path), htredir, | |
| recvb + 4, recvb + 4, recvb + 4); | |
| @@ -189,8 +190,8 @@ handlerequest(int sock, char *req, int rlen, char *base, ch… | |
| } | |
| /* | |
| - * Valid cases in gopher we overwrite here, but could be used for | |
| - * other geomyidae features: | |
| + * FUTURE: Valid cases in gopher we overwrite here, but could be used | |
| + * for other geomyidae features: | |
| * | |
| * request string = "?..." -> "/?..." | |
| * request string = "" -> "/" | |
| @@ -198,6 +199,9 @@ handlerequest(int sock, char *req, int rlen, char *base, ch… | |
| * | |
| * Be careful, when you consider those special cases to be used | |
| * for some feature. You can easily do good and bad. | |
| + * | |
| + * Look at printelem() in ind.c for the counterpart of producing | |
| + * selectors. | |
| */ | |
| args = strchr(recvb, '?'); | |
| @@ -209,6 +213,10 @@ handlerequest(int sock, char *req, int rlen, char *base, c… | |
| recvb[1] = '\0'; | |
| } | |
| + /* | |
| + * Do not allow requests not beginning with '/' or which contain | |
| + * "..". | |
| + */ | |
| if (recvb[0] != '/' || strstr(recvb, "..")){ | |
| dprintf(sock, "%s", selinval); | |
| return; |