diff --git a/crates/format/src/lib.rs b/crates/format/src/lib.rs index d76453bee..f0ac3b452 100644 --- a/crates/format/src/lib.rs +++ b/crates/format/src/lib.rs @@ -694,17 +694,23 @@ pub fn base64_decode(s: &str) -> Option> { return None; } let mut out = Vec::with_capacity(clean.len() / 4 * 3); - for c in clean.chunks(4) { + let groups = clean.len() / 4; + for (i, c) in clean.chunks(4).enumerate() { let mut n = 0u32; let mut pad = 0; for &b in c { n <<= 6; if b == b'=' { pad += 1; + } else if pad > 0 { + return None; } else { n |= val(b)?; } } + if pad > 2 || (pad > 0 && i + 1 != groups) { + return None; + } out.push((n >> 16) as u8); if pad < 2 { out.push((n >> 8) as u8); @@ -782,4 +788,14 @@ mod tests { } assert_eq!(base64_encode(b"foobar"), "Zm9vYmFy"); } + + #[test] + fn base64_rejects_misplaced_padding() { + for s in ["====", "A===", "AA=A", "=AAA", "QQ==QUJD", "QUI=QUJD"] { + assert_eq!(base64_decode(s), None, "{s}"); + } + assert_eq!(base64_decode("QQ=="), Some(vec![0x41])); + assert_eq!(base64_decode("QUI="), Some(vec![0x41, 0x42])); + assert_eq!(base64_decode("QUJD"), Some(vec![0x41, 0x42, 0x43])); + } }