diff --git a/lib/encoding/base64/base64_test.ww b/lib/encoding/base64/base64_test.ww index cd0d9bce..61fb0ebb 100644 --- a/lib/encoding/base64/base64_test.ww +++ b/lib/encoding/base64/base64_test.ww @@ -117,15 +117,32 @@ fn inval_check(enc: *base64.encoding, encoded: str) void = { // ---- decodestr error cases ---- ref/hare/encoding/base64/base64.ha:525 // -// Wrong length, bad char, embedded / excess padding all → invalid. +// Table-driven (parallel-array idiom; tuple rows blocked by #111). Each +// row exercises one malformed class the hand-written validation in +// decodestr must reject. Cross-alphabet chars are covered separately by +// urlsafe_distinct(); Hare's all-padding-but-not-multiple-of-4 rows +// ("=", "===", "=====", base64.ha:527-531) collapse onto the length +// guard here, so this table pins the multiple-of-4 survivors of every +// class instead. @test fn decode_invalid() void = { - inval_check(&base64.std_encoding, "Zg"); // not a multiple of 4 - inval_check(&base64.std_encoding, "Z@=="); // '@' not in alphabet - inval_check(&base64.std_encoding, "===="); // all padding - inval_check(&base64.std_encoding, "Zg==Zg=="); // data after padding - inval_check(&base64.std_encoding, "Zm8=Zm8="); // data after padding - inval_check(&base64.std_encoding, "@Zg="); // bad leading char + let bad: [10]str = [ + "Z", // len % 4 == 1 (lone trailing char) + "Zg", // len % 4 == 2 + "Zm9", // len % 4 == 3 + "Z@==", // non-alphabet char in data region + "@Zg=", // bad leading char + "====", // all padding (no data) + "A===", // excess '=' (3 pads in the final quad) + "Z=g=", // '=' not in the trailing position + "Zg==Zg==", // data after padding (embedded '=') + "Zm8=Zm8=", // data after padding (embedded '=') + ]; + let i: i32 = 0; + for (i < len(bad)) { + inval_check(&base64.std_encoding, bad[i]); + i += 1; + }; }; // ---- size calc ---- ref/hare/encoding/base64/base64.ha:601