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
This commit is contained in:
Miran 2020-07-17 10:59:53 +02:00 • committed by GitHub
commit c62513049c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 42 additions and 42 deletions

View file

@ -47,6 +47,8 @@
import std/private/since
import strutils, parseutils, base64
include includes/decode_helpers
type
Url* = distinct string
@ -90,6 +92,7 @@ proc decodeUrl*(s: string, decodePlus = true): string =
## This means that any ``%xx`` (where ``xx`` denotes a hexadecimal
## value) are converted to the character with ordinal number ``xx``,
## and every other character is carried over.
## If ``xx`` is not a valid hexadecimal value, it is left intact.
##
## As a special rule, when the value of ``decodePlus`` is true, ``+``
## characters are converted to a space.
@ -101,12 +104,7 @@ proc decodeUrl*(s: string, decodePlus = true): string =
assert decodeUrl("https%3A%2F%2Fnim-lang.org%2Fthis+is+a+test") == "https://nim-lang.org/this is a test"
assert decodeUrl("https%3A%2F%2Fnim-lang.org%2Fthis%20is%20a%20test",
false) == "https://nim-lang.org/this is a test"
proc handleHexChar(c: char, x: var int) {.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: assert(false)
assert decodeUrl("abc%xyz") == "abc%xyz"
result = newString(s.len)
var i = 0
@ -114,11 +112,7 @@ proc decodeUrl*(s: string, decodePlus = true): string =
while i < s.len:
case s[i]
of '%':
var x = 0
handleHexChar(s[i+1], x)
handleHexChar(s[i+2], x)
inc(i, 2)
result[j] = chr(x)
result[j] = decodePercent(s, i)
of '+':
if decodePlus:
result[j] = ' '