Summary
Found by Copilot during PR #33 review. Pre-existing issue in insert_segment overlap detection.
Problem
The fully_covered check in FlowDirection::insert_segment (src/reassembly/segment.rs:125-127) only tests if a single existing segment covers [new_start, new_end):
let fully_covered = trimmed_ranges
.iter()
.any(|&(es, ee)| es <= new_start && ee >= new_end);
When the new segment is fully covered by the union of multiple adjacent existing segments, fully_covered is false. The gap computation correctly produces an empty gaps vec, but the return logic (line 181-186) reports PartialOverlap instead of Duplicate.
Impact
segments_inserted stat inflated by 1 for each occurrence (caller counts PartialOverlap as inserted)
- No data corruption — no bytes are actually inserted
- Rare in practice — requires a new segment exactly spanning multiple existing segments with no gap
Fix
After the gap computation, check !had_gap && !has_conflict → return Duplicate instead of falling through to PartialOverlap:
return if !had_gap && has_conflict {
InsertResult::ConflictingOverlap
} else if !had_gap {
InsertResult::Duplicate // fully covered by union of segments
} else if truncated {
InsertResult::Truncated
} else {
InsertResult::PartialOverlap
};
Summary
Found by Copilot during PR #33 review. Pre-existing issue in
insert_segmentoverlap detection.Problem
The
fully_coveredcheck inFlowDirection::insert_segment(src/reassembly/segment.rs:125-127) only tests if a single existing segment covers[new_start, new_end):When the new segment is fully covered by the union of multiple adjacent existing segments,
fully_coveredis false. The gap computation correctly produces an emptygapsvec, but the return logic (line 181-186) reportsPartialOverlapinstead ofDuplicate.Impact
segments_insertedstat inflated by 1 for each occurrence (caller counts PartialOverlap as inserted)Fix
After the gap computation, check
!had_gap && !has_conflict→ returnDuplicateinstead of falling through toPartialOverlap: