Skip to content

[Crash] Avoid iOS 16 URL parsing crash in stringWithUserAndPasswordStripped - #916

Open
o-nnerb wants to merge 1 commit into
swift-server:mainfrom
request-dl:fix/ios16-url-percent-encoded-crash
Open

[Crash] Avoid iOS 16 URL parsing crash in stringWithUserAndPasswordStripped#916
o-nnerb wants to merge 1 commit into
swift-server:mainfrom
request-dl:fix/ios16-url-percent-encoded-crash

Conversation

@o-nnerb

@o-nnerb o-nnerb commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Summary

URL.stringWithUserAndPasswordStripped (added in #906, used by the built-in span attribute support from #857) calls the percent-encoded URL.user() / URL.password() accessors when #available(macOS 13.0, iOS 16.0, tvOS 16.0, watchOS 9.0, *).

On iOS 16, calling these accessors can crash inside Foundation's URL parsing. The trap surfaces at URL.host(percentEncoded:) even though .host() is never called from this code path — the new percent-encoded accessors appear to share internal component-parsing code with host parsing on that OS version. Swift Forums has a report of the same crash signature triggered by a different percent-encoded accessor (URL.query(percentEncoded:)), also surfacing inside URL.host(percentEncoded:): https://forums.swift.org/t/does-url-query-percentencoded-calls-url-host-percentencoded-under-the-hood/70452

Since HTTPClient.TracingConfiguration.init() defaults to InstrumentationSystem.tracer (typically a no-op tracer when the app hasn't bootstrapped one), this code path runs on effectively every request made through HTTPClient/HTTP2ClientRequestHandler, not only when an app has opted into tracing. That makes this a crash-on-every-request risk for any app running on affected iOS 16 devices.

Fix

Raise the #available gate from iOS 16/macOS 13 to iOS 17/macOS 14 (and the corresponding tvOS/watchOS versions), so iOS 16 falls back to the existing legacy branch using the older, non-percent-encoded user/password properties, which do not hit this bug.

Testing

  • swift build succeeds.
  • Crash observed and confirmed in a production Crashlytics report on the crashed thread nio.transportservices.eventloop.taskqueue, with the trap in URL.host(percentEncoded:) reached via stringWithUserAndPasswordStripped.getterhandleRequestTracingAttributesRequestBag.LoopBoundState.startRequestSpan(tracer:)RequestBag.willExecuteRequest0(_:)HTTP2ClientRequestHandler.write(context:data:promise:).

URL.user()/password() (the percent-encoded accessors) share internal
parsing code with URL.host(percentEncoded:) on iOS 16, and calling
them there can crash inside host parsing even though host is never
touched here. Gate the fast path on iOS 17 instead, so iOS 16 falls
back to the legacy user/password properties, which don't hit the bug.

See https://forums.swift.org/t/70452 for the same crash signature.
@o-nnerb o-nnerb changed the title Avoid iOS 16 URL parsing crash in stringWithUserAndPasswordStripped [Crash] Avoid iOS 16 URL parsing crash in stringWithUserAndPasswordStripped Aug 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant