mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[Runtime] Fix memory leak in -[__SwiftNativeNSError description] for large error values.
Balance the call to allocateBufferIn with a call to deallocateBufferIn. When an error value is small, the missing deallocateBufferIn doesn't do anything. But when the error value is a larger struct that doesn't fit inline, we need deallocateBufferIn to avoid leaking the allocation. rdar://109933822
This commit is contained in:
@@ -103,13 +103,16 @@ using namespace swift::hashable_support;
|
||||
- (id /* NSString */)description {
|
||||
auto error = (const SwiftError *)self;
|
||||
auto value = error->getValue();
|
||||
auto type = error->type;
|
||||
|
||||
// Copy the value, since it will be consumed by getDescription.
|
||||
ValueBuffer copyBuf;
|
||||
auto copy = error->type->allocateBufferIn(©Buf);
|
||||
auto copy = type->allocateBufferIn(©Buf);
|
||||
error->type->vw_initializeWithCopy(copy, const_cast<OpaqueValue *>(value));
|
||||
|
||||
return getDescription(copy, error->type);
|
||||
auto description = getDescription(copy, type);
|
||||
type->deallocateBufferIn(©Buf);
|
||||
return description;
|
||||
}
|
||||
|
||||
- (NSInteger)code {
|
||||
|
||||
@@ -863,6 +863,11 @@ struct SwiftError2: Error, CustomStringConvertible {
|
||||
var description: String
|
||||
}
|
||||
|
||||
struct SwiftErrorLarge: Error, CustomStringConvertible {
|
||||
var description: String
|
||||
var makeItLarge = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
|
||||
}
|
||||
|
||||
ErrorBridgingTests.test("Swift Error description memory management") {
|
||||
func checkDescription() {
|
||||
// Generate a non-small, non-constant NSString bridged to String.
|
||||
@@ -883,6 +888,15 @@ ErrorBridgingTests.test("Swift Error description memory management") {
|
||||
expectEqual(str, bridgedError.description)
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure large structs also work.
|
||||
let largeError = SwiftErrorLarge(description: str)
|
||||
let largeBridgedError = largeError as NSError
|
||||
for _ in 0 ..< 10 {
|
||||
autoreleasepool {
|
||||
expectEqual(str, largeBridgedError.description)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if #available(SwiftStdlib 5.3, *) {
|
||||
|
||||
Reference in New Issue
Block a user