Skip to content

Improve CborStreamReader Logic to Handle Nesting and End-of-Buffer Corner Cases #3956

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: cbor-protocol
Choose a base branch
from

Conversation

muhammad-othman
Copy link
Member

Description

This PR updates the CborStreamReader streaming logic to correctly handle scenarios where the buffer ends just after an item was read, particularly when working with nested containers.

Previously, the streaming CBOR reader could incorrectly signal completion when the current buffer segment ended but nested containers were still open. This caused issues with large or segmented CBOR payloads where container boundaries did not align with buffer boundaries.

  • Avoids prematurely treating PeekState() == Finished as a final read state when there are still open containers in the nesting stack.
  • Ensures containers are only closed when the corresponding EndArray or EndMap is explicitly read when end-of-current-buffer-part scenarios.

Motivation and Context

DOTNET-8252

Testing

  • DRY_RUN-08c395ab-328f-4d34-8928-282cecedfd90
  • Added unit tests to cover when the buffer ends close to the end of containers.

Screenshots (if appropriate)

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

Checklist

  • My code follows the code style of this project
  • My change requires a change to the documentation
  • I have updated the documentation accordingly
  • I have read the README document
  • I have added tests to cover my changes
  • All new and existing tests passed

License

  • I confirm that this pull request can be released under the Apache 2 license

@@ -106,13 +106,6 @@ private void RefillBuffer(int bytesToSkip = 0)
// Update the total size of valid data in our buffer.
_currentChunkSize = leftoverBytesCount + bytesReadFromStream;

// Check for a malformed stream: if we have leftovers but the stream is empty,
// it means the CBOR data was truncated.
if (bytesReadFromStream == 0 && leftoverBytesCount > 0)
Copy link
Member Author

Choose a reason for hiding this comment

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

This check isn't valid anymore since the current logic does call RefillBuffer multiple times to make sure we are really at the end of the stream not just the current buffer, so we will fall back to the outer ExecuteRead to catch when a stream is ending with an incomplete CBOR data item.

@@ -139,7 +132,7 @@ private T ExecuteRead<T>(Func<CborReader, T> readOperation)
{
return readOperation(_internalCborReader);
}
catch (CborContentException ex)
catch (Exception ex) when (ex is InvalidOperationException || ex is CborContentException)
Copy link
Member Author

Choose a reason for hiding this comment

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

Catching InvalidOperationException to account when CBOR reader assumes that we are reading a different type because of how the current buffer ends.

@muhammad-othman muhammad-othman force-pushed the muhamoth/DOTNET-8252-CBOR-stream-chunking-edge-case branch from 4454815 to 3e75c30 Compare August 13, 2025 19:41
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.

1 participant