Skip to content

Commit bdb822a

Browse files
committed
[Runtime] Accept Nil in the patched bundleForClass:.
The patched +[NSBundle bundleForClass:] crashes on Nil, while the original Foundation implementation returns the main bundle. Avoid the crash and pass Nil through to Foundation. This also ensures that Nil is passed through to class_getImageName rather than crashing. SR-9188 rdar://problem/45849924
1 parent 51198e4 commit bdb822a

File tree

2 files changed

+29
-1
lines changed

2 files changed

+29
-1
lines changed

stdlib/public/runtime/ObjCRuntimeGetImageNameFromClass.mm

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,11 @@ typedef BOOL (*objc_hook_getImageName)(
5656
/// Get the image name corresponding to a Swift class, accounting for
5757
/// dynamically-initialized class metadata. Returns NO for ObjC classes.
5858
static BOOL
59-
getImageNameFromSwiftClass(Class _Nonnull objcClass,
59+
getImageNameFromSwiftClass(Class _Nullable objcClass,
6060
const char * _Nullable * _Nonnull outImageName) {
61+
if (objcClass == Nil)
62+
return NO;
63+
6164
auto *classAsMetadata = reinterpret_cast<const ClassMetadata *>(objcClass);
6265

6366
// Is this a Swift class?

test/stdlib/Bundle.swift

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// RUN: %target-run-simple-swift
2+
// REQUIRES: executable_test
3+
// REQUIRES: objc_interop
4+
5+
import Foundation
6+
import StdlibUnittest
7+
8+
var BundleTests = TestSuite("BundleTests")
9+
10+
BundleTests.test("Bundle.bundleForNilClass") {
11+
// Ensure that bundleForClass: tolerates a nil parameter. The
12+
// Foundation implementation does. The patched version from
13+
// ObjCRuntimeGetImageNameFromClass did not.
14+
//
15+
// SR-9188
16+
typealias BundleForClassFunc =
17+
@convention(c) (AnyObject, Selector, AnyObject?) -> Bundle
18+
19+
let sel = #selector(Bundle.init(for:))
20+
let imp = unsafeBitCast(Bundle.method(for: sel), to: BundleForClassFunc.self)
21+
let bundleForNil = imp(Bundle.self, sel, nil);
22+
expectEqual(Bundle.main, bundleForNil)
23+
}
24+
25+
runAllTests()

0 commit comments

Comments
 (0)