Skip to content

Commit

Permalink
Fixed crash with third party library gtm-session-fetcher
Browse files Browse the repository at this point in the history
  • Loading branch information
NachoEmbrace committed Sep 23, 2024
1 parent f6f2a90 commit d0408c9
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 4 deletions.
32 changes: 32 additions & 0 deletions Sources/EmbraceCore/Capture/Network/URLSessionCaptureService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,12 @@ struct URLSessionInitWithDelegateSwizzler: URLSessionSwizzler {
try swizzleClassMethod { originalImplementation -> BlockImplementationType in
return { urlSession, configuration, delegate, queue -> URLSession in
let proxiedDelegate = (delegate != nil) ? delegate : EmbraceDummyURLSessionDelegate()

// check if we support proxying this type of delegate
guard isDelegateSupported(proxiedDelegate) else {
return originalImplementation(urlSession, Self.selector, configuration, delegate, queue)
}

let newDelegate = URLSessionDelegateProxy(originalDelegate: proxiedDelegate, handler: handler)
let session = originalImplementation(urlSession, Self.selector, configuration, newDelegate, queue)

Expand All @@ -116,6 +122,32 @@ struct URLSessionInitWithDelegateSwizzler: URLSessionSwizzler {
}
}
}

// list of third party URLSessionDelegate implementations that we don't support
// due to issues / crashes out of our control
private let unsupportedDelegates: [String] = [

// This type belongs to an internal library used by Firebase which
// incorrectly assumes the type of the URLSession delegate, resulting
// in it calling a method that is not implemented by our proxy.
//
// We can't solve this on our side in a clean way so we'll just not
// capture any requests from this library until the issue is solved
// on their side.
//
// Library: https://github.com/google/gtm-session-fetcher/
// Issue: https://github.com/google/gtm-session-fetcher/issues/190
"GTMSessionFetcher"
]

func isDelegateSupported(_ delegate: URLSessionDelegate?) -> Bool {
guard let delegate = delegate else {
return true
}

let name = String(describing: delegate)
return unsupportedDelegates.first { name.contains($0) } == nil
}
}

struct SessionTaskResumeSwizzler: URLSessionSwizzler {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class URLSessionInitWithDelegateSwizzlerTests: XCTestCase {
func testAfterInstall_onCreateURLSessionWithDelegate_originalShouldBeWrapped() throws {
givenDataTaskWithURLRequestSwizzler()
try givenSwizzlingWasDone()
whenInitializingURLSessionWithDummyDelegate()
whenInitializingURLSessionWithDelegate()
thenSessionsDelegateShouldntBeDummyDelegate()
thenSessionsDelegateShouldBeEmbracesProxy()
}
Expand All @@ -31,6 +31,14 @@ class URLSessionInitWithDelegateSwizzlerTests: XCTestCase {
givenDataTaskWithURLRequestSwizzler()
thenBaseClassShouldBeURLSession()
}

func test_unsupportedDelegates() throws {
givenDataTaskWithURLRequestSwizzler()
try givenSwizzlingWasDone()
whenInitializingURLSessionWithDelegate(GTMSessionFetcher())
thenSessionsDelegateShouldntBeEmbracesProxy()
XCTAssertTrue(session.delegate.self is GTMSessionFetcher)
}
}

private extension URLSessionInitWithDelegateSwizzlerTests {
Expand All @@ -43,10 +51,9 @@ private extension URLSessionInitWithDelegateSwizzlerTests {
try sut.install()
}

func whenInitializingURLSessionWithDummyDelegate() {
let originalDelegate = DummyURLSessionDelegate()
func whenInitializingURLSessionWithDelegate(_ delegate: URLSessionDelegate = DummyURLSessionDelegate()) {
session = URLSession(configuration: .default,
delegate: originalDelegate,
delegate: delegate,
delegateQueue: nil)
}

Expand All @@ -62,7 +69,14 @@ private extension URLSessionInitWithDelegateSwizzlerTests {
XCTAssertTrue(session.delegate.self is URLSessionDelegateProxy)
}

func thenSessionsDelegateShouldntBeEmbracesProxy() {
XCTAssertFalse(session.delegate.self is URLSessionDelegateProxy)
}

func thenBaseClassShouldBeURLSession() {
XCTAssertTrue(sut.baseClass == URLSession.self)
}
}

// unsupported delegates
class GTMSessionFetcher: NSObject, URLSessionDelegate {}

0 comments on commit d0408c9

Please sign in to comment.