Skip to content

Commit a5e6b85

Browse files
authored
Make sure SwiftObject doesn't crash when compared to tagged pointers (#83269)
Fixes rdar://152912840
1 parent 6416cd2 commit a5e6b85

File tree

2 files changed

+19
-1
lines changed

2 files changed

+19
-1
lines changed

stdlib/public/runtime/SwiftObject.mm

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -438,7 +438,13 @@ - (BOOL)isEqual:(id)other {
438438
// Legacy behavior: Don't proxy to Swift Hashable or Equatable
439439
return NO; // We know the ids are different
440440
}
441-
441+
if (isObjCTaggedPointer(other)) {
442+
// Swift class types cannot be tagged, and a Swift Equatable conformance
443+
// cannot validly be called for an object of a different type, so this can
444+
// only be incorrect if someone has an Equatable that's invalid in an
445+
// extremely specific way (unsafeBitCasting `other` to an unrelated type)
446+
return NO;
447+
}
442448

443449
// Get Swift type for self and other
444450
auto selfMetadata = _swift_getClassOfAllocated(self);

test/stdlib/BridgeEquatableToObjC.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ struct MyNonEquatableStruct {
2222
var text: String
2323
}
2424

25+
class MyEquatableClass: Equatable {
26+
static func == (lhs: MyEquatableClass, rhs: MyEquatableClass) -> Bool { true }
27+
}
28+
2529
BridgeEquatableToObjC.test("Bridge equatable struct") {
2630
let swiftA = MyEquatableStruct(text: "xABC")
2731
let swiftB = swiftA
@@ -46,5 +50,13 @@ BridgeEquatableToObjC.test("Bridge non-equatable struct") {
4650
expectEqual(objcResult, false)
4751
}
4852

53+
BridgeEquatableToObjC.test("Compare tagged pointer to equatable SwiftObject") {
54+
let literal = "The quick brown fox jumps over the lazy dog"
55+
let bridgedLiteral = literal as NSString
56+
let foo = MyEquatableClass()
57+
let bridgedFoo = foo as AnyObject
58+
let result = bridgedFoo.isEqual(bridgedLiteral)
59+
expectEqual(result, false)
60+
}
4961

5062
runAllTests()

0 commit comments

Comments
 (0)