Security and privacy
- Error and refusal responses are sent as plain text, and content sniffing is
refused on them, so a value echoed back in a diagnostic cannot be interpreted
as markup by the browser. - A torrent's
Content-Dispositionheader can no longer choose the name a
download is saved under. - Response cookies are scoped to the host and path that set them, are taken
only from a followed redirect's own origin, and aSet-Cookievalue is
bounded to non-control bytes — a terminator inside one previously truncated
the next request's header block. - Four
loginmgraccounts now require an explicitly configured origin instead
of a built-in hostname, and Torrentech, mTeam and AniDUB are reached over the
scheme their account names. Several of those domains had lapsed and been
re-registered by other parties. Permissionselects exactly one mode class, compares group IDs numerically,
and resolves relative symlinks beside the link — the previous comparison
could grant access the kernel refuses.system.multicallpreserves validated member trust, and an account list that
was never discovered is not stored.
Fixes
- A value of zero is handled as a value throughout: the last piece when it is a
single zero byte, an SCGI reply chunk of0, a header line that is a single
zero, a base directory named0, and a bencoded integer read as an integer
rather than a float. - The daemon state follows the daemon again, survives a failed torrent-list
request, and an unreachable daemon is named in the response header. A bad
torrent list is refused before the plugins read it. Accept-Encodingcoding tokens and quality values are honoured,$exitis
respected on a 304 and after an external gzip, and the offered encoding is
initialised.- A submenu stays open while the pointer moves into it, a macOS ctrl-click
reads as the secondary click, a multi-line status tip keeps its line breaks,
and desktop add inputs survive a failed upload. - The HTTP client stops after a header read timeout, discards stale bodies,
distinguishes a socket failure from an HTTP response, preserves literal body
bytes, percent-encodes the URL given to curl, declines a redirect target no
request can carry, and exposes only the final response's headers. fileutilpreserves an existing custom temporary directory's mode and
reports a temporary directory anyone may rewrite. The cache retains its
writer lock while removing an entry and remembers the version a successful
store published.feedssupports an explicit public application URL and serves a feed only
for a view that has it;rsschecks a feed's validators by grammar;
extsearchtakes its origins fromloginmgr;mobileignores files
returned for a previous torrent.- A missing translation key falls back to English, and the bundled Public
Suffix List reports its own age.
Translations
- French: strings still in English translated, wrong translations corrected,
and the permission lists completed. - Two English strings describing a read/write/execute check as "read/execute"
are corrected; following the old text granted a permission that did not
satisfy the check.
Tests
Substantial additions across the suite: shared HTTP and SCGI fixtures, a
harness that drives getplugins.php, serializable daemon replies that run
without pcntl, key parity for lang/*.php, and non-empty assertions on every
swept collection so a glob that stops matching cannot report a pass. The test
tree is now checked in CI as well.
What's Changed
- Snoopy: stop after a header read timeout by @IvanShift in #3399
- Snoopy: refuse malformed URLs without retaining a response by @IvanShift in #3400
- Snoopy: distinguish socket failures from HTTP responses by @IvanShift in #3401
- Snoopy: preserve literal request and response body bytes by @IvanShift in #3398
- fix(objects): keep a submenu open while the pointer moves into it by @xirvik in #3403
- fix: read a macOS ctrl-click as the secondary click it is by @xirvik in #3404
- Fix/zero byte read loops by @xirvik in #3405
- Hash the remaining zero piece in multi-file torrents by @IvanShift in #3407
- CachedEcho: honor exit after sending external gzip by @IvanShift in #3408
- Send tracklabel error responses as plain text by @IvanShift in #3413
- Preserve download names in Content-Disposition headers by @IvanShift in #3411
- Snoopy: discard stale bodies after HTTP read timeouts by @IvanShift in #3409
- Fileutil: preserve existing custom temporary directory modes by @IvanShift in #3415
- Cache: retain the writer lock when removing an entry by @IvanShift in #3410
- Snoopy: scope mutable state to a request chain by @IvanShift in #3416
- tests: run serializable SCGI replies without pcntl by @IvanShift in #3412
- Fix/response header hygiene by @xirvik in #3422
- Fix/torrent basedir and bencode by @xirvik in #3423
- Fix/snoopy request state resets by @xirvik in #3424
- Close test gaps found by mutating merged work by @xirvik in #3425
- Feeds: support an explicit public application URL by @IvanShift in #3418
- Keep account sessions when saving settings fails by @IvanShift in #3419
- Bound the Set-Cookie capture to non-control bytes by @xirvik in #3426
- Preserve validated member trust in system.multicall by @IvanShift in #3421
- Preserve desktop add inputs when uploads fail by @IvanShift in #3420
- Settings: unregister the stored plugin hook subject by @IvanShift in #3414
- Unregister hooks by name, and read either stored shape by @xirvik in #3428
- Fix/loginmgr cache write results by @xirvik in #3429
- Fix/loginmgr configured origins by @xirvik in #3430
- Close three gaps left by merged work by @xirvik in #3431
- Fix/snoopy wire integrity by @xirvik in #3432
- Snoopy: retain timeouts after partial body reads by @IvanShift in #3427
- Mobile: ignore files returned for a previous torrent by @IvanShift in #3434
- Carry a bencoded integer back as an integer by @xirvik in #3437
- Cache: remember the version published by a successful store by @IvanShift in #3433
- Trust the server's scheme over the client's by @xirvik in #3438
- Refuse to store an account list never discovered by @xirvik in #3439
- Decline a header value no request can carry by @xirvik in #3440
- Check the test files, and fall back to English by @xirvik in #3441
- Discard a response no request answered for by @xirvik in #3442
- Assert what the merged work left unasserted by @xirvik in #3443
- Share one add-torrent result collector by @xirvik in #3444
- Drive getplugins.php, and warn on a wide temp dir by @xirvik in #3445
- Send the index, the scheme and the date that were meant by @xirvik in #3446
- Snoopy: expose only the final HTTP response headers by @IvanShift in #3435
- Share framed SCGI transport between XMLRPC clients by @IvanShift in #3436
- WebUI: preserve daemon state after failed list requests by @IvanShift in #3450
- tracklabels: configure the WebUI when column changes are denied by @IvanShift in #3449
- Snoopy: scope response cookies to their request targets by @IvanShift in #3453
- Reuse shared HTTP fixtures in endpoint tests by @IvanShift in #3447
- Permission: select one mode class and resolve relative symlinks by @IvanShift in #3451
- Honor gzip coding tokens and quality values by @IvanShift in #3448
- Report an aged suffix list, and key cookies once by @xirvik in #3454
- Name the add-torrent fixture tree uniquely by @xirvik in #3455
- Mark an unreachable daemon in the response by @xirvik in #3456
- Give a timed cookie case its full lifetime by @xirvik in #3460
- Fix/permission gid compare by @xirvik in #3457
- check_port, extratio: show the plugin's own startup error by @Heliedan in #3459
- fr: translate the strings still in English, fix wrong translations by @Heliedan in #3458
- Fix/permission message flag parity by @xirvik in #3461
- Tests/lang php parity and nonempty guards by @xirvik in #3462
- Bump version to 5.3.19 by @xirvik in #3465
New Contributors
Full Changelog: v5.3.18...v5.3.19