Skip to content

Commit 8d2b1bb

Browse files
authored
Merge pull request #24394 from mikeash/decode-the-undecodable
[Stdlib] Make the SwiftNativeNSXXXBase classes gracefully handle being decoded with NSKeyedUnarchiver.
2 parents 89e50b5 + 7506e9c commit 8d2b1bb

File tree

2 files changed

+59
-0
lines changed

2 files changed

+59
-0
lines changed

stdlib/public/stubs/SwiftNativeNSXXXBase.mm.gyb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,9 @@ SWIFT_RUNTIME_STDLIB_API
6262

6363
@implementation __SwiftNativeNS${Class}Base
6464

65+
- (id)initWithCoder: (NSCoder *)coder {
66+
return [self init];
67+
}
6568
- (id)retain {
6669
auto SELF = reinterpret_cast<HeapObject *>(self);
6770
swift_retain(SELF);
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
// RUN: %target-run-simple-swift
2+
// REQUIRES: executable_test
3+
4+
// REQUIRES: objc_interop
5+
6+
import Foundation
7+
import StdlibUnittest
8+
9+
let testSuite = TestSuite("SwiftNativeNSXXXCoding")
10+
11+
// Ensure that T gracefully handles being decoded. It doesn't have to
12+
// work, just not crash.
13+
private func test<T: NSObject & NSCoding>(type: T.Type) {
14+
if #available(macOS 10.13, iOS 11.0, tvOS 11.0, watchOS 4.0, *) {
15+
let swiftClassName = "__SwiftNative\(type)Base"
16+
print(swiftClassName)
17+
let archiver = NSKeyedArchiver(requiringSecureCoding: true)
18+
archiver.setClassName(swiftClassName, for: T.self)
19+
archiver.encode(T(), forKey: "key")
20+
archiver.finishEncoding()
21+
let d = archiver.encodedData
22+
23+
let unarchiver = try! NSKeyedUnarchiver(forReadingFrom: d)
24+
_ = unarchiver.decodeObject(of: T.self, forKey: "key")
25+
}
26+
}
27+
28+
29+
// Test all the classes listed in SwiftNativeNSXXXBase.mm.gyb except for
30+
// NSEnumerator (which doesn't conform to NSCoding).
31+
32+
testSuite.test("NSArray") {
33+
test(type: NSArray.self)
34+
}
35+
36+
testSuite.test("NSDictionary") {
37+
test(type: NSDictionary.self)
38+
}
39+
40+
testSuite.test("NSSet") {
41+
test(type: NSSet.self)
42+
}
43+
44+
testSuite.test("NSString") {
45+
test(type: NSString.self)
46+
}
47+
48+
testSuite.test("NSData") {
49+
test(type: NSData.self)
50+
}
51+
52+
testSuite.test("NSIndexSet") {
53+
test(type: NSIndexSet.self)
54+
}
55+
56+
runAllTests()

0 commit comments

Comments
 (0)