From 9b94c1dda9cb83d1c7c109a7d66c1b57ff26912e Mon Sep 17 00:00:00 2001 From: Koni Marti Date: Sat, 23 Nov 2024 17:43:54 +0100 Subject: [PATCH] fix: base64 decoding Fix the base64 decoding. If there's an 'A' character in the encoded text, the base64 decode function returns an INVALID_PADDING error. The reason lies in the way Base64Decoder.init tries to find a suitable invalid character. Fix this by defining the invalid character as 0xff (which is already the case for a decoding without padding). This error has not been caught by the test harness, because no test contains an 'A' character in the the encoded text yet. Add a new test. --- lib/std/encoding/base64.c3 | 22 ++++------------------ test/unit/stdlib/encoding/base64.c3 | 7 ++++++- 2 files changed, 10 insertions(+), 19 deletions(-) diff --git a/lib/std/encoding/base64.c3 b/lib/std/encoding/base64.c3 index e4ee8389b..306e36554 100644 --- a/lib/std/encoding/base64.c3 +++ b/lib/std/encoding/base64.c3 @@ -124,27 +124,13 @@ fn void! Base64Decoder.init(&self, String alphabet, int padding = '=') check_alphabet(alphabet, padding)!; *self = { .padding = padding, .alphabet = alphabet }; - bool[256] checked; + self.invalid = 0xff; + self.reverse[..] = self.invalid; + foreach (i, c : alphabet) { - checked[c] = true; self.reverse[c] = (char)i; } - if (padding < 0) - { - self.invalid = 255; - return; - } - // Find a character for invalid neither in the alphabet nor equal to the padding. - char pad = (char)padding; - foreach (i, ok : checked) - { - if (!ok && (char)i != pad) - { - self.invalid = (char)i; - break; - } - } } <* @@ -285,4 +271,4 @@ fn void! check_alphabet(String alphabet, int padding) @local if (checked[c]) return Base64Error.DUPLICATE_IN_ALPHABET?; checked[c] = true; } -} \ No newline at end of file +} diff --git a/test/unit/stdlib/encoding/base64.c3 b/test/unit/stdlib/encoding/base64.c3 index e8607341e..ec994b3b8 100644 --- a/test/unit/stdlib/encoding/base64.c3 +++ b/test/unit/stdlib/encoding/base64.c3 @@ -19,6 +19,7 @@ fn void encode() { "foob", "Zm9vYg==" }, { "fooba", "Zm9vYmE=" }, { "foobar", "Zm9vYmFy" }, + { "test", "dGVzdA==" }, }; foreach (tc : tcases) { @@ -41,6 +42,7 @@ fn void encode_nopadding() { "foob", "Zm9vYg" }, { "fooba", "Zm9vYmE" }, { "foobar", "Zm9vYmFy" }, + { "test", "dGVzdA" }, }; foreach (tc : tcases) { @@ -63,6 +65,8 @@ fn void decode() { "Zm9vYg==", "foob" }, { "Zm9vYmE=", "fooba" }, { "Zm9vYmFy", "foobar" }, + { "Zm9vYmFy", "foobar" }, + { "dGVzdA==", "test" }, }; foreach (tc : tcases) { @@ -85,6 +89,7 @@ fn void decode_nopadding() { "Zm9vYg", "foob" }, { "Zm9vYmE", "fooba" }, { "Zm9vYmFy", "foobar" }, + { "dGVzdA", "test" }, }; foreach (tc : tcases) { @@ -95,4 +100,4 @@ fn void decode_nopadding() usz nn = b.decode(tc.in, buf[:n])!; assert(buf[:nn] == tc.out); } -} \ No newline at end of file +}