Skip to content

v4.2.20 - #92

Merged
Power2All merged 3 commits into
masterfrom
v4.2.20
Aug 8, 2026
Merged

Power2All merged 3 commits into
masterfrom
v4.2.20

Conversation

@Power2All

@Power2All Power2All commented Aug 8, 2026

Copy link
Copy Markdown
Owner
  • Applied full audit and security scan on code, and applied recommended solutions.
  • Optimalisation of over-engineered code, applied recommended alternatives.

Summary by CodeRabbit

  • New Features
    • Added an optional maximum torrent limit; 0 preserves unlimited behavior.
    • Peer responses now honor requested counts across HTTP, UDP, and WebSocket announcements.
  • Security
    • Strengthened API authentication, input validation, token handling, and JavaScript escaping.
    • Improved path validation while supporting absolute certificate paths.
  • Bug Fixes
    • Prevented malformed database records and invalid deletion identifiers from causing failures.
    • Corrected completion counting, peer validation, counter overflow, and stale peer handling.
  • Documentation
    • Added v4.2.20 release notes and updated configuration guidance.

…ed solutions.

* Optimalisation of over-engineered code, applied recommended alternatives.
@Power2All Power2All self-assigned this Aug 8, 2026
@Power2All Power2All added the enhancement New feature or request label Aug 8, 2026
@coderabbitai

coderabbitai Bot commented Aug 8, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@Power2All, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 13 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: e926a32c-e637-4278-8eca-95f8557f72ce

📥 Commits

Reviewing files that changed from the base of the PR and between 4920d4b and bde69ae.

📒 Files selected for processing (7)
  • src/database/impls/database_connector_mysql.rs
  • src/database/impls/database_connector_pgsql.rs
  • src/database/impls/database_connector_sqlite.rs
  • src/tracker/impls/torrent_tracker_handlers.rs
  • src/tracker/impls/torrent_tracker_peers.rs
  • src/tracker/tests.rs
  • tests/tracker_tests.rs
📝 Walkthrough

Walkthrough

Changes

Version 4.2.20 metadata and Docker references were updated. The changes add API and input validation, configurable torrent limits, safer database handling, bounded announce responses, escaped JavaScript arguments, and shared compressed storage.

Release and runtime changes

