aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOmar Polo <op@omarpolo.com>2024-06-10 11:42:22 +0000
committerOmar Polo <op@omarpolo.com>2024-06-10 11:42:22 +0000
commit7f6c46ae1ea4288c371a85080ff67fc406980241 (patch)
tree84c3001c4906791370ec3c7a74e86a5f7a896eb3
parent3d06af043cdbb58d9ef31ad8f9e5a8f46660e79f (diff)
iri: don't error on a '..' component at the start of the path
I choose to out of paranoia, but the algorithm defined in RFC3986 allows for them. So, we should rather remove the leading '..' component and continue to handle the rest of the path. Fixes https://github.com/omar-polo/gmid/issues/12
-rw-r--r--iri.c8
-rw-r--r--regress/iri_test.c16
2 files changed, 14 insertions, 10 deletions
diff --git a/iri.c b/iri.c
index 38d526b..91bc9f6 100644
--- a/iri.c
+++ b/iri.c
@@ -260,11 +260,15 @@ path_clean(char *path)
} else if (q == path && p[0] == '.' && p[1] == '.' &&
(p[2] == '/' || p[2] == '\0')) {
/* ../ at the start of path */
- return 0;
+ p += 2;
+ if (*p == '/')
+ p++;
} else if (q == path && p[0] == '.' &&
(p[1] == '/' || p[1] == '\0')) {
/* ./ at the start of path */
- p += 2;
+ p++;
+ if (*p == '/')
+ p++;
} else if (p[0] == '/' && p[1] == '/') {
/* trim double slashes */
p++;
diff --git a/regress/iri_test.c b/regress/iri_test.c
index fa6d578..a0e7466 100644
--- a/regress/iri_test.c
+++ b/regress/iri_test.c
@@ -201,13 +201,13 @@ main(void)
IRI("gemini", "omarpolo.com", "", "", "", ""),
"parse paths with a trailing ..");
TEST("gemini://omarpolo.com/foo/../..",
- FAIL,
- empty,
- "reject paths that would escape the root");
+ PASS,
+ IRI("gemini", "omarpolo.com", "", "", "", ""),
+ "parse paths that would escape the root");
TEST("gemini://omarpolo.com/foo/../../",
- FAIL,
- empty,
- "reject paths that would escape the root")
+ PASS,
+ IRI("gemini", "omarpolo.com", "", "", "", ""),
+ "parse paths that would escape the root")
TEST("gemini://omarpolo.com/foo/../foo/../././/bar/baz/.././.././/",
PASS,
IRI("gemini", "omarpolo.com", "", "", "", ""),
@@ -271,8 +271,8 @@ main(void)
IRI("foo", "bar.com", "", "caffè+macchiato.gmi", "", ""),
"can decode");
TEST("foo://bar.com/foo%2F..%2F..",
- FAIL,
- empty,
+ PASS,
+ IRI("foo", "bar.com", "", "", "", ""),
"conversion and checking are done in the correct order");
TEST("foo://bar.com/foo%00?baz",
FAIL,