#53341: fix: settle pending upload stream reads when a net.request ends
Merged
Created: Aug 31, 2026, 1:20:46 PM
Merged: Sep 1, 2026, 10:31:43 AM
8 comments
Target: main
Description of Change
net.requestnever told its chunked upload getter when the request ended. A protocol handler that had parked abody.read()on the upload stream then waited forever for aGetSizereply that could not come, and the stream'sSelfKeepAlivekept it rooted.SimpleURLLoaderWrapper::OnCompleteandCancelnow abort the getter, so the pending read rejects with the request's net error.- This is the cause of the
cpp heap url loader module keeps a ChunkedDataPipeReadableStream alive …hang seen on the ASan and UBSan shard-3 jobs (three unrelated PRs on 2026-08-31, e.g. this run). That test's handler never responds and drops the one-timecallback; the native side only references it weakly (gin_helper/callback.cc), so the test's own GC loop could collect it, which fails the request withERR_FAILEDbeforerequest.end()runs. Whether the GC caught it in time is timing-dependent, hence the flake. The handler now holds the callback for the test's duration. - New
api-net-speccases: a handler parks an upload-stream read and the request is aborted or failed (the read rejects withERR_FAILED), and a response completes while a write is still in flight (the write callback getsERR_ABORTED). - The first CI run of this PR hit an ASan use-after-poison in
mojo::ReceiverSetState::Entry::OnDisconnect. Withpoison_history_sizeon, ASan attributes the poison to cppgc'sUnmarkedObjectsPoisonerat the start of a sweep: aSimpleURLLoaderWrapperhad been found dead but not yet finalized when the network service's disconnect for one of its observer receivers arrived.UtilityProcessWrapperhas the sameReceiverSetshape. Both now get a cppgc pre-finalizer that drops the receivers before the sweep, asReplyChanneland the IPC renderer classes already do. Locally the 28-file ASan shard reproduced the crash on the first version and runs clean with this one.
Verified locally on an ASan build: the original cpp-heap spec failed 3/3 before and passes after, a standalone repro with the callback still collectable completes instead of hanging, and the new net specs pass.
Checklist
- I have built and tested this change
- I have filled out the PR description
- I have reviewed and verified the changes
- PR release notes describe the change in a way relevant to app developers, and are capitalized, punctuated, and past tense.
Release Notes
Notes: Fixed a pending read on a net.request chunked upload stream inside a protocol handler never settling when the request failed or was aborted.
Backports
Semver Impact
Major
Breaking changes
Minor
New features
Patch
Bug fixes
None
Docs, tests, etc.
Semantic Versioning helps users understand the impact of updates:
- Major (X.y.z): Breaking changes that may require code modifications
- Minor (x.Y.z): New features that maintain backward compatibility
- Patch (x.y.Z): Bug fixes that don't change the API
- None: Changes that don't affect using facing parts of Electron