[cgi] split the query in words if needed and add them to the argv

This commit is contained in:
Omar Polo 2021-02-07 18:55:04 +00:00
parent a13739138b
commit 9f006a2127
5 changed files with 79 additions and 8 deletions

View File

@ -1,5 +1,7 @@
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>

48
ex.c
View File

@ -230,6 +230,46 @@ xasprintf(const char *fmt, ...)
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 */
static int
launch_cgi(struct iri *iri, const char *spath, char *relpath,
@ -246,7 +286,6 @@ launch_cgi(struct iri *iri, const char *spath, char *relpath,
return -1;
case 0: { /* child */
char *argv[] = {NULL, NULL};
char *ex, *pwd;
char iribuf[GEMINI_URL_LEN];
char path[PATH_MAX];
@ -256,7 +295,6 @@ launch_cgi(struct iri *iri, const char *spath, char *relpath,
goto childerr;
ex = xasprintf("%s/%s", vhost->dir, spath);
argv[0] = ex;
serialize_iri(iri, iribuf, sizeof(iribuf));
@ -307,15 +345,15 @@ launch_cgi(struct iri *iri, const char *spath, char *relpath,
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;
}

1
gmid.h
View File

@ -257,6 +257,7 @@ char *utf8_nth(char*, size_t);
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**);

23
iri.c
View File

@ -75,6 +75,13 @@ valid_pct_encoded(struct parser *p)
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)
{
@ -86,8 +93,7 @@ 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;
@ -437,3 +443,16 @@ serialize_iri(struct iri *i, char *buf, size_t len)
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;
}

View File

@ -69,6 +69,10 @@ quit() {
wait || true
}
count() {
wc -l | xargs
}
# usage: eq a b errmsg
# if a and b aren't equal strings, exit with errmsg
eq() {
@ -152,7 +156,7 @@ echo OK GET / with custom lang
check "should be running"
# finally try with CGI scripts
# try with CGI scripts
config '' 'cgi "*"'
checkconf
restart
@ -179,6 +183,13 @@ get /bigfile > bigfile
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"'