Skip to content

Review batch 3: 7 verified fixes across tracker, torrent, client#7

Merged
iksnerd merged 1 commit into
mainfrom
fix/review-batch3
Jun 13, 2026
Merged

Review batch 3: 7 verified fixes across tracker, torrent, client#7
iksnerd merged 1 commit into
mainfrom
fix/review-batch3

Conversation

@iksnerd

@iksnerd iksnerd commented Jun 13, 2026

Copy link
Copy Markdown
Owner

Third batch from the 2026-06-13 review — the medium/low findings I'd deprioritized, each verified by reading the code first (two claimed bugs turned out to be false positives and were left alone).

Changes

GetPeers off-by-oneinternal/tracker/state.go
The limit check ran after the append, so numwant=0 returned 1 peer instead of 0. Check before appending. Test added.

sort=seeders paginationinternal/tracker/registry.go
Seeder counts are memory-only, so the query paginated by created_at in SQL and then re-sorted only the current page — wrong ranking across pages. Now scans the matching set (capped at 1000, logged when exceeded so the truncation isn't silent), sorts by seeders, and paginates in memory.

Content-Disposition header injectioninternal/tracker/registry.go
The DB-sourced torrent name was interpolated raw into the response header. Sanitize quotes/backslash/control chars first.

Magnet hash validationinternal/torrent/magnet.go
btih/btmh info hashes were stored verbatim. Validate v1 as 40 hex chars and v2 as 64 hex at the parse boundary (LangSec). Tests added; existing tests updated to use realistic-length hashes.

PIECE block validationinternal/client/downloader.go
The block's index/begin were ignored, so a stray/duplicate/reordered block from a non-conforming peer landed at the wrong offset (caught only later by the SHA-1 check). Validate both before copying.

generatePeerIDinternal/client/downloader.go
Switched from time-seeded math/rand to crypto/rand so two clients started in the same instant don't collide.

WritePiece integrity checkinternal/client/storage.go
Asserts every piece byte mapped to a file instead of silently returning success on a bad offset mapping (the previously-unused dataOffset now guards this).

Verified false positives (not changed)

  • swarm.go "resultChan deadlock" (claimed critical) — the drain loop at Start absorbs any in-flight worker sends before wg.Wait() closes the channel; no sender can block past close.
  • wire.go payload cap — 2<<20 is exactly 2 MiB, matching its comment.

Still open (need reference client / architectural change, not in this PR)

v2 Merkle padding (inconclusive — needs a Transmission 4.x golden vector), multi-file hybrid padding files, and the swarm's static peer partitioning (reliability, not correctness).

Verification

go build, go vet, gofmt clean; full go test ./... passes including new tests.

🤖 Generated with Claude Code

- tracker/state: GetPeers returned 1 peer when numwant=0 (off-by-one — the
  limit check ran after the append). Check before appending. Test added.
- tracker/registry: 'sort=seeders' applied SQL LIMIT/OFFSET by created_at then
  re-sorted only that page, so seeder ranking was wrong across pages. Scan the
  matching set (capped at 1000, logged if exceeded), then sort + paginate in
  memory.
- tracker/registry: sanitize the DB-sourced name before interpolating into the
  Content-Disposition header (strip quotes/backslash/control chars).
- torrent/magnet: validate btih (40 hex) and btmh:1220 (64 hex) info hashes at
  the parse boundary instead of storing arbitrary text (LangSec). Tests added.
- client/downloader: validate PIECE block index+begin before copying, so a
  stray/duplicate/reordered block can't land at the wrong offset.
- client/downloader: generatePeerID now uses crypto/rand instead of
  time-seeded math/rand (collision risk).
- client/storage: WritePiece asserts every piece byte mapped to a file rather
  than silently returning success on a bad offset mapping.

Verified false positives, not changed: swarm.go resultChan 'deadlock' (the
drain loop absorbs in-flight sends before close) and the wire.go 2 MiB cap.
@iksnerd iksnerd merged commit 47f8214 into main Jun 13, 2026
1 check passed
@iksnerd iksnerd deleted the fix/review-batch3 branch June 13, 2026 11:14
iksnerd added a commit that referenced this pull request Jun 21, 2026
Review batch 3: 7 verified fixes across tracker, torrent, client
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