Skip to content

Commit a2eaad3

Browse files
authored
Merge pull request #2686 from swiftwasm/release/5.4
[pull] swiftwasm-release/5.4 from release/5.4
2 parents e6855ea + 6e52b9a commit a2eaad3

File tree

1 file changed

+21
-2
lines changed

1 file changed

+21
-2
lines changed

stdlib/public/runtime/ErrorObject.mm

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -542,6 +542,26 @@ typedef SWIFT_CC(swift) NSDictionary *(*GetErrorDefaultUserInfoFunction)(
542542

543543
extern "C" const ProtocolDescriptor PROTOCOL_DESCR_SYM(s5Error);
544544

545+
static IMP
546+
getNSProxyLookupMethod() {
547+
Class NSProxyClass = objc_lookUpClass("NSProxy");
548+
return class_getMethodImplementation(NSProxyClass, @selector(methodSignatureForSelector:));
549+
}
550+
551+
// A safer alternative to calling `isKindOfClass:` directly.
552+
static bool
553+
isKindOfClass(HeapObject *object, Class cls) {
554+
IMP NSProxyLookupMethod = SWIFT_LAZY_CONSTANT(getNSProxyLookupMethod());
555+
// People sometimes fail to override `methodSignatureForSelector:` in their
556+
// NSProxy subclasses, which causes `isKindOfClass:` to crash. Avoid that...
557+
Class objectClass = object_getClass((id)object);
558+
IMP objectLookupMethod = class_getMethodImplementation(objectClass, @selector(methodSignatureForSelector:));
559+
if (objectLookupMethod == NSProxyLookupMethod) {
560+
return false;
561+
}
562+
return [reinterpret_cast<id>(object) isKindOfClass: cls];
563+
}
564+
545565
bool
546566
swift::tryDynamicCastNSErrorObjectToValue(HeapObject *object,
547567
OpaqueValue *dest,
@@ -550,8 +570,7 @@ typedef SWIFT_CC(swift) NSDictionary *(*GetErrorDefaultUserInfoFunction)(
550570
Class NSErrorClass = getNSErrorClass();
551571

552572
// The object must be an NSError subclass.
553-
if (isObjCTaggedPointerOrNull(object) ||
554-
![reinterpret_cast<id>(object) isKindOfClass: NSErrorClass])
573+
if (isObjCTaggedPointerOrNull(object) || !isKindOfClass(object, NSErrorClass))
555574
return false;
556575

557576
id srcInstance = reinterpret_cast<id>(object);

0 commit comments

Comments
 (0)