about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2022-02-19 11:55:06 +0100
committerbptato <nincsnevem662@gmail.com>2022-02-19 11:58:09 +0100
commit7fd9de65e4acfdbb71b284353043c19e2f152acd (patch)
tree2cb988ec79503197597ee493830600573e47748f
parent8efeab3d8770d0e5beaaa872a161d18b90d67658 (diff)
downloadchawan-7fd9de65e4acfdbb71b284353043c19e2f152acd.tar.gz
Fix not being able to load local files with ?, #, etc
-rw-r--r--src/client.nim10
-rw-r--r--src/types/url.nim6
-rw-r--r--src/utils/twtstr.nim8
3 files changed, 19 insertions, 5 deletions
diff --git a/src/client.nim b/src/client.nim
index 3ee26609..66cd0c41 100644
--- a/src/client.nim
+++ b/src/client.nim
@@ -143,11 +143,17 @@ proc loadUrl(client: Client, url: string, ctype = "") =
   if firstparse.issome:
     client.gotoUrl(url, none(ClickAction), none(Url), true, true, ctype)
   else:
+    let cdir = parseUrl("file://" & getCurrentDir() & DirSep)
     try:
-      let cdir = parseUrl("file://" & getCurrentDir() & DirSep)
+      # attempt to load local file
       client.gotoUrl(url, none(ClickAction), cdir, true, true, ctype)
     except LoadError:
-      client.gotoUrl("http://" & url, none(ClickAction), none(Url), true, true, ctype)
+      try:
+        # attempt to load local file (this time percent encoded)
+        client.gotoUrl(percentEncode(url, LocalPathPercentEncodeSet), none(ClickAction), cdir, true, true, ctype)
+      except LoadError:
+        # attempt to load remote page
+        client.gotoUrl("http://" & url, none(ClickAction), none(Url), true, true, ctype)
 
 proc reloadPage(client: Client) =
   client.gotoUrl(client.buffer.location, none(ClickAction), none(Url), true, false, client.buffer.contenttype)
diff --git a/src/types/url.nim b/src/types/url.nim
index d4c8b91c..447dafc8 100644
--- a/src/types/url.nim
+++ b/src/types/url.nim
@@ -1,4 +1,4 @@
-#See https://url.spec.whatwg.org/#url-parsing.
+# See https://url.spec.whatwg.org/#url-parsing.
 import strutils
 import tables
 import options
@@ -698,12 +698,12 @@ proc basicParseUrl*(input: string, base = none(Url), url: var Url = Url(), overr
           state = FRAGMENT_STATE
       elif has:
         #TODO If c is not a URL code point and not U+0025 (%), validation error.
-        #TOOD If c is U+0025 (%) and remaining does not start with two ASCII hex digits, validation error.
+        #TODO If c is U+0025 (%) and remaining does not start with two ASCII hex digits, validation error.
         buffer &= c
     of FRAGMENT_STATE:
       if has:
         #TODO If c is not a URL code point and not U+0025 (%), validation error.
-        #TOOD If c is U+0025 (%) and remaining does not start with two ASCII hex digits, validation error.
+        #TODO If c is U+0025 (%) and remaining does not start with two ASCII hex digits, validation error.
         url.fragment.get.percentEncode(c, FragmentPercentEncodeSet)
     inc pointer
   return url.some
diff --git a/src/utils/twtstr.nim b/src/utils/twtstr.nim
index 6f324f49..df8cfa6e 100644
--- a/src/utils/twtstr.nim
+++ b/src/utils/twtstr.nim
@@ -411,6 +411,11 @@ const PathPercentEncodeSet* = (QueryPercentEncodeSet + {'?', '`', '{', '}'})
 const UserInfoPercentEncodeSet* = (PathPercentEncodeSet + {'/', ':', ';', '=', '@', '['..'^', '|'})
 const ComponentPercentEncodeSet* = (UserInfoPercentEncodeSet + {'$'..'&', '+', ','})
 const ApplicationXWWWFormUrlEncodedSet* = (ComponentPercentEncodeSet + {'!', '\''..')', '~'})
+# used by client
+when defined(windows) or defined(OS2) or defined(DOS):
+  const LocalPathPercentEncodeSet* = (QueryPercentEncodeSet + {'?', ':'})
+else:
+  const LocalPathPercentEncodeSet* = (QueryPercentEncodeSet + {'?', ':', '\\'})
 
 proc percentEncode*(append: var string, c: char, set: set[char], spaceAsPlus = false) {.inline.} =
   if spaceAsPlus and c == ' ':
@@ -428,6 +433,9 @@ proc percentEncode*(append: var string, s: string, set: set[char], spaceAsPlus =
 func percentEncode*(c: char, set: set[char]): string {.inline.} =
   result.percentEncode(c, set)
 
+func percentEncode*(s: string, set: set[char]): string =
+  result.percentEncode(s, set)
+
 func percentDecode*(input: string): string =
   var i = 0
   while i < input.len: