commit - a13739138b17a21dbb50011cc65fb135e9f804c8
commit + 9f006a2127398af12ecf9159cd5ef28b3685e7a6
blob - bf662e37bc7aecfb660fa7d68f1c2d5885361f33
blob + 187a4ac461eb025869e5586e5aecd819b4ee8344
--- ChangeLog
+++ ChangeLog
2021-02-07 Omar Polo <op@omarpolo.com>
+ * ex.c (do_exec): [cgi] split the query in words if needed and add them to the argv
+
* parse.y (option): added prefork option
2021-02-06 Omar Polo <op@omarpolo.com>
blob - 58f5004c7513d3f6f2e4566099fad2bb3b9cb1c4
blob + 0a65472deabc66510a2c758b4d3ac50ecb837912
--- ex.c
+++ ex.c
va_end(ap);
return s;
+}
+
+static void
+do_exec(const char *ex, const char *spath, char *query)
+{
+ char **argv, buf[PATH_MAX], *sname, *t;
+ size_t i, n;
+
+ strlcpy(buf, spath, sizeof(buf));
+ sname = basename(buf);
+
+ if (query == NULL || strchr(query, '=') != NULL) {
+ if ((argv = calloc(2, sizeof(char*))) == NULL)
+ err(1, "calloc");
+ argv[0] = sname;
+ execvp(ex, argv);
+ warn("execvp: %s", argv[0]);
+ return;
+ }
+
+ n = 1;
+ for (t = query ;; t++, n++) {
+ if ((t = strchr(t, '+')) == NULL)
+ break;
+ }
+
+ if ((argv = calloc(n+2, sizeof(char*))) == NULL)
+ err(1, "calloc");
+
+ argv[0] = sname;
+ for (i = 0; i < n; ++i) {
+ t = strchr(query, '+');
+ if (t != NULL)
+ *t = '\0';
+ argv[i+1] = pct_decode_str(query);
+ query = t+1;
+ }
+
+ execvp(ex, argv);
+ warn("execvp: %s", argv[0]);
}
/* fd or -1 on error */
return -1;
case 0: { /* child */
- char *argv[] = {NULL, NULL};
char *ex, *pwd;
char iribuf[GEMINI_URL_LEN];
char path[PATH_MAX];
goto childerr;
ex = xasprintf("%s/%s", vhost->dir, spath);
- argv[0] = ex;
serialize_iri(iri, iribuf, sizeof(iribuf));
safe_setenv("TLS_CLIENT_ISSUER", cissuer);
safe_setenv("TLS_CLIENT_HASH", chash);
- strlcpy(path, argv[0], sizeof(path));
+ strlcpy(path, ex, sizeof(path));
+
pwd = dirname(path);
if (chdir(pwd)) {
warn("chdir");
goto childerr;
}
- execvp(argv[0], argv);
- warn("execvp: %s", argv[0]);
+ do_exec(ex, spath, iri->query);
goto childerr;
}
blob - af829ba968a9fc8b2472ce6efd7403d4811d37ef
blob + 1beb95e383fae7773dede8dc27991e251dc5e9d7
--- gmid.h
+++ gmid.h
int parse_iri(char*, struct iri*, const char**);
int trim_req_iri(char*, const char **);
int serialize_iri(struct iri*, char*, size_t);
+char *pct_decode_str(char *);
/* puny.c */
int puny_decode(const char*, char*, size_t, const char**);
blob - 1d550efe97334463553ecebb6f9d4392cc0a1954
blob + b911b0dd6408e147ca0a6beb908dfc8d5ef53d9c
--- iri.c
+++ iri.c
return 1;
}
+static void
+pct_decode(char *s)
+{
+ sscanf(s+1, "%2hhx", s);
+ memmove(s+1, s+3, strlen(s+3)+1);
+}
+
static int
parse_pct_encoded(struct parser *p)
{
return 0;
}
- sscanf(p->iri+1, "%2hhx", p->iri);
- memmove(p->iri+1, p->iri+3, strlen(p->iri+3)+1);
+ pct_decode(p->iri);
if (*p->iri == '\0') {
p->err = "illegal percent-encoding";
return 0;
return l < len;
}
+
+char *
+pct_decode_str(char *s)
+{
+ char *t;
+
+ for (t = s; *t; ++t) {
+ if (*t == '%' && valid_pct_enc_string(t))
+ pct_decode(t);
+ }
+
+ return s;
+}
blob - 9492b1d92e0ab68cca7f4ac7cd36fb69d7c7cfe9
blob + 1c991b3530bd7f9d63f0b5bedc5690ea41de564a
--- regress/runtime
+++ regress/runtime
wait || true
}
+count() {
+ wc -l | xargs
+}
+
# usage: eq a b errmsg
# if a and b aren't equal strings, exit with errmsg
eq() {
check "should be running"
-# finally try with CGI scripts
+# try with CGI scripts
config '' 'cgi "*"'
checkconf
restart
eq "$(cat bigfile.sha)" "$(cat testdata/bigfile.sha)" "Unexpected sha for /serve-bigfile"
echo OK GET /serve-bigfile with cgi
+# ensure we split the query correctly
+eq "$(get /env | awk /^-/ | count)" 1 "Unexpected number of arguments"
+eq "$(get /env?foo | awk /^-/ | count)" 2 "Unexpected number of arguments"
+eq "$(get /env?foo+bar | awk /^-/ | count)" 3 "Unexpected number of arguments"
+eq "$(get /env?foo+bar=5 | awk /^-/ | count)" 1 "Unexpected number of arguments"
+eq "$(get /env?foo+bar%3d5 | awk /^-/ | count)" 3 "Unexpected number of arguments"
+
check "should be running"
config '' 'index "foo.gmi"'