Skip to content

fix(recv_buffer): skip already-written bytes on overlapping writes#5900

Open
MarkedMuichiro wants to merge 8 commits intomicrosoft:mainfrom
MarkedMuichiro:fix/recv-buffer-overlap-copy
Open

fix(recv_buffer): skip already-written bytes on overlapping writes#5900
MarkedMuichiro wants to merge 8 commits intomicrosoft:mainfrom
MarkedMuichiro:fix/recv-buffer-overlap-copy

Conversation

@MarkedMuichiro
Copy link
Copy Markdown
Contributor

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:

  • OverlapWritePreservesExistingData: partial overlap at end
  • OverlapWriteAtFront: fill gap and overlap
  • OverlapWriteExactDuplicate: pure duplicate write
  • OverlapWriteMultipleGaps: swiss-cheese pattern covered by large write

@guhetier

@MarkedMuichiro MarkedMuichiro requested a review from a team as a code owner March 27, 2026 23:59
@MarkedMuichiro MarkedMuichiro requested a review from guhetier March 30, 2026 05:46
Copy link
Copy Markdown
Collaborator

@guhetier guhetier left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The product code update looks good, thanks for the contribution!
The tests need some changes to actually validate the feature.

@MarkedMuichiro
Copy link
Copy Markdown
Contributor Author

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 WriteCustom helper that accepts an explicit buffer, and a ValidateBufferCustom that validates against a provided expected array. The overlap tests now write 0xff sentinel values in the already-written regions of the second write. If the fix were broken and those bytes got overwritten, the sentinels would appear in the buffer and ValidateBufferCustom would catch the corruption immediately.

Also removed the redundant ValidateBuffer call you flagged — it was already handled by Read.

@MarkedMuichiro MarkedMuichiro requested a review from guhetier March 31, 2026 00:27
Copy link
Copy Markdown
Collaborator

@guhetier guhetier left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me one the dead code is removed.

@MarkedMuichiro
Copy link
Copy Markdown
Contributor Author

Looks good to me one the dead code is removed.

Done. Thank you.

guhetier
guhetier previously approved these changes Mar 31, 2026
@guhetier
Copy link
Copy Markdown
Collaborator

Thanks for the contribution! I'll merge this once the CI succeeds.

@MarkedMuichiro MarkedMuichiro requested a review from guhetier April 1, 2026 16:52
@MarkedMuichiro
Copy link
Copy Markdown
Contributor Author

@guhetier Any idea why some test cases are failing?

@guhetier
Copy link
Copy Markdown
Collaborator

guhetier commented Apr 3, 2026

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.
Copy link
Copy Markdown
Contributor

@sm-msft sm-msft Apr 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added OverlapWriteThreeRangesTwoOverlaps and OverlapWriteThreeContiguousNonOverlapping per your request. Thanks for the suggestion!

MarkedMuichiro and others added 7 commits April 6, 2026 23:20
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>
@MarkedMuichiro MarkedMuichiro force-pushed the fix/recv-buffer-overlap-copy branch from 99d16a6 to d104bd3 Compare April 6, 2026 23:20
@MarkedMuichiro
Copy link
Copy Markdown
Contributor Author

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.

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;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Overlapping CRYPTO frames overwrite previously received data

3 participants