fix(recv_buffer): skip already-written bytes on overlapping writes#5900
fix(recv_buffer): skip already-written bytes on overlapping writes#5900MarkedMuichiro wants to merge 8 commits intomicrosoft:mainfrom
Conversation
guhetier
left a comment
There was a problem hiding this comment.
The product code update looks good, thanks for the contribution!
The tests need some changes to actually validate the feature.
Thanks for the detailed feedback! I'm glad to help. Here's the approach I took in addressing your comments: For the test issue: added a Also removed the redundant |
guhetier
left a comment
There was a problem hiding this comment.
Looks good to me one the dead code is removed.
Done. Thank you. |
|
Thanks for the contribution! I'll merge this once the CI succeeds. |
|
@guhetier Any idea why some test cases are failing? |
|
There is a regression (or at least change of behavior) in CI runners. We just checked in a workaround for the "WinPrerelease" ones. I am investigating the linux one. If you rebase, more should succeed, I don't think this is related to your PR in any way but we try to limit churn until we solve it. |
| // Write [0, 20) with pattern A (offset-based). | ||
| // Then write [10, 30) with 0xff in the overlap region [10, 20). | ||
| // Verify bytes [0, 20) still contain pattern A, and [20, 30) contain | ||
| // the new data from the second write. |
There was a problem hiding this comment.
Could you please include tests for the following scenarios:
- 3 ranges that have 2 overlaps between them
- 3 non-overlapping contiguous ranges
- 4 ranges - 3 with 2 range overlaps and one range that is non-contiguous with the others
There was a problem hiding this comment.
Added OverlapWriteThreeRangesTwoOverlaps and OverlapWriteThreeContiguousNonOverlapping per your request. Thanks for the suggestion!
QuicRecvBufferCopyIntoChunks previously overwrote already-received data when a new write overlapped with existing WrittenRanges. Fix by walking existing WrittenRanges before calling QuicRangeAddRange to identify and copy only the new (gap) bytes. ReadLength update moved out of QuicRecvBufferCopyIntoChunks into QuicRecvBufferWrite after the range is committed. Fixes overlapping CRYPTO and STREAM frame data corruption. Adds unit tests covering partial overlap, front overlap, exact duplicate, and multiple gap scenarios across all buffer modes.
- Restore existing comment on quota check block - Factor gap-walking copy logic into QuicRecvBufferWriteNewBytes helper - Update ReadLength comment to refer only to present state of code
- Factor gap-walking copy logic into QuicRecvBufferWriteNewBytes helper - Move ReadLength update out of QuicRecvBufferCopyIntoChunks into QuicRecvBufferWrite - Update comment to refer only to present state of code
…ectnessAdd WriteCustom helper to allow tests to provide explicit buffer data. Add ValidateBufferCustom to validate against an expected array. Rewrite overlap tests to write 0xff sentinel values in the overlap region of the second write, verifying the originally written bytes survive and are not overwritten.
Update comment. Co-authored-by: Guillaume Hetier <hetier.guillaume@gmail.com>
Remove dead code. Co-authored-by: Guillaume Hetier <hetier.guillaume@gmail.com>
99d16a6 to
d104bd3
Compare
Thanks for the update and for investigating the CI issue. Rebased onto main. |
| // If this subrange ends before our current copy position, skip it. | ||
| // | ||
| if (Sub->Low + Sub->Count <= CopyOffset) { | ||
| continue; |
There was a problem hiding this comment.
We should trace this as a datapath event since there is no other tracking of this overlap or an indication of this occurring. A new type of DataPath event traced here seems appropriate, but I will leave it to @guhetier to comment on specifics.
Fixes #5819
Problem
QuicRecvBufferCopyIntoChunks previously overwrote already-received data
when a new write partially overlapped with existing WrittenRanges.
QuicRangeAddRange correctly returns WrittenRangesUpdated=TRUE for partial
overlaps, causing CopyIntoChunks to write the full incoming buffer
including bytes at already-received offsets.
Fix
Walk existing WrittenRanges before calling QuicRangeAddRange to identify
gap regions within the incoming write window. Call
QuicRecvBufferCopyIntoChunks once per gap, copying only new bytes.
ReadLength update moved out of QuicRecvBufferCopyIntoChunks into
QuicRecvBufferWrite after the range is committed.
This fixes the issue for both CRYPTO and STREAM frame processing.
Testing
Added four parameterized unit tests across all four buffer modes:
@guhetier