fix(core): reset reassembler slot on buffer overflow; drop tautological assert
This commit is contained in:
+18
-2
@@ -120,6 +120,10 @@ impl Reassembler {
|
|||||||
// record where this index's bytes live.
|
// record where this index's bytes live.
|
||||||
let start = self.buf.len();
|
let start = self.buf.len();
|
||||||
if self.buf.len().saturating_add(data.len()) > self.buf.capacity() {
|
if self.buf.len().saturating_add(data.len()) > self.buf.capacity() {
|
||||||
|
// No valid observation encodes to more than MAX_FRAME*2 bytes, so a
|
||||||
|
// fragment that cannot fit marks the stream as malformed: reset the
|
||||||
|
// slot rather than leaving it stuck holding an unreassemblable set.
|
||||||
|
self.reset_slot();
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
self.buf
|
self.buf
|
||||||
@@ -185,7 +189,7 @@ impl Reassembler {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::wire::{Frame, WireError};
|
use crate::wire::Frame;
|
||||||
use crate::{Payload, Topic};
|
use crate::{Payload, Topic};
|
||||||
use std::vec::Vec;
|
use std::vec::Vec;
|
||||||
|
|
||||||
@@ -450,10 +454,22 @@ mod tests {
|
|||||||
assert!(got, "chunk == 0 must return an error");
|
assert!(got, "chunk == 0 must return an error");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn buffer_overflow_resets_slot() {
|
||||||
|
let mut r = Reassembler::new();
|
||||||
|
// Two max-sized fragments fill the 3000-byte buffer.
|
||||||
|
assert!(r.feed([0xA; 16], 0, 64, &[0u8; 1500], 0).is_none());
|
||||||
|
assert!(r.feed([0xA; 16], 1, 64, &[0u8; 1500], 0).is_none());
|
||||||
|
assert_eq!(r.buf.len(), 3000);
|
||||||
|
// A third fragment overflows; the slot must reset, not stay stuck.
|
||||||
|
assert!(r.feed([0xA; 16], 2, 64, &[0u8; 1], 0).is_none());
|
||||||
|
assert!(r.buf.is_empty(), "overflow must reset the slot buffer");
|
||||||
|
assert!(r.id.is_none(), "overflow must clear the slot id");
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn decode_garbage_is_not_a_frame() {
|
fn decode_garbage_is_not_a_frame() {
|
||||||
// smoke check that wire decode of the module's dependency behaves
|
// smoke check that wire decode of the module's dependency behaves
|
||||||
assert!(Frame::decode(&[0xFFu8, 0xFF, 0xFF]).is_err());
|
assert!(Frame::decode(&[0xFFu8, 0xFF, 0xFF]).is_err());
|
||||||
assert!(WireError::Malformed == WireError::Malformed);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user