From 6224bee6cfc0edbb588870e44de0c9d88090f7c7 Mon Sep 17 00:00:00 2001 From: Nikolay Volosatov Date: Wed, 31 Jul 2019 18:08:42 +0300 Subject: [PATCH 1/5] fix supportsSecureCoding for intercepted classes --- Classes/Stubbing/KWIntercept.m | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/Classes/Stubbing/KWIntercept.m b/Classes/Stubbing/KWIntercept.m index 79107895..0f098bac 100644 --- a/Classes/Stubbing/KWIntercept.m +++ b/Classes/Stubbing/KWIntercept.m @@ -37,6 +37,8 @@ void KWInterceptedDealloc(id anObject, SEL aSelector); Class KWInterceptedClass(id anObject, SEL aSelector); Class KWInterceptedSuperclass(id anObject, SEL aSelector); +BOOL KWInterceptedSupportsSecureCodingTrue(id anObject, SEL aSelector); +BOOL KWInterceptedSupportsSecureCodingFalse(id anObject, SEL aSelector); #pragma mark - Getting Forwarding Implementations @@ -120,6 +122,15 @@ Class KWInterceptClassForCanonicalClass(Class canonicalClass) { Class interceptMetaClass = object_getClass(interceptClass); class_addMethod(interceptMetaClass, @selector(forwardInvocation:), (IMP)KWInterceptedForwardInvocation, "v@:@"); + SEL supportsSecureCodingSelector = @selector(supportsSecureCoding); + Method supportsSecureCodingMethod = class_getClassMethod(canonicalClass, supportsSecureCodingSelector); + if (supportsSecureCodingMethod != NULL) { + BOOL support = [(id)canonicalClass performSelector:supportsSecureCodingSelector]; + IMP supportsSecureCodingIMP = support ? (IMP)KWInterceptedSupportsSecureCodingTrue + : (IMP)KWInterceptedSupportsSecureCodingFalse; + class_addMethod(interceptMetaClass, supportsSecureCodingSelector, supportsSecureCodingIMP, "B@:"); + } + return interceptClass; } @@ -223,6 +234,14 @@ Class KWInterceptedSuperclass(id anObject, SEL aSelector) { return originalSuperclass; } +BOOL KWInterceptedSupportsSecureCodingTrue(id anObject, SEL aSelector) { + return YES; +} + +BOOL KWInterceptedSupportsSecureCodingFalse(id anObject, SEL aSelector) { + return NO; +} + #pragma mark - Managing Objects Stubs void KWAssociateObjectStub(id anObject, KWStub *aStub, BOOL overrideExisting) { From dc077e308e633613f15bce0df70ca3f5e952ad82 Mon Sep 17 00:00:00 2001 From: Nikolay Volosatov Date: Fri, 10 Jan 2020 15:59:29 +0300 Subject: [PATCH 2/5] ignore warning --- Classes/Stubbing/KWIntercept.m | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Classes/Stubbing/KWIntercept.m b/Classes/Stubbing/KWIntercept.m index 0f098bac..6f8e9a49 100644 --- a/Classes/Stubbing/KWIntercept.m +++ b/Classes/Stubbing/KWIntercept.m @@ -125,7 +125,10 @@ Class KWInterceptClassForCanonicalClass(Class canonicalClass) { SEL supportsSecureCodingSelector = @selector(supportsSecureCoding); Method supportsSecureCodingMethod = class_getClassMethod(canonicalClass, supportsSecureCodingSelector); if (supportsSecureCodingMethod != NULL) { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Warc-performSelector-leaks" BOOL support = [(id)canonicalClass performSelector:supportsSecureCodingSelector]; +#pragma clang diagnostic pop IMP supportsSecureCodingIMP = support ? (IMP)KWInterceptedSupportsSecureCodingTrue : (IMP)KWInterceptedSupportsSecureCodingFalse; class_addMethod(interceptMetaClass, supportsSecureCodingSelector, supportsSecureCodingIMP, "B@:"); From 8014497096ba1da5927491779da7d0dcfced80f3 Mon Sep 17 00:00:00 2001 From: Nikolay Volosatov Date: Fri, 10 Jan 2020 17:17:09 +0300 Subject: [PATCH 3/5] add test for secure coding of NSDate after stubbing --- Tests/KWRealObjectStubTest.m | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Tests/KWRealObjectStubTest.m b/Tests/KWRealObjectStubTest.m index 4ed9bd06..e0bcc1d3 100644 --- a/Tests/KWRealObjectStubTest.m +++ b/Tests/KWRealObjectStubTest.m @@ -195,6 +195,15 @@ - (void)testItShouldStubWithBlock { XCTAssertEqual([cruiser classification], @"Enterprise", @"expected method to be stubbed with block"); } +- (void)testStubSecureCodingOfDateClass { + NSDate *date = [NSDate date]; + [NSDate stub:@selector(date) andReturn:date]; + if (@available(iOS 11.0, *)) { + NSData *data = [NSKeyedArchiver archivedDataWithRootObject:date requiringSecureCoding:YES error:NULL]; + XCTAssertNotNil(data, @"expected stubbed class to be able to use secure coding"); + } +} + @end #endif // #if KW_TESTS_ENABLED From af4fcff59705b13b18dfbbcc1d294394e32ff6c6 Mon Sep 17 00:00:00 2001 From: Nikolay Volosatov Date: Fri, 10 Jan 2020 17:28:50 +0300 Subject: [PATCH 4/5] use explicit cast --- Classes/Stubbing/KWIntercept.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Classes/Stubbing/KWIntercept.m b/Classes/Stubbing/KWIntercept.m index 6f8e9a49..7d3f4f57 100644 --- a/Classes/Stubbing/KWIntercept.m +++ b/Classes/Stubbing/KWIntercept.m @@ -127,7 +127,7 @@ Class KWInterceptClassForCanonicalClass(Class canonicalClass) { if (supportsSecureCodingMethod != NULL) { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Warc-performSelector-leaks" - BOOL support = [(id)canonicalClass performSelector:supportsSecureCodingSelector]; + BOOL support = (BOOL)[(id)canonicalClass performSelector:supportsSecureCodingSelector]; #pragma clang diagnostic pop IMP supportsSecureCodingIMP = support ? (IMP)KWInterceptedSupportsSecureCodingTrue : (IMP)KWInterceptedSupportsSecureCodingFalse; From 75cc4e69fd8e0c6b0fed692c1c72f4753ed58013 Mon Sep 17 00:00:00 2001 From: Nikolay Volosatov Date: Fri, 10 Jan 2020 17:33:48 +0300 Subject: [PATCH 5/5] fix macOS availability for new test --- Tests/KWRealObjectStubTest.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/KWRealObjectStubTest.m b/Tests/KWRealObjectStubTest.m index e0bcc1d3..a3494842 100644 --- a/Tests/KWRealObjectStubTest.m +++ b/Tests/KWRealObjectStubTest.m @@ -198,7 +198,7 @@ - (void)testItShouldStubWithBlock { - (void)testStubSecureCodingOfDateClass { NSDate *date = [NSDate date]; [NSDate stub:@selector(date) andReturn:date]; - if (@available(iOS 11.0, *)) { + if (@available(macOS 10.13, iOS 11.0, watchOS 4.0, tvOS 11.0, *)) { NSData *data = [NSKeyedArchiver archivedDataWithRootObject:date requiringSecureCoding:YES error:NULL]; XCTAssertNotNil(data, @"expected stubbed class to be able to use secure coding"); }