summary refs log tree commit diff stats
path: root/lib/pure/includes/decode_helpers.nim
diff options
context:
space:
mode:
authorMiran <narimiran@disroot.org>2020-07-17 10:59:53 +0200
committerGitHub <noreply@github.com>2020-07-17 10:59:53 +0200
commitc62513049cd7dcbd5b339c2078856a31c498b4aa (patch)
tree9f44f58f5d4d83f159922e6f03994f0f6cea4310 /lib/pure/includes/decode_helpers.nim
parent1355b461aa70cd1e17b2f07085aa6c97cb54283f (diff)
downloadNim-c62513049cd7dcbd5b339c2078856a31c498b4aa.tar.gz
fix #14082, don't crash on incorrectly formatted input (#14977) [backport]
* fix #14082, don't crash on incorrectly formatted input

* address code review

* remove duplication
Diffstat (limited to 'lib/pure/includes/decode_helpers.nim')
-rw-r--r--lib/pure/includes/decode_helpers.nim24
1 files changed, 24 insertions, 0 deletions
diff --git a/lib/pure/includes/decode_helpers.nim b/lib/pure/includes/decode_helpers.nim
new file mode 100644
index 000000000..74fe37d07
--- /dev/null
+++ b/lib/pure/includes/decode_helpers.nim
@@ -0,0 +1,24 @@
+# Include file that implements 'decodePercent' and friends. Do not import it!
+
+proc handleHexChar(c: char, x: var int, f: var bool) {.inline.} =
+  case c
+  of '0'..'9': x = (x shl 4) or (ord(c) - ord('0'))
+  of 'a'..'f': x = (x shl 4) or (ord(c) - ord('a') + 10)
+  of 'A'..'F': x = (x shl 4) or (ord(c) - ord('A') + 10)
+  else: f = true
+
+proc decodePercent(s: string, i: var int): char =
+  ## Converts `%xx` hexadecimal to the charracter with ordinal number `xx`.
+  ##
+  ## If `xx` is not a valid hexadecimal value, it is left intact: only the
+  ## leading `%` is returned as-is, and `xx` characters will be processed in the
+  ## next step (e.g. in `uri.decodeUrl`) as regular characters.
+  result = '%'
+  if i+2 < s.len:
+    var x = 0
+    var failed = false
+    handleHexChar(s[i+1], x, failed)
+    handleHexChar(s[i+2], x, failed)
+    if not failed:
+      result = chr(x)
+      inc(i, 2)