Clear service decoders on oversized frames
ci / test (push) Waiting to run
ci / fuzz-smoke (push) Waiting to run
ci / windows-client (push) Waiting to run
ci / package-release (linux-x86_64, ubuntu-latest) (push) Waiting to run
ci / package-release (macos-aarch64, macos-14) (push) Waiting to run
ci / package-release (macos-x86_64, macos-13) (push) Waiting to run
ci / package-release (windows-x86_64, windows-latest) (push) Waiting to run
ci / publish-gitea-release (push) Blocked by required conditions
ci / remote-bench (push) Waiting to run

This commit is contained in:
DuProcess
2026-07-12 23:37:47 -04:00
parent fbedd54eaa
commit e67e06ebb5
2 changed files with 34 additions and 0 deletions
+21
View File
@@ -32,6 +32,7 @@ impl FrameDecoder {
}
let len = u32::from_be_bytes(self.buf[..4].try_into().unwrap()) as usize;
if len > FRAME_MAX_LEN {
self.buf.clear();
bail!("exec protocol frame too large: {len} bytes");
}
if self.buf.len() < 4 + len {
@@ -69,3 +70,23 @@ fn encode_frame(payload: &[u8]) -> Result<Vec<u8>> {
out.extend_from_slice(payload);
Ok(out)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn oversized_frame_clears_decoder_state() {
let mut decoder = FrameDecoder::default();
let too_large = ((FRAME_MAX_LEN + 1) as u32).to_be_bytes();
assert!(decoder.push(&too_large).is_err());
let valid = encode_response(&ExecResponse::Exit { code: Some(0) }).unwrap();
let frames = decoder.push(&valid).unwrap();
assert_eq!(frames.len(), 1);
assert_eq!(
decode_response(&frames[0]).unwrap(),
ExecResponse::Exit { code: Some(0) }
);
}
}
+13
View File
@@ -123,6 +123,7 @@ impl FrameDecoder {
}
let len = u32::from_be_bytes(self.buf[..4].try_into().unwrap()) as usize;
if len > FRAME_MAX_LEN {
self.buf.clear();
bail!("file protocol frame too large: {len} bytes");
}
if self.buf.len() < 4 + len {
@@ -288,6 +289,18 @@ mod tests {
assert_eq!(frames.len(), 1);
}
#[test]
fn oversized_frame_clears_decoder_state() {
let mut decoder = FrameDecoder::default();
let too_large = ((FRAME_MAX_LEN + 1) as u32).to_be_bytes();
assert!(decoder.push(&too_large).is_err());
let valid = encode_response(&FileResponse::Ok).unwrap();
let frames = decoder.push(&valid).unwrap();
assert_eq!(frames.len(), 1);
assert_eq!(decode_response(&frames[0]).unwrap(), FileResponse::Ok);
}
#[test]
fn copy_endpoint_parses_scp_style_but_not_windows_drive() {
assert_eq!(