security-union / security-union/remote-shutter
FakeMultipeerService.sentMessages is an unsynchronized array (latent TSan race)
Nobody has claimed this yet.
- Dominant language
- Swift
- Stars
- 19
- Forks
- 3
- Avg merge
- 28m
- Merged PRs (30d)
- 6
Description
RemoteCamTests/SessionTestSupport.swift:25
var sentMessages: [(msg: Message, peers: [MCPeerID], mode: MCSessionSendDataMode)] = []
...
sentMessages.append((msg, peers, mode)) // :44 — from the coordinator's actor context
Appended from the coordinator's actor while tests read it from the test thread — the same data race that made LoopbackMultipeerService.sentMessages crash 5 of 10 runs under Thread Sanitizer (fixed in PR #157, commit 4d81746).
This one isn't what TSan currently trips on, so it was left alone deliberately — but it's the same latent shape and will bite as soon as a test reads it while the actor is still sending.
Fix (same shape as the one already landed)
private let sentMessagesStorage = Locked<[(msg: Message, peers: [MCPeerID], mode: MCSessionSendDataMode)]>([])
var sentMessages: [(msg: Message, peers: [MCPeerID], mode: MCSessionSendDataMode)] {
get { sentMessagesStorage.value }
set { sentMessagesStorage.value = newValue }
}
plus sentMessagesStorage.mutate { $0.append(...) } in send. Keeping the property's name and type means all existing reads and removeAll() calls compile untouched (~14 sites in RemoteCamSessionTests).
Locked<T> is in RemoteCam/Locked.swift, reachable from tests via @testable import RemoteShutter.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with RemoteCamTests/SessionTestSupport.swift around line 25 and compare its sentMessages access with the synchronized implementation in RemoteCam/Locked.swift and PR #157. Run the RemoteCamSessionTests under Thread Sanitizer; done means existing reads and removeAll() calls still compile and concurrent message recording is race-free.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- swift
- Domain
- testing-qa
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 88/100