diff options
author | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-09-25 14:10:50 +0300 |
---|---|---|
committer | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-09-25 14:10:50 +0300 |
commit | 5c44f8354238d436734e12d3af44cc0c211d2fe2 (patch) | |
tree | b7786524eb93348f17197ea2267095a5111978b1 /src | |
parent | fcbd43ab3a362611d6a548aae0a1e9741502ee2e (diff) |
Canonical URL form decodes colons in paths
The handling of colons (a reserved character used in the URL scheme and authority) was left ambiguous in the canonical form.
Diffstat (limited to 'src')
-rw-r--r-- | src/gmutil.c | 15 |
1 files changed, 14 insertions, 1 deletions
diff --git a/src/gmutil.c b/src/gmutil.c index d87de8f6..1d361875 100644 --- a/src/gmutil.c +++ b/src/gmutil.c | |||
@@ -620,7 +620,20 @@ const iString *canonicalUrl_String(const iString *d) { | |||
620 | - all non-reserved characters decoded (i.e., it's an IRI) | 620 | - all non-reserved characters decoded (i.e., it's an IRI) |
621 | - expect for spaces, which are always `%20` | 621 | - expect for spaces, which are always `%20` |
622 | This means a canonical URL can be used on a gemtext link line without modifications. */ | 622 | This means a canonical URL can be used on a gemtext link line without modifications. */ |
623 | iString *canon = maybeUrlDecodeExclude_String(d, "%/?:;#&= "); | 623 | iString *canon = NULL; |
624 | iUrl parts; | ||
625 | init_Url(&parts, d); | ||
626 | /* Colons are in decoded form in the URL path. */ | ||
627 | if (iStrStrN(parts.path.start, "%3A", size_Range(&parts.path)) || | ||
628 | iStrStrN(parts.path.start, "%3a", size_Range(&parts.path))) { | ||
629 | /* This is done separately to avoid the copy if %3A is not present; it's rare. */ | ||
630 | canon = copy_String(d); | ||
631 | urlDecodePath_String(canon); | ||
632 | urlDecodeExclude_String(d, "%/?:;#&= "); /* decode everything else in all parts */ | ||
633 | } | ||
634 | else { | ||
635 | canon = maybeUrlDecodeExclude_String(d, "%/?:;#&= "); | ||
636 | } | ||
624 | /* `canon` may now be NULL if nothing was decoded. */ | 637 | /* `canon` may now be NULL if nothing was decoded. */ |
625 | if (indexOfCStr_String(canon ? canon : d, " ") != iInvalidPos || | 638 | if (indexOfCStr_String(canon ? canon : d, " ") != iInvalidPos || |
626 | indexOfCStr_String(canon ? canon : d, "\n") != iInvalidPos) { | 639 | indexOfCStr_String(canon ? canon : d, "\n") != iInvalidPos) { |