aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXavier Del Campo Romero <xavi.dcr@tutanota.com>2023-11-12 00:14:05 +0100
committerXavier Del Campo Romero <xavi.dcr@tutanota.com>2023-11-12 01:29:54 +0100
commit9ac68fd76c43523ea3aa3bcc4f9fef0ac2cee830 (patch)
tree066cec43512bfd3234b30b403b20c55c1336508a
parent957ac188e57cbb16db183fbd0fc87b09fea8e20c (diff)
http: Make http_decode_url return int
So far, it was not possible callers to distinguish between decoding errors, as caused by ill-formed input, from fatal errors.
-rw-r--r--http.c74
-rw-r--r--include/libweb/http.h2
2 files changed, 43 insertions, 33 deletions
diff --git a/http.c b/http.c
index 42f5181..0184c65 100644
--- a/http.c
+++ b/http.c
@@ -133,7 +133,7 @@ static int parse_arg(struct ctx *const c, const char *const arg,
int ret = -1;
struct http_arg a = {0}, *args = NULL;
const char *sep = memchr(arg, '=', n);
- char *enckey = NULL, *encvalue = NULL;
+ char *enckey = NULL, *encvalue = NULL, *deckey = NULL, *decvalue = NULL;
if (!sep)
{
@@ -170,25 +170,25 @@ static int parse_arg(struct ctx *const c, const char *const arg,
__func__, strerror(errno));
goto end;
}
-
/* URL parameters use '+' for whitespace, rather than %20. */
- a = (const struct http_arg)
+ else if ((ret = http_decode_url(enckey, true, &deckey)))
{
- .key = http_decode_url(enckey, true),
- .value = http_decode_url(encvalue, true)
- };
-
- if (!a.key)
- {
- fprintf(stderr, "%s: http_decode_url key failed\n", __func__);
+ fprintf(stderr, "%s: http_decode_url enckey failed\n", __func__);
goto end;
}
- else if (!a.value)
+ else if ((ret = http_decode_url(encvalue, true, &decvalue)))
{
- fprintf(stderr, "%s: http_decode_url value failed\n", __func__);
+ fprintf(stderr, "%s: http_decode_url encvalue failed\n", __func__);
goto end;
}
- else if (!(args = realloc(c->args, (c->n_args + 1) * sizeof *args)))
+
+ a = (const struct http_arg)
+ {
+ .key = deckey,
+ .value = decvalue
+ };
+
+ if (!(args = realloc(c->args, (c->n_args + 1) * sizeof *args)))
{
fprintf(stderr, "%s: realloc(3): %s\n", __func__, strerror(errno));
goto end;
@@ -200,7 +200,11 @@ static int parse_arg(struct ctx *const c, const char *const arg,
end:
if (ret)
+ {
arg_free(&a);
+ free(deckey);
+ free(decvalue);
+ }
free(enckey);
free(encvalue);
@@ -321,7 +325,7 @@ static int parse_resource(struct ctx *const c, const char *const enc_res)
fprintf(stderr, "%s: strndup(3): %s\n", __func__, strerror(errno));
goto end;
}
- else if (!(resource = http_decode_url(trimmed_encres, false)))
+ else if ((ret = http_decode_url(trimmed_encres, false, &resource)))
{
fprintf(stderr, "%s: http_decode_url failed\n", __func__);
goto end;
@@ -1968,31 +1972,32 @@ failure:
return NULL;
}
-char *http_decode_url(const char *url, const bool spaces)
+int http_decode_url(const char *url, const bool spaces, char **out)
{
- char *ret = NULL;
+ int ret = -1;
+ char *str = NULL;
size_t n = 0;
while (*url)
{
- char *const r = realloc(ret, n + 1);
+ char *const r = realloc(str, n + 1);
if (!r)
{
fprintf(stderr, "%s: realloc(3) loop: %s\n",
__func__, strerror(errno));
- goto failure;
+ goto end;
}
- ret = r;
+ str = r;
if (spaces && *url == '+')
{
- ret[n++] = ' ';
+ str[n++] = ' ';
url++;
}
else if (*url != '%')
- ret[n++] = *url++;
+ str[n++] = *url++;
else if (*(url + 1) && *(url + 2))
{
const char buf[sizeof "00"] = {*(url + 1), *(url + 2)};
@@ -2002,32 +2007,37 @@ char *http_decode_url(const char *url, const bool spaces)
if (*endptr)
{
fprintf(stderr, "%s: invalid number %s\n", __func__, buf);
- goto failure;
+ ret = 1;
+ goto end;
}
url += 3;
- ret[n++] = res;
+ str[n++] = res;
}
else
{
fprintf(stderr, "%s: unterminated %%\n", __func__);
- goto failure;
+ ret = 1;
+ goto end;
}
}
- char *const r = realloc(ret, n + 1);
+ char *const r = realloc(str, n + 1);
if (!r)
{
fprintf(stderr, "%s: realloc(3) end: %s\n", __func__, strerror(errno));
- goto failure;
+ goto end;
}
- ret = r;
- ret[n] = '\0';
- return ret;
+ str = r;
+ str[n] = '\0';
+ *out = str;
+ ret = 0;
-failure:
- free(ret);
- return NULL;
+end:
+ if (ret)
+ free(str);
+
+ return ret;
}
diff --git a/include/libweb/http.h b/include/libweb/http.h
index 68ffb9a..80030fb 100644
--- a/include/libweb/http.h
+++ b/include/libweb/http.h
@@ -105,6 +105,6 @@ int http_response_add_header(struct http_response *r, const char *header,
const char *value);
char *http_cookie_create(const char *key, const char *value);
char *http_encode_url(const char *url);
-char *http_decode_url(const char *url, bool spaces);
+int http_decode_url(const char *url, bool spaces, char **out);
#endif /* HTTP_H */