From 26908a5a40fda6c221abffe86388881ed3605cc5 Mon Sep 17 00:00:00 2001
From: noriaki watanabe <nabeyang@gmail.com>
Date: Sat, 19 Oct 2024 00:50:52 +0900
Subject: [PATCH] Fixed an infinite loop caused by force casting NSError to
 CocoaError. (#5115)

(cherry picked from commit bf7369a3909583c82f36b901917a92ea0d639a9f)
---
 Sources/Foundation/NSError.swift   | 4 +++-
 Tests/Foundation/TestNSError.swift | 6 ++++++
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/Sources/Foundation/NSError.swift b/Sources/Foundation/NSError.swift
index af7fe0e54d..dc25698ffe 100644
--- a/Sources/Foundation/NSError.swift
+++ b/Sources/Foundation/NSError.swift
@@ -704,7 +704,9 @@ extension CocoaError: _ObjectiveCBridgeable {
     }
 
     public static func _forceBridgeFromObjectiveC(_ x: NSError, result: inout CocoaError?) {
-        result = _unconditionallyBridgeFromObjectiveC(x)
+        if !_conditionallyBridgeFromObjectiveC(x, result: &result) {
+            fatalError("Unable to bridge \(NSError.self) to \(self)")
+        }
     }
 
     public static func _conditionallyBridgeFromObjectiveC(_ x: NSError, result: inout CocoaError?) -> Bool {
diff --git a/Tests/Foundation/TestNSError.swift b/Tests/Foundation/TestNSError.swift
index d597fb0a99..5521895d3a 100644
--- a/Tests/Foundation/TestNSError.swift
+++ b/Tests/Foundation/TestNSError.swift
@@ -222,4 +222,10 @@ class TestCocoaError: XCTestCase {
         XCTAssertNotNil(e.underlying as? POSIXError)
         XCTAssertEqual(e.underlying as? POSIXError, POSIXError.init(.EACCES))
     }
+
+    func test_forceCast() {
+        let nsError = NSError(domain: NSCocoaErrorDomain, code: CocoaError.coderInvalidValue.rawValue)
+        let error = nsError as! CocoaError
+        XCTAssertEqual(error.errorCode, CocoaError.coderInvalidValue.rawValue)
+    }
 }