commit 6f22091df20685c8b7a8a89823aa31606bea2be0
parent 42b52f54ede822d8e937025394d69702d5f910d3
Author: Christoph Lohmann <20h@r-36.net>
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:
ind.c | | | 36 | ++++++++++++++++++++++++------------ |
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 *addr, char *port)
/*
* 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[2]);
+
+ 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, char *ohost,
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, char *ohost,
}
/*
- * 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, char *ohost,
*
* 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, char *ohost,
recvb[1] = '\0';
}
+ /*
+ * Do not allow requests not beginning with '/' or which contain
+ * "..".
+ */
if (recvb[0] != '/' || strstr(recvb, "..")){
dprintf(sock, "%s", selinval);
return;