erikdoe / ocmock

Mock objects for Objective-C
http://ocmock.org
Apache License 2.0
2.16k stars 606 forks source link

OCMPartialMock initialized with NSConstantArray is crashing on Xcode 14.0b3 #522

Open rmaloney3 opened 2 years ago

rmaloney3 commented 2 years ago

OCMock 3.9.1 Xcode 14.0 beta 3 (14A5270f)

Using the above versions, when initializing an OCMPartialMock with an NSConstantArray, it results in an EXC_BAD_ACCESS crash in -[OCPartialMockObject prepareObjectForInstanceMethodMocking] on line 160 of OCPartialMockObject.m.

Here is an example that reproduces the crash:

- (void)testPartialMockWithArrayConstant {
    NSArray *identifiers = @[ @1, @2, @3 ];
    id mockIdentifiers = OCMPartialMock(identifiers);
}

Modifying the code to use an NSArray instead of an NSConstantArray does not crash:

- (void)testPartialMockWithArray {
    NSArray *identifiers = [NSArray arrayWithObjects:@1, @2, @3, nil];;
    id mockIdentifiers = OCMPartialMock(identifiers);
}
dmaclach commented 2 years ago

Got any crash logs you could add? Be interested to know what OS you are running on as well.

rmaloney3 commented 2 years ago

Crash report on macOS 12.4 (21F79): xctest-2022-07-20-102120.txt

erikdoe commented 2 years ago

I can repreduce the crash, with a different stack trace. Not sure what to do here. It feels like another optimisation in the runtime, which makes immutable arrays somehow special so that the setup and clean up doesn't work as expected for them.

One option would be to add a check for immutable arrays and consider it an error when a test tries to create a partial mock for an immutable array (which is a questionable thing to do anyway).

By the way, to my knowledge there is no NSConstantArray. The only thing that's publicly visible is NSArray and NSMutableArray. At runtime you'll also see classes like __NSArrayI.