-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Reactivate "Performance improvements for Blob" #1167
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
Conversation
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.
@jberkel Just caught wind of this change and I think it should be reverted quickly. It introduces a serious security issue for folks accessing the bytes interface.
public init(bytes: [UInt8]) { | ||
self.bytes = bytes | ||
public var bytes: UnsafePointer<UInt8> { | ||
data.bytes.assumingMemoryBound(to: UInt8.self) |
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.
This is unfortunately undefined behavior and could lead to crashes. We should revert this.
|
||
public let bytes: [UInt8] | ||
public let data: NSData |
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.
I think these days NSData
is going to make things slower in Swift. If we want to make fundamental changes like this they should be benchmarked. I have some other repos with examples that use swift-benchmark
if that would help!
@jberkel Sorry for the fly-by! And much appreciation for your continual maintenance of this 😄 Just don't want folks to get bit by this potential issue in production. |
@jberkel I just pulled the 0.14.0 tag to prevent folks from taking this change for now, but please cut 0.14.1 when you have a chance to revert. |
@stephencelis Oh, hello. The PR this is based on sat around unchallenged for six years and now you're appearing here deus ex machina :) Could you explain a bit more, I don't see the security issue, let i8bufptr = UnsafeBufferPointer(start: bytes.assumingMemoryBound(to: UInt8.self), count: length) so I don't see why this would be less safe. |
Apple's documentation mentions that
However, And as far as I can tell, the elementary type |
@jberkel Again, sorry for the fly-by out of nowhere! Please let me take some time to try to flesh out my concerns. I'll start with the one that I think is the most pressing:
Hope these concerns are clear and make sense! I appreciate wanting to continually improve the library for its users, but I also want to make sure we don't ship something that could cause unintentional problems for them. |
It's only a dangling pointer once the func test_dangling_pointer() {
var unsafePointer: UnsafePointer<UInt8>? = nil
do {
var blob: Blob? = Blob(bytes: [42, 41, 40])
unsafePointer = blob!.bytes
blob = nil
}
XCTAssertEqual(unsafePointer?.pointee, 42)
} Interestingly, even compiled with "guard malloc" and run with "malloc scribble" this test passes. It looks like the memory isn't freed immediately. But yes, clearly some "shoot-in-the-foot" potential here.
That's a fair point, it should have been benchmarked. I'll try to do some benchmarking, more out of curiosity.
This is probably the weakest argument, as stated above I don't see how this behavior can be undefined according to the Swift memory model. This PR was rushed into the last release, which wasn't a good idea. On the other hand, it's been around for a few years and nobody challenged it, so I assumed it was ok to include. I'll do a new release soon, don't have much time now because I'm travelling. |
Sure, but APIs that return dangling pointers make it very easy for folks to make this mistake by holding onto the pointer and letting the data be deallocated. I think the job of a high-level library is to prevent folks from making these kinds of mistakes by not shipping interfaces that make it easy.
I'd like to be a little more cautious here as I don't see how we can guarantee it. We know that using unsafe interfaces can cause problems at runtime when used incorrectly. Might be worth asking the compiler engineers on the Swift forums if it is safe to use this API here and, if so, document the findings? |
#416