Layer / File(s) Summary
Release metadata
Cargo.toml, README.md, docker/*
Release references now use version 4.2.20. Serde enables the rc feature.
Shared compressed storage
src/common/structs/compressed_bytes.rs, src/common/impls/compressed_bytes.rs
CompressedBytes now stores immutable compressed data in Arc<[u8]>.
Configuration and torrent cap
src/config/*, src/tracker/*
The tracker adds max_torrents. New swarms are rejected at the limit. Completion counting validates state transitions and saturates counters.
API and input security
src/api/*, src/security/*, src/rtctorrent_bridge/*, src/tracker/impls/torrent_tracker_handlers.rs, src/websocket/websocket.rs
OpenAPI access requires validated authentication. Hexadecimal validators, traversal checks, JavaScript escaping, peer-message validation, RTC gating, and constant-time comparison are applied.
User deletion and persistence
src/api/api_users.rs, src/database/impls/*
Removal records retain configured identifiers. Database connectors skip malformed or incomplete identifiers and reuse resolved SQL values.
Announce response controls
src/http/http.rs, src/udp/*, src/websocket/websocket.rs
Peer responses honor validated numwant values. UDP payload-IP use is restricted by proxy allowlists.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant AnnounceHandler
  participant Tracker
  participant PeerStore
  Client->>AnnounceHandler: announce with numwant
  AnnounceHandler->>Tracker: validate and process announce
  Tracker->>PeerStore: retrieve up to requested peer count
  PeerStore-->>Tracker: peers
  Tracker-->>AnnounceHandler: bounded response
  AnnounceHandler-->>Client: encoded peers
Loading

Possibly related PRs

Suggested labels: bug

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The title identifies the release version but does not describe the main security, validation, configuration, and tracker changes. Use a concise title that names the primary change, such as security hardening and tracker improvements for v4.2.20.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch v4.2.20

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

🧹 Nitpick comments (1)
src/common/structs/compressed_bytes.rs (1)

48-48: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Document or hide the mutable tuple storage in CompressedBytes.

CompressedBytes stores data as pub Arc<[u8]>, and the private impl only uses compress/decompress. Add an accessor method or keep the tuple field private, and update the docs to say the field is for crate-internal construction, because Arc does not make the backing bytes immutable.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/common/structs/compressed_bytes.rs` at line 48, Update the
CompressedBytes tuple struct to hide its Arc<[u8]> field or expose it through a
deliberate accessor, and document that construction is intended for
crate-internal use. Preserve the existing compress and decompress behavior while
preventing callers from treating the public tuple storage as immutable merely
because it uses Arc.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@README.md`:
- Line 603: Update the changelog entry containing “Optimalisation” to use
“Optimization,” preserving the rest of the release note unchanged.

In `@src/api/api_users.rs`:
- Around line 45-50: Validate and canonicalize the configured identifier in
user_removal_entry, then reuse that single validated value for both hashing and
UserEntryItem tombstone construction. In
src/database/impls/database_connector_mysql.rs:750-775,
src/database/impls/database_connector_pgsql.rs:758-783, and
src/database/impls/database_connector_sqlite.rs:774-799, update the user-removal
SQL paths to bind the resolved identifier parameter instead of interpolating
id_val, preserving the existing identifier semantics.

In `@src/config/impls/configuration.rs`:
- Around line 248-250: Update the TRACKER__MAX_TORRENTS override in the
configuration loading flow to preserve the already loaded
tracker_config.max_torrents value when parsing fails, rather than falling back
to 0; alternatively, reject the invalid override and fail startup. Keep valid
environment overrides unchanged.

In `@src/database/impls/database_connector_mysql.rs`:
- Around line 682-687: Update the user-loading pagination logic in
src/database/impls/database_connector_mysql.rs:682-687,
src/database/impls/database_connector_pgsql.rs:690-695, and
src/database/impls/database_connector_sqlite.rs:708-713 to track the number of
rows fetched from each page separately from successfully parsed users. Continue
fetching while the fetched-row count equals length, including when malformed
rows are skipped, rather than using the loaded-user count as the cursor
condition.

In `@src/tracker/impls/torrent_tracker_peers.rs`:
- Around line 60-75: Make torrent admission atomic with insertion: update
may_create_torrent and the vacant-entry insertion path to reserve capacity under
synchronization before creating a new torrent, preventing concurrent distinct
info-hashes from exceeding max_torrents. Release the reservation when insertion
does not complete or creation fails, while preserving max_torrents == 0 as
unlimited. Add a concurrent test covering distinct info-hashes and the
configured cap.
- Around line 248-255: Update the peer-removal flow before the completion
transition check in the tracker announce handling: remove the peer ID from both
IPv4 and IPv6 regular peer maps, regardless of the incoming address family, then
calculate `seeds_removed` and evaluate the `completed && torrent_peer.left ==
NumberOfBytes(0)` condition. Preserve the existing `was_rtc_seed` handling and
completion counter update.

In `@src/udp/impls/udp_server.rs`:
- Around line 588-593: Update the UDP response construction around the numwant
calculation to store the clamped value in a local variable, then reuse it for
response vector capacity and every subsequent seed and peer-loop limit instead
of the hard-coded 72. Preserve the existing 1..=72 clamping behavior, including
tracker-choice and out-of-range requests.

---

Nitpick comments:
In `@src/common/structs/compressed_bytes.rs`:
- Line 48: Update the CompressedBytes tuple struct to hide its Arc<[u8]> field
or expose it through a deliberate accessor, and document that construction is
intended for crate-internal use. Preserve the existing compress and decompress
behavior while preventing callers from treating the public tuple storage as
immutable merely because it uses Arc.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: be55612c-275d-4631-a0fb-90b681ac15e7

📥 Commits

Reviewing files that changed from the base of the PR and between 1abfe99 and 57e90bc.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (25)
  • Cargo.toml
  • README.md
  • docker/Dockerfile
  • docker/build.bat
  • src/api/api.rs
  • src/api/api_users.rs
  • src/common/impls/compressed_bytes.rs
  • src/common/structs/compressed_bytes.rs
  • src/config/config.rs
  • src/config/impls/configuration.rs
  • src/config/structs/tracker_config.rs
  • src/database/impls/database_connector_mysql.rs
  • src/database/impls/database_connector_pgsql.rs
  • src/database/impls/database_connector_sqlite.rs
  • src/http/http.rs
  • src/rtctorrent_bridge/impls/rtc_torrent_bridge.rs
  • src/security/security.rs
  • src/security/tests.rs
  • src/tracker/impls/torrent_tracker_handlers.rs
  • src/tracker/impls/torrent_tracker_peers.rs
  • src/tracker/mod.rs
  • src/tracker/tests.rs
  • src/udp/impls/parse_pool.rs
  • src/udp/impls/udp_server.rs
  • src/websocket/websocket.rs

Comment thread README.md Outdated
Comment thread src/api/api_users.rs Outdated
Comment thread src/config/impls/configuration.rs
Comment thread src/database/impls/database_connector_mysql.rs
Comment thread src/tracker/impls/torrent_tracker_peers.rs Outdated
Comment thread src/tracker/impls/torrent_tracker_peers.rs
Comment thread src/udp/impls/udp_server.rs Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/database/impls/database_connector_pgsql.rs (1)

762-797: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Bind UUID values for all user persistence statements. Both connectors bind UUIDs for DELETE statements but interpolate them into INSERT and UPDATE statements. A malformed UUID retained from a persisted row can break a save batch or change the generated SQL.

  • src/database/impls/database_connector_pgsql.rs#L762-L797: use a PostgreSQL placeholder and bind the UUID in the Add and Update paths.
  • src/database/impls/database_connector_sqlite.rs#L778-L812: use a SQLite placeholder and bind the UUID in the Add and Update paths.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/database/impls/database_connector_pgsql.rs` around lines 762 - 797, Bind
UUID values in all user persistence statements: in
src/database/impls/database_connector_pgsql.rs lines 762-797, update the Add and
Update paths to use PostgreSQL placeholders and bind the UUID through the query
statement, matching the existing DELETE handling; in
src/database/impls/database_connector_sqlite.rs lines 778-812, make the
equivalent Add and Update changes using SQLite placeholders. Preserve numeric ID
handling and existing control flow.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/tracker/impls/torrent_tracker_peers.rs`:
- Around line 180-185: Change the admission flow around try_claim_torrent_slot
and handle_announce to return an explicit rejected result instead of
AnnounceEntry::default(). Ensure rejected announces bypass persistence, cache,
and user activity/completion updates in torrent_tracker_handlers, while
preserving normal processing for admitted announces. Add integration coverage
for rejected Started and Completed announces.

---

Outside diff comments:
In `@src/database/impls/database_connector_pgsql.rs`:
- Around line 762-797: Bind UUID values in all user persistence statements: in
src/database/impls/database_connector_pgsql.rs lines 762-797, update the Add and
Update paths to use PostgreSQL placeholders and bind the UUID through the query
statement, matching the existing DELETE handling; in
src/database/impls/database_connector_sqlite.rs lines 778-812, make the
equivalent Add and Update changes using SQLite placeholders. Preserve numeric ID
handling and existing control flow.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: b4c68a81-bbaf-4977-8c66-c285538f4d29

📥 Commits

Reviewing files that changed from the base of the PR and between 57e90bc and 4920d4b.

📒 Files selected for processing (10)
  • README.md
  • src/api/api_users.rs
  • src/common/structs/compressed_bytes.rs
  • src/config/impls/configuration.rs
  • src/database/impls/database_connector_mysql.rs
  • src/database/impls/database_connector_pgsql.rs
  • src/database/impls/database_connector_sqlite.rs
  • src/tracker/impls/torrent_tracker_peers.rs
  • src/tracker/tests.rs
  • src/udp/impls/udp_server.rs
🚧 Files skipped from review as they are similar to previous changes (5)
  • README.md
  • src/common/structs/compressed_bytes.rs
  • src/api/api_users.rs
  • src/config/impls/configuration.rs
  • src/database/impls/database_connector_mysql.rs

Comment thread src/tracker/impls/torrent_tracker_peers.rs
@Power2All
Power2All merged commit 70c8bad into master Aug 8, 2026
2 checks passed
@Power2All
Power2All deleted the v4.2.20 branch August 8, 2026 18:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant