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
Fix crash: Create ByteBuffer Slice from ByteBuffer Slice after 16MB #1813
Conversation
f3a98d6
to
5037dfc
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While this patch is great, it does a bit too much reaching into the ByteBuffer internals for my comfort. Can we rewrite it to avoid using UInt24 and avoid touching the _slice directly?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you so much @fabianfett , this is really fantastic work!!
Tests/NIOTests/ByteBufferTest.swift
Outdated
// 16MiB after the originating backing storage. | ||
|
||
// create a buffer with (16MiB - 1byte) + 2 bytes = 16MiB + 1 byte | ||
let inputBufferLength = Int(_UInt24.max) + 2 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just hardcode the value here. The _
means that _UInt24
is meant to be private. So let inputBufferLength = 1 << 24 + 1
or similar.
let finalSlice = remainingSlice.readSlice(length: finalSliceLength) | ||
XCTAssertEqual(finalSlice?.storageCapacity, 1) | ||
XCTAssertEqual(finalSlice?._slice.lowerBound, 0) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we should additionally assert
- that the slices/values read have the correct content (
1
s,2
s, and3
s or so as suggested above) - that the underlying storage has indeed changed. There's a (test only) property called
buffer.storageIdentifier
or so which stays the same if nothing got reallocated/copied and changes if it has
5037dfc
to
ff3956e
Compare
ff3956e
to
5c8e24c
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One minor cleanup and then I think this is good.
Co-authored-by: Cory Benfield <lukasa@apple.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, nice patch!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome, I left one suggestion which you may want to apply. We prefer lines <= 120 (IIRC) and Array<UInt8>(...)
over [UInt8](...)
for the constructors.
Co-authored-by: Johannes Weiss <johannesweiss@apple.com>
Fixes an issue that could lead to an assert in Debug mode and to undefined behavior in Release mode.
Motivation:
ByteBuffer
slice from an originatingByteBuffer
slice where the newByteBuffer
slice starts more than 16MiB into the underlyingByteBuffer
storage, the newByteBuffer
slice will get a new 0 based storage.Modifications:
ByteBuffer
slice which is more than 16MiB into its originating storage.Result:
ByteBuffer
slices from slices after the 16MiB threshold.