diff --git a/cmp/src/ref.c b/cmp/src/ref.c index 26ecc21..eccf470 100644 --- a/cmp/src/ref.c +++ b/cmp/src/ref.c @@ -34,6 +34,7 @@ static const u8 values[256] = { void SUFFIX(encode_seq, COMPILER) (u8 const* restrict input, usize len, u8* restrict output) { + len -= len % 3; for (; len; len -= 3) { *output++ = symbols[(u8)(input[0] >> 2)]; *output++ = symbols[(u8)(input[0] << 4 | input[1] >> 4)]; @@ -46,6 +47,7 @@ void SUFFIX(encode_seq, COMPILER) void SUFFIX(encode_par, COMPILER) (u8 const* restrict input, usize len, u8* restrict output) { + len -= len % 3; for (; len; len -= 3) { u64 x = (u64)input[0] << 16 | (u64)input[1] << 8 | input[2]; output[0] = symbols[(u8)(x >> 18)]; @@ -60,6 +62,7 @@ void SUFFIX(encode_par, COMPILER) i32 SUFFIX(decode_seq, COMPILER) (u8 const* restrict input, usize len, u8* restrict output) { + len -= len % 4; for (; len; len -= 4) { if (values[input[0]] >= 64) return -1; if (values[input[1]] >= 64) return -1; @@ -76,6 +79,7 @@ i32 SUFFIX(decode_seq, COMPILER) i32 SUFFIX(decode_par, COMPILER) (u8 const* restrict input, usize len, u8* restrict output) { + len -= len % 4; for (; len; len -= 4) { if (values[input[0]] & values[input[1]] & values[input[2]] & values[input[3]] & 0xc0) { diff --git a/cmp/tests/lib.rs b/cmp/tests/lib.rs index 2c00b79..3304df0 100644 --- a/cmp/tests/lib.rs +++ b/cmp/tests/lib.rs @@ -54,3 +54,39 @@ fn difference() { assert_eq!(BASE64.decode(x).unwrap(), vec![0, 0]); assert_eq!(BASE64_STANDARD.decode(x).err().unwrap(), InvalidByte(2, b'=')); } + +#[test] +fn partial_block() { + let encode = &[ + (b"f" as &[u8], b"" as &[u8]), + (b"fo" as &[u8], b"" as &[u8]), + (b"foob" as &[u8], b"Zm9v" as &[u8]), + (b"fooba" as &[u8], b"Zm9v" as &[u8]), + ]; + for &(ref i, ref o) in encode { + let mut r = vec![0u8; o.len()]; + cmp::base64_encode_seq_gcc(i, &mut r); + assert_eq!(&r, o); + } + for &(ref i, ref o) in encode { + let mut r = vec![0u8; o.len()]; + cmp::base64_encode_par_gcc(i, &mut r); + assert_eq!(&r, o); + } + let decode = &[ + (b"Z" as &[u8], b"" as &[u8]), + (b"Zm9" as &[u8], b"" as &[u8]), + (b"Zm9vY" as &[u8], b"foo" as &[u8]), + (b"Zm9vYmF" as &[u8], b"foo" as &[u8]), + ]; + for &(ref i, ref o) in decode { + let mut r = vec![0u8; o.len()]; + assert_eq!(cmp::base64_decode_seq_gcc(i, &mut r), Ok(())); + assert_eq!(&r, o); + } + for &(ref i, ref o) in decode { + let mut r = vec![0u8; o.len()]; + assert_eq!(cmp::base64_decode_par_gcc(i, &mut r), Ok(())); + assert_eq!(&r, o); + } +}