commit 2ac684a4e1b8a971689edc8c5543832dd1b9db0e from: Omar Polo via: Thomas Adam date: Sat Sep 03 23:12:56 2022 UTC gotwebd: percent-decode the received query string ok stsp@ commit - a6fd182ad357eeabb88cffe83d799b412e4cdab7 commit + 2ac684a4e1b8a971689edc8c5543832dd1b9db0e blob - c8b7537c3a1a4cb682e0c7af9a311a4f6d09e6c4 blob + 976d5eac6eb1b6d018e514bb87a9afbb78454dc1 --- gotwebd/gotweb.c +++ gotwebd/gotweb.c @@ -1,6 +1,7 @@ /* * Copyright (c) 2016, 2019, 2020-2022 Tracey Emery * Copyright (c) 2015 Mike Larkin + * Copyright (c) 2014 Reyk Floeter * Copyright (c) 2013 David Gwynne * Copyright (c) 2013 Florian Obser * @@ -23,6 +24,7 @@ #include #include +#include #include #include #include @@ -421,13 +423,62 @@ err: return error; } +/* + * Adapted from usr.sbin/httpd/httpd.c url_decode. + */ static const struct got_error * +gotweb_urldecode(char *url) +{ + char *p, *q; + char hex[3]; + unsigned long x; + + hex[2] = '\0'; + p = q = url; + + while (*p != '\0') { + switch (*p) { + case '%': + /* Encoding character is followed by two hex chars */ + if (!isxdigit((unsigned char)p[1]) || + !isxdigit((unsigned char)p[2]) || + (p[1] == '0' && p[2] == '0')) + return got_error(GOT_ERR_BAD_QUERYSTRING); + + hex[0] = p[1]; + hex[1] = p[2]; + + /* + * We don't have to validate "hex" because it is + * guaranteed to include two hex chars followed by nul. + */ + x = strtoul(hex, NULL, 16); + *q = (char)x; + p += 2; + break; + default: + *q = *p; + break; + } + p++; + q++; + } + *q = '\0'; + + return NULL; +} + +static const struct got_error * gotweb_assign_querystring(struct querystring **qs, char *key, char *value) { const struct got_error *error = NULL; const char *errstr; int a_cnt, el_cnt; + error = gotweb_urldecode(value); + if (error) + return error; + for (el_cnt = 0; el_cnt < QSELEM__MAX; el_cnt++) { if (strcmp(key, querystring_keys[el_cnt].name) != 0) continue; blob - ab13ceafe2a0043b913454118e0c81bab18d3ea1 blob + 32ded08f2703834a744542900c736972cdb203ad --- include/got_error.h +++ include/got_error.h @@ -175,6 +175,7 @@ #define GOT_ERR_VERIFY_TAG_SIGNATURE 155 #define GOT_ERR_SIGNING_TAG 156 #define GOT_ERR_COMMIT_REDUNDANT_AUTHOR 157 +#define GOT_ERR_BAD_QUERYSTRING 158 struct got_error { int code; blob - bee9789607409d33d238a9d098ae9924da0f1344 blob + bd09c98f60e847f0f4694f3931012a07cce40577 --- lib/error.c +++ lib/error.c @@ -230,6 +230,7 @@ static const struct got_error got_errors[] = { { GOT_ERR_SIGNING_TAG, "unable to sign tag" }, { GOT_ERR_COMMIT_REDUNDANT_AUTHOR, "specified author is equal to the " "default one"}, + { GOT_ERR_BAD_QUERYSTRING, "invalid query string" }, }; static struct got_custom_error {