Skip to content

Commit 22bdcb2

Browse files
authored
Merge pull request #66298 from mikeash/fix-nserror-description-memory-leak-5.9
[5.9][Runtime] Fix memory leak in -[__SwiftNativeNSError description] for large error values.
2 parents 3a87a21 + 9ef470e commit 22bdcb2

File tree

2 files changed

+19
-2
lines changed

2 files changed

+19
-2
lines changed

stdlib/public/runtime/ErrorObject.mm

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,13 +103,16 @@ - (void)dealloc {
103103
- (id /* NSString */)description {
104104
auto error = (const SwiftError *)self;
105105
auto value = error->getValue();
106+
auto type = error->type;
106107

107108
// Copy the value, since it will be consumed by getDescription.
108109
ValueBuffer copyBuf;
109-
auto copy = error->type->allocateBufferIn(&copyBuf);
110+
auto copy = type->allocateBufferIn(&copyBuf);
110111
error->type->vw_initializeWithCopy(copy, const_cast<OpaqueValue *>(value));
111112

112-
return getDescription(copy, error->type);
113+
auto description = getDescription(copy, type);
114+
type->deallocateBufferIn(&copyBuf);
115+
return description;
113116
}
114117

115118
- (NSInteger)code {

test/stdlib/ErrorBridged.swift

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -863,6 +863,11 @@ struct SwiftError2: Error, CustomStringConvertible {
863863
var description: String
864864
}
865865

866+
struct SwiftErrorLarge: Error, CustomStringConvertible {
867+
var description: String
868+
var makeItLarge = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
869+
}
870+
866871
ErrorBridgingTests.test("Swift Error description memory management") {
867872
func checkDescription() {
868873
// Generate a non-small, non-constant NSString bridged to String.
@@ -883,6 +888,15 @@ ErrorBridgingTests.test("Swift Error description memory management") {
883888
expectEqual(str, bridgedError.description)
884889
}
885890
}
891+
892+
// Make sure large structs also work.
893+
let largeError = SwiftErrorLarge(description: str)
894+
let largeBridgedError = largeError as NSError
895+
for _ in 0 ..< 10 {
896+
autoreleasepool {
897+
expectEqual(str, largeBridgedError.description)
898+
}
899+
}
886900
}
887901

888902
if #available(SwiftStdlib 5.3, *) {

0 commit comments

Comments
 (0)