From 82d3537566ccdfbff9ba45087e305f4b5e92f05c Mon Sep 17 00:00:00 2001 From: Ben Yohay Date: Sun, 1 May 2022 09:39:29 +0300 Subject: [PATCH] OCMock: Fix crash when running on iOS 15 device. `object_getClass` crashes on some arguments when being run on an iOS 15 device. `object_getClass` is needed because OCMock needs to detect if the argument is actually a `OCMPassByRefSetter`, which disguises as a pointer to an object (`id *`) but is actually an object (`id`). The solution is to make sure before calling `object_getClass` that the type encoding of the argument is actually a pointer to an object, and then it should be safe to call `object_getClass`. The problem is that the value was previously wrapped with an `NSValue`, which disguised the type encoding as a `void *`. Therefore the check of whether the argument is `id *` is done before it will be wrapped with `NSValue`. --- Source/OCMock/NSInvocation+OCMAdditions.m | 9 +++++++++ Source/OCMock/OCMArg.m | 2 -- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/Source/OCMock/NSInvocation+OCMAdditions.m b/Source/OCMock/NSInvocation+OCMAdditions.m index 61569546..699ecce7 100644 --- a/Source/OCMock/NSInvocation+OCMAdditions.m +++ b/Source/OCMock/NSInvocation+OCMAdditions.m @@ -19,6 +19,7 @@ #import "NSMethodSignature+OCMAdditions.h" #import "OCMArg.h" #import "OCMFunctionsPrivate.h" +#import "OCMPassByRefSetter.h" #if(TARGET_OS_OSX && (!defined(__MAC_10_10) || __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_10)) || \ (TARGET_OS_IPHONE && (!defined(__IPHONE_8_0) || __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_8_0)) @@ -195,6 +196,14 @@ - (id)getArgumentAtIndexAsObject:(NSInteger)argIndex return value; } + if (strcmp(argType, "^@") == 0) { + id *value; + [self getArgument:&value atIndex:argIndex]; + if (object_getClass((id)value) == [OCMPassByRefSetter class]) { + return (id)value; + } + } + switch(argType[0]) { case ':': diff --git a/Source/OCMock/OCMArg.m b/Source/OCMock/OCMArg.m index 063181ac..d61bc936 100644 --- a/Source/OCMock/OCMArg.m +++ b/Source/OCMock/OCMArg.m @@ -129,8 +129,6 @@ + (id)resolveSpecialValues:(NSValue *)value void *pointer = [value pointerValue]; if(pointer == (void *)0x01234567) return [OCMArg any]; - if((pointer != NULL) && (object_getClass((id)pointer) == [OCMPassByRefSetter class])) - return (id)pointer; } else if(type[0] == ':') {