Skip to content

Commit

Permalink
base64: use url encoding with updated api
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
konimarti authored and lerno committed Nov 25, 2024
1 parent 8d03aaf commit 3f7f7a0
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 24 deletions.
42 changes: 19 additions & 23 deletions lib/std/encoding/base64.c3
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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, '=')!!;
}
33 changes: 32 additions & 1 deletion test/unit/stdlib/encoding/base64.c3
Original file line number Diff line number Diff line change
Expand Up @@ -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);
};
}
}
Expand Down Expand Up @@ -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);
}
};
}

0 comments on commit 3f7f7a0

Please sign in to comment.