Reject malformed base64 in MCP and segmask decoders

Found while testing crates/mcp/src/base64.rs:20 (base64_decode)

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
NetterSilver
2026-10-29 12:42:30 +00:00
co-authored by Claude Haiku 5.5
parent 77c0a6adfa
commit bdf535e954
2 changed files with 30 additions and 2 deletions
+13 -1
View File
@@ -104,9 +104,14 @@ fn base64_encode(bytes: &[u8]) -> String {
fn base64_decode(s: &str) -> Option<Vec<u8>> {
let mut out = Vec::with_capacity(s.len() / 4 * 3);
let (mut acc, mut bits) = (0u32, 0u32);
let mut padded = false;
for c in s.bytes().filter(|c| !c.is_ascii_whitespace()) {
if c == b'=' {
break;
padded = true;
continue;
}
if padded {
return None;
}
let v = B64.iter().position(|b| *b == c)? as u32;
acc = (acc << 6) | v;
@@ -117,6 +122,9 @@ fn base64_decode(s: &str) -> Option<Vec<u8>> {
acc &= (1 << bits) - 1;
}
}
if bits == 6 {
return None;
}
Some(out)
}
@@ -133,6 +141,10 @@ mod tests {
assert_eq!(base64_encode(b"Man"), "TWFu");
assert_eq!(base64_encode(b"Ma"), "TWE=");
assert!(base64_decode("TW!u").is_none());
assert!(base64_decode("Z").is_none());
assert!(base64_decode("Zm9vY").is_none());
assert!(base64_decode("Zg==!!!not-base64").is_none());
assert_eq!(base64_decode("Zg==\n").unwrap(), b"f");
}
#[test]
+17 -1
View File
@@ -20,9 +20,14 @@ pub fn base64_encode(bytes: &[u8]) -> String {
pub fn base64_decode(text: &str) -> Option<Vec<u8>> {
let mut out = Vec::with_capacity(text.len() / 4 * 3);
let (mut acc, mut bits) = (0u32, 0u32);
let mut padded = false;
for c in text.bytes().filter(|c| !c.is_ascii_whitespace()) {
if c == b'=' {
break;
padded = true;
continue;
}
if padded {
return None;
}
let v = ALPHABET.iter().position(|&a| a == c)? as u32;
acc = (acc << 6) | v;
@@ -33,6 +38,9 @@ pub fn base64_decode(text: &str) -> Option<Vec<u8>> {
acc &= (1 << bits) - 1;
}
}
if bits == 6 {
return None;
}
Some(out)
}
@@ -57,4 +65,12 @@ mod tests {
}
assert!(base64_decode("not base64!").is_none());
}
#[test]
fn rejects_malformed() {
assert!(base64_decode("Z").is_none());
assert!(base64_decode("Zm9vY").is_none());
assert!(base64_decode("Zg==!!!not-base64").is_none());
assert_eq!(base64_decode("Zg==\n").unwrap(), b"f");
}
}