aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog4
-rw-r--r--iri.c34
-rw-r--r--regress/iri_test.c8
3 files changed, 40 insertions, 6 deletions
diff --git a/ChangeLog b/ChangeLog
index d4ae6db..ad55d54 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
diff --git a/iri.c b/iri.c
index efdeb11..8501d9a 100644
--- a/iri.c
+++ b/iri.c
@@ -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",