gatewayd: strict status lines and chunk lines; no as casts (M4a review, findings 1 and 3)
A status line splits on single spaces only, and every chunk line must end in CRLF. The bounded `as` casts in http.rs, handshake.rs and proto's sha1.rs become try_from and from. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -14,24 +14,20 @@ const ALPHABET: &[u8; 64] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwx
|
||||
pub fn base64(bytes: &[u8]) -> String {
|
||||
// Standard alphabet (ALPHABET), "=" padding: each 3 bytes become 4 characters; a last group of
|
||||
// 1 or 2 bytes becomes 2 or 3 characters and 2 or 1 "=". No indexing that can go out of bounds.
|
||||
let sextet = |n: u32, shift: u32| -> char {
|
||||
let index = usize::try_from((n >> shift) & 0x3f).unwrap_or(0);
|
||||
char::from(ALPHABET.get(index).copied().unwrap_or(b'A'))
|
||||
};
|
||||
let mut out = String::new();
|
||||
for chunk in bytes.chunks(3) {
|
||||
let b0 = chunk.first().copied().unwrap_or(0);
|
||||
let b1 = chunk.get(1).copied().unwrap_or(0);
|
||||
let b2 = chunk.get(2).copied().unwrap_or(0);
|
||||
let n = ((b0 as u32) << 16) | ((b1 as u32) << 8) | (b2 as u32);
|
||||
out.push(ALPHABET[((n >> 18) & 0x3f) as usize] as char);
|
||||
out.push(ALPHABET[((n >> 12) & 0x3f) as usize] as char);
|
||||
out.push(if chunk.len() > 1 {
|
||||
ALPHABET[((n >> 6) & 0x3f) as usize] as char
|
||||
} else {
|
||||
'='
|
||||
});
|
||||
out.push(if chunk.len() > 2 {
|
||||
ALPHABET[(n & 0x3f) as usize] as char
|
||||
} else {
|
||||
'='
|
||||
});
|
||||
let n = (u32::from(b0) << 16) | (u32::from(b1) << 8) | u32::from(b2);
|
||||
out.push(sextet(n, 18));
|
||||
out.push(sextet(n, 12));
|
||||
out.push(if chunk.len() > 1 { sextet(n, 6) } else { '=' });
|
||||
out.push(if chunk.len() > 2 { sextet(n, 0) } else { '=' });
|
||||
}
|
||||
out
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user