=> 5e31f66313e2dc15fb9e75395504feb0992c3feb
[1mdiff --git a/src/app.c b/src/app.c[m [1mindex 3b4c24f0..73cc35ee 100644[m [1m--- a/src/app.c[m [1m+++ b/src/app.c[m [36m@@ -2791,12 +2791,6 @@[m [miBool handleCommand_App(const char *cmd) {[m setRedirectCount_DocumentWidget(doc, redirectCount);[m setOrigin_DocumentWidget(doc, origin);[m showCollapsed_Widget(findWidget_App("document.progress"), iFalse);[m [31m- if (prefs_App()->decodeUserVisibleURLs) {[m [31m- urlDecodePath_String(url);[m [31m- }[m [31m- else {[m [31m- urlEncodePath_String(url);[m [31m- } [m setUrlFlags_DocumentWidget(doc, url,[m isHistory ? useCachedContentIfAvailable_DocumentWidgetSetUrlFlag : 0);[m /* Optionally, jump to a text in the document. This will only work if the document[m [1mdiff --git a/src/gmrequest.c b/src/gmrequest.c[m [1mindex a9c5919d..c23e8499 100644[m [1m--- a/src/gmrequest.c[m [1m+++ b/src/gmrequest.c[m [36m@@ -585,8 +585,10 @@[m [mvoid setUrl_GmRequest(iGmRequest *d, const iString *url) {[m /* TODO: Gemini spec allows UTF-8 encoded URLs, but still need to percent-encode non-ASCII[m characters? Could be a server-side issue, e.g., if they're using a URL parser meant for[m the web. */[m [31m- urlEncodePath_String(&d->url);[m [31m- urlEncodeSpaces_String(&d->url);[m [32m+[m[32m /* Encode everything except already-percent encoded characters. */[m [32m+[m[32m iString *enc = urlEncodeExclude_String(&d->url, "%" URL_RESERVED_CHARS);[m [32m+[m[32m set_String(&d->url, enc);[m [32m+[m[32m delete_String(enc);[m d->identity = identityForUrl_GmCerts(d->certs, &d->url);[m }[m [m [1mdiff --git a/src/gmutil.c b/src/gmutil.c[m [1mindex 79462e41..98e4d4d6 100644[m [1m--- a/src/gmutil.c[m [1m+++ b/src/gmutil.c[m [36m@@ -330,6 +330,28 @@[m [mvoid urlEncodePath_String(iString *d) {[m delete_String(encoded);[m }[m [m [32m+[m[32mvoid urlEncodeQuery_String(iString *d) {[m [32m+[m[32m iUrl url;[m [32m+[m[32m init_Url(&url, d);[m [32m+[m[32m if (isEmpty_Range(&url.query)) {[m [32m+[m[32m return;[m [32m+[m[32m }[m [32m+[m[32m iString encoded;[m [32m+[m[32m init_String(&encoded);[m [32m+[m[32m appendRange_String(&encoded, (iRangecc){ constBegin_String(d), url.query.start });[m [32m+[m[32m iString query;[m [32m+[m[32m url.query.start++; /* omit the question mark */[m [32m+[m[32m initRange_String(&query, url.query);[m [32m+[m[32m iString *encQuery = urlEncode_String(&query); /* fully encoded */[m [32m+[m[32m appendCStr_String(&encoded, "?");[m [32m+[m[32m append_String(&encoded, encQuery);[m[41m [m [32m+[m[32m delete_String(encQuery);[m [32m+[m[32m deinit_String(&query);[m [32m+[m[32m appendRange_String(&encoded, (iRangecc){ url.query.end, constEnd_String(d) });[m [32m+[m[32m set_String(d, &encoded);[m [32m+[m[32m deinit_String(&encoded);[m [32m+[m[32m}[m [32m+[m iBool isKnownScheme_Rangecc(iRangecc scheme) {[m if (isKnownUrlScheme_Rangecc(scheme)) {[m return iTrue;[m [36m@@ -667,20 +689,20 @@[m [mconst iString *canonicalUrl_String(const iString *d) {[m iString *canon = NULL;[m iUrl parts;[m init_Url(&parts, d);[m [31m- /* Colons are in decoded form in the URL path. */[m [32m+[m[32m /* Colons (0x3a) are in decoded form in the URL path. */[m if (iStrStrN(parts.path.start, "%3A", size_Range(&parts.path)) ||[m iStrStrN(parts.path.start, "%3a", size_Range(&parts.path))) {[m /* This is done separately to avoid the copy if %3A is not present; it's rare. */[m canon = copy_String(d);[m urlDecodePath_String(canon);[m [31m- iString *dec = maybeUrlDecodeExclude_String(canon, "%/?:;#&+= "); /* decode everything else in all parts */[m [32m+[m[32m iString *dec = maybeUrlDecodeExclude_String(canon, "% " URL_RESERVED_CHARS); /* decode everything else in all parts */[m if (dec) {[m set_String(canon, dec);[m delete_String(dec);[m }[m }[m else {[m [31m- canon = maybeUrlDecodeExclude_String(d, "%/?:;#&+= ");[m [32m+[m[32m canon = maybeUrlDecodeExclude_String(d, "% " URL_RESERVED_CHARS);[m }[m /* `canon` may now be NULL if nothing was decoded. */[m if (indexOfCStr_String(canon ? canon : d, " ") != iInvalidPos ||[m [36m@@ -689,7 +711,7 @@[m [mconst iString *canonicalUrl_String(const iString *d) {[m canon = copy_String(d);[m }[m urlEncodeSpaces_String(canon);[m [31m- }[m [32m+[m[32m }[m[41m [m return canon ? collect_String(canon) : d;[m }[m [m [1mdiff --git a/src/gmutil.h b/src/gmutil.h[m [1mindex 6d337eeb..15bb7b2e 100644[m [1m--- a/src/gmutil.h[m [1m+++ b/src/gmutil.h[m [36m@@ -100,6 +100,7 @@[m [miRegExp * newGemtextLink_RegExp (void);[m [m #define GEMINI_DEFAULT_PORT ((uint16_t) 1965)[m #define GEMINI_DEFAULT_PORT_CSTR "1965"[m [32m+[m[32m#define URL_RESERVED_CHARS ":/?#[]@!$&'()*+,;=" /* RFC 3986 */[m [m struct Impl_Url {[m iRangecc scheme;[m [36m@@ -131,6 +132,7 @@[m [mconst iString * urlFragmentStripped_String(const iString *);[m const iString * urlQueryStripped_String (const iString *);[m void urlDecodePath_String (iString *);[m void urlEncodePath_String (iString *);[m [32m+[m[32mvoid urlEncodeQuery_String (iString *);[m iString * makeFileUrl_String (const iString *localFilePath);[m const char * makeFileUrl_CStr (const char *localFilePath);[m iString * localFilePathFromUrl_String(const iString *);[m [1mdiff --git a/src/ui/inputwidget.c b/src/ui/inputwidget.c[m [1mindex b94e0c27..24983d69 100644[m [1m--- a/src/ui/inputwidget.c[m [1m+++ b/src/ui/inputwidget.c[m [36m@@ -1100,9 +1100,15 @@[m [mstatic void updateBuffered_InputWidget_(iInputWidget *d) {[m void setText_InputWidget(iInputWidget *d, const iString *text) {[m if (!d) return;[m if (d->inFlags & isUrl_InputWidgetFlag) {[m [31m- /* If user wants URLs encoded, also Punycode the domain. */[m [31m- if (!prefs_App()->decodeUserVisibleURLs) {[m [32m+[m[32m if (prefs_App()->decodeUserVisibleURLs) {[m iString *enc = collect_String(copy_String(text));[m [32m+[m[32m urlDecodePath_String(enc);[m [32m+[m[32m text = enc;[m [32m+[m[32m }[m [32m+[m[32m else {[m [32m+[m[32m /* The user wants URLs encoded, also Punycode the domain. */[m [32m+[m[32m iString *enc = collect_String(copy_String(text));[m [32m+[m[32m urlEncodePath_String(enc);[m /* Prevent address bar spoofing (mentioned as IDN homograph attack in[m https://github.com/skyjake/lagrange/issues/73) */[m punyEncodeUrlHost_String(enc);[m
text/gemini; charset=utf-8
This content has been proxied by September (ba2dc).