diff options
author | Omar Polo <op@omarpolo.com> | 2021-02-05 14:31:53 +0000 |
---|---|---|
committer | Omar Polo <op@omarpolo.com> | 2021-02-05 14:31:53 +0000 |
commit | 8404ec301fed4f0bb5a3d1e7b5a2e184a93cc4e5 (patch) | |
tree | e13c781fb785af232191412b46354a5b229e530b | |
parent | 709f4c94471b5b910557420ab9bddb677c229100 (diff) |
don't %-decode the query
-rw-r--r-- | ChangeLog | 4 | ||||
-rw-r--r-- | iri.c | 34 | ||||
-rw-r--r-- | regress/iri_test.c | 8 |
3 files changed, 40 insertions, 6 deletions
@@ -1,3 +1,7 @@ +2021-02-05 Omar Polo <op@omarpolo.com> + + * iri.c (parse_query): don't %-decode the query part. This affects the value of QUERY_STRING for CGI scripts too, since that must be %-encoded and we're currently shipping it decoded. + 2021-02-04 Omar Polo <op@omarpolo.com> * gmid.c (main): reload configuration on SIGHUP, without disconnecting the clients @@ -46,12 +46,42 @@ sub_delimiters(int p) } static int +valid_pct_enc_string(char *s) +{ + if (*s != '%') + return 1; + + if (!isxdigit(s[1]) || !isxdigit(s[2])) + return 0; + + if (s[1] == '0' && s[2] == '0') + return 0; + + return 1; +} + +static int +valid_pct_encoded(struct parser *p) +{ + if (p->iri[0] != '%') + return 0; + + if (!valid_pct_enc_string(p->iri)) { + p->err = "illegal percent-encoding"; + return 0; + } + + p->iri += 2; + return 1; +} + +static int parse_pct_encoded(struct parser *p) { if (p->iri[0] != '%') return 0; - if (!isxdigit(p->iri[1]) || !isxdigit(p->iri[2])) { + if (!valid_pct_enc_string(p->iri)) { p->err = "illegal percent-encoding"; return 0; } @@ -259,7 +289,7 @@ parse_query(struct parser *p) || sub_delimiters(*p->iri) || *p->iri == '/' || *p->iri == '?' - || parse_pct_encoded(p) + || valid_pct_encoded(p) || valid_multibyte_utf8(p)) p->iri++; diff --git a/regress/iri_test.c b/regress/iri_test.c index a662e79..ba5fe4b 100644 --- a/regress/iri_test.c +++ b/regress/iri_test.c @@ -204,10 +204,10 @@ main(void) PASS, IRI("foo", "example.com", "", "foo/", "gne&foo", ""), "parse query strings"); - TEST("foo://example.com/foo/?gne%2F", - PASS, - IRI("foo", "example.com", "", "foo/", "gne/", ""), - "parse query strings"); + /* TEST("foo://example.com/foo/?gne%2F", */ + /* PASS, */ + /* IRI("foo", "example.com", "", "foo/", "gne/", ""), */ + /* "parse query strings"); */ /* fragment */ TEST("foo://bar.co/#foo", |