fix: Fix uri encoding/decoding and add new tests
Some checks failed
test / test (push) Has been cancelled

This commit is contained in:
2025-10-27 19:08:18 +00:00
parent 56e3682237
commit e51116c2b2
2 changed files with 23 additions and 37 deletions

View File

@@ -109,7 +109,7 @@ pub fn parse_min_max(
do_parse_min_max(str, "", min, max, parse_fn) do_parse_min_max(str, "", min, max, parse_fn)
} }
pub fn do_parse_min_max( fn do_parse_min_max(
str: d, str: d,
acc: String, acc: String,
min: Int, min: Int,
@@ -403,14 +403,6 @@ pub fn parse_hex_digits(str, min, max) {
parse_min_max(str, min, max, parse_hex_digit) parse_min_max(str, min, max, parse_hex_digit)
} }
fn encoding_not_needed(i: Int) -> Bool {
// $-_.+!*'()
case i {
36 | 45 | 95 | 46 | 43 | 33 | 42 | 39 | 40 | 41 -> True
_ -> False
}
}
fn is_unreserved_char(i: Int) -> Bool { fn is_unreserved_char(i: Int) -> Bool {
case i { case i {
45 | 46 | 95 | 126 -> True 45 | 46 | 95 | 126 -> True
@@ -660,13 +652,13 @@ pub fn do_percent_encode(str: String) -> String {
fn encode_codepoint(codepoint: Int) -> String { fn encode_codepoint(codepoint: Int) -> String {
case codepoint <= 127 { case codepoint <= 127 {
True -> { True -> {
case is_unreserved_char(codepoint) || encoding_not_needed(codepoint) { case is_unreserved_char(codepoint) {
True -> { True -> {
let assert Ok(cpnt) = string.utf_codepoint(codepoint) let assert Ok(cpnt) = string.utf_codepoint(codepoint)
string.from_utf_codepoints([cpnt]) string.from_utf_codepoints([cpnt])
} }
False -> { False -> {
"%" <> int.to_base16(codepoint) "%" <> string.pad_start(int.to_base16(codepoint), 2, "0")
} }
} }
} }

View File

@@ -1146,37 +1146,31 @@ pub fn equivalence_tests() {
]) ])
} }
const percent_codec_fixtures = [ const percent_encode_examples = [
#(" ", "%20"), #("", ""),
#(",", "%2C"), #("%", "%25"),
#(";", "%3B"), #("%%", "%25%25"),
#(":", "%3A"), #(" \r\n\t\u{B}\f", "%20%0D%0A%09%0B%0C"),
#("!", "!"), #(
#("?", "%3F"), "-_.~0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ",
#("'", "'"), "-_.~0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ",
#("(", "("), ),
#(")", ")"), #("\u{0}", "%00"),
#("[", "%5B"), #("abc\u{00}def", "abc%00def"),
#("@", "%40"),
#("/", "%2F"),
#("\\", "%5C"),
#("&", "%26"), #("&", "%26"),
#("#", "%23"), #(
#("=", "%3D"), "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~",
#("~", "~"), "%21%22%23%24%25%26%27%28%29%2A%2B%2C-.%2F%3A%3B%3C%3D%3E%3F%40%5B%5C%5D%5E_%60%7B%7C%7D~",
#("ñ", "%C3%B1"), ),
#("-", "-"), #("“Aha”", "%E2%80%9CAha%E2%80%9D"),
#("_", "_"), #("\u{201C}Aha\u{201D}", "%E2%80%9CAha%E2%80%9D"),
#(".", "."), #("*+,=>/", "%2A%2B%2C%3D%3E%2F"),
#("*", "*"),
#("+", "+"),
#("100% great+fun", "100%25%20great+fun"),
] ]
pub fn percent_encode_tests() { pub fn percent_encode_tests() {
describe("percent encoding", [ describe("percent encoding", [
it("encoding", fn() { it("encoding", fn() {
percent_codec_fixtures percent_encode_examples
|> list.map(fn(t) { |> list.map(fn(t) {
let #(a, b) = t let #(a, b) = t
uri.percent_encode(a) uri.percent_encode(a)
@@ -1185,7 +1179,7 @@ pub fn percent_encode_tests() {
Nil Nil
}), }),
it("decoding", fn() { it("decoding", fn() {
percent_codec_fixtures percent_encode_examples
|> list.map(fn(t) { |> list.map(fn(t) {
let #(a, b) = t let #(a, b) = t
uri.percent_decode(b) uri.percent_decode(b)