Skip to content

Commit a8f2f95

Browse files
authored
Merge pull request #28804 from DougGregor/error-cast-overrelease
[Dynamic casting] Fix overrelease on unsuccessful cast to an Error type.
2 parents 439d99c + 23cc079 commit a8f2f95

File tree

2 files changed

+20
-1
lines changed

2 files changed

+20
-1
lines changed

stdlib/public/runtime/Casting.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2382,7 +2382,10 @@ static bool swift_dynamicCastImpl(OpaqueValue *dest, OpaqueValue *src,
23822382
#if SWIFT_OBJC_INTEROP
23832383
// If the source is an NSError, and the target is a bridgeable
23842384
// Error, try to bridge.
2385-
if (tryDynamicCastNSErrorToValue(dest, src, srcType, targetType, flags)) {
2385+
auto innerFlags = flags - DynamicCastFlags::Unconditional
2386+
- DynamicCastFlags::DestroyOnFailure;
2387+
if (tryDynamicCastNSErrorToValue(dest, src, srcType, targetType,
2388+
innerFlags)) {
23862389
return true;
23872390
}
23882391
#endif

test/stdlib/ErrorBridged.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -820,4 +820,20 @@ ErrorBridgingTests.test("CFError-to-Error casts") {
820820
}
821821
}
822822

823+
enum MyError: Error {
824+
case someThing
825+
}
826+
827+
ErrorBridgingTests.test("SR-9207 crash in failed cast to NSError") {
828+
829+
if #available(macOS 9999, iOS 9999, tvOS 9999, watchOS 9999, *) {
830+
let error = MyError.someThing
831+
let foundationError = error as NSError
832+
833+
if let urlError = foundationError as? URLError {
834+
expectUnreachable()
835+
}
836+
}
837+
}
838+
823839
runAllTests()

0 commit comments

Comments
 (0)