base64: use url encoding with updated api

Ensure that the URL alphabet for base64 is used with the urlencode
functions (urlencode, urlencode_buffer, urlencode_temp and
urlencode_new) are used. Add a new test.
This commit is contained in:
Koni Marti
2024-11-24 23:25:55 +01:00
committed by Christoffer Lerno
parent 8d03aafe72
commit 3f7f7a0aa7
2 changed files with 51 additions and 24 deletions

View File

@@ -20,59 +20,55 @@ fn char[]! decode_buffer(char[] code, char[] buffer)
return buffer[:std_decoder.decode(code, buffer)!];
}
fn String encode(char[] code, Allocator allocator)
fn String! encode(char[] code, Allocator allocator)
{
@check_coder(std_encoder);
char[] data = allocator::alloc_array(allocator, char, std_encoder.encode_len(code.len));
std_encoder.encode(code, data)!!;
return (String)data;
return (String)data[:std_encoder.encode(code, data)!];
}
fn char[]! decode(char[] code, Allocator allocator)
{
@check_coder(std_decoder);
char[] data = allocator::alloc_array(allocator, char, std_decoder.decode_len(code.len))!;
std_decoder.decode(code, data)!;
return data;
return data[:std_decoder.decode(code, data)!];
}
fn String encode_new(char[] code) @inline => encode(code, allocator::heap());
fn String encode_temp(char[] code) @inline => encode(code, allocator::temp());
fn String! encode_new(char[] code) @inline => encode(code, allocator::heap());
fn String! encode_temp(char[] code) @inline => encode(code, allocator::temp());
fn char[]! decode_new(char[] code) @inline => decode(code, allocator::heap());
fn char[]! decode_temp(char[] code) @inline => decode(code, allocator::temp());
fn String urlencode(char[] code, Allocator allocator)
fn String! urlencode(char[] code, Allocator allocator)
{
@check_coder(url_encoder);
@check_coder(url_encoder, URL_ALPHABET);
char[] data = allocator::alloc_array(allocator, char, url_encoder.encode_len(code.len));
url_encoder.encode(code, data)!!;
return (String)data;
return (String)data[:url_encoder.encode(code, data)!];
}
fn char[]! urldecode(char[] code, Allocator allocator)
{
@check_coder(url_decoder);
@check_coder(url_decoder, URL_ALPHABET);
char[] data = allocator::alloc_array(allocator, char, url_decoder.decode_len(code.len))!;
url_decoder.decode(code, data)!;
return data;
return data[:url_decoder.decode(code, data)!];
}
fn String! urlencode_buffer(char[] code, char[] buffer)
{
@check_coder(url_encoder);
return (String)buffer[:std_encoder.encode(code, buffer)!];
@check_coder(url_encoder, URL_ALPHABET);
return (String)buffer[:url_encoder.encode(code, buffer)!];
}
fn char[]! urldecode_buffer(char[] code, char[] buffer)
{
@check_coder(url_decoder);
@check_coder(url_decoder, URL_ALPHABET);
return buffer[:url_decoder.decode(code, buffer)!];
}
fn String! urlencode_new(char[] code) @inline => urlencode(code, allocator::heap());
fn String! urlencode_temp(char[] code) @inline => urlencode(code, allocator::temp());
fn char[]! urldecode_new(char[] code) @inline => decode(code, allocator::heap());
fn char[]! urldecode_temp(char[] code) @inline => decode(code, allocator::temp());
fn char[]! urldecode_new(char[] code) @inline => urldecode(code, allocator::heap());
fn char[]! urldecode_temp(char[] code) @inline => urldecode(code, allocator::temp());
const MASK @private = 0b111111;
@@ -347,8 +343,8 @@ tlocal Base64Decoder std_decoder @local;
tlocal Base64Decoder url_decoder @local;
macro @check_coder(#coder) @local
macro @check_coder(#coder, alphabet = STD_ALPHABET) @local
{
if (#coder.alphabet) return;
#coder.init(STD_ALPHABET, '=')!!;
}
if (#coder.alphabet == alphabet) return;
#coder.init(alphabet, '=')!!;
}

View File

@@ -31,7 +31,7 @@ fn void encode()
char[64] buf;
b.encode(tc.in, buf[:n])!;
assert(buf[:n] == tc.out);
assert(base64::encode_temp(tc.in) == tc.out);
assert(base64::encode_temp(tc.in)! == tc.out);
};
}
}
@@ -105,3 +105,34 @@ fn void decode_nopadding()
assert(buf[:nn] == tc.out);
}
}
fn void! urlencode() {
TestCase[] tcases = {
{ x"14fb9c03d97e", "FPucA9l-"},
};
@pool()
{
usz n;
char[] got;
char[64] buf;
foreach (t : tcases)
{
Base64Encoder enc;
enc.init(base64::URL_ALPHABET)!;
n = enc.encode(t.in, buf[..])!;
assert (buf[:n] == t.out, "got: %s, want: %s", (String)buf[:n], (String)t.out);
got = base64::urlencode_temp(t.in)!;
assert (got == t.out, "got: %s, want: %s", got, (String)t.out);
Base64Decoder dec;
dec.init(base64::URL_ALPHABET)!;
n = dec.decode(t.out, buf[..])!;
assert (buf[:n] == t.in, "got: %s, want: %s", (String)buf[:n], (String)t.in);
got = base64::urldecode_temp(t.out)!;
assert (got == t.in, "got: %s, want: %s", got, (String)t.in);
}
};
}