ruTorrent v5.3.17 — v5.3.16..b3239ed, 39 commits
. A security release. If ruTorrent is reachable from an address other people
can use, take this one: a torrent label could carry markup that ran in the
interface, and it did not have to be a label you typed.
Security
- Torrent labels: the Add-torrent dialog built its label dropdown by
concatenating each label into an , so a label carrying markup became
elements and ran as the list was built, before the dialog was opened. A label
is not always typed by the person who reads it — an RSS filter substitutes
${N} from a feed item's title, description or link into the label it sets,
autotools expands {TRACKER} from an announce URL, and addtorrent.php takes
label= from the request — so one can be planted by a feed or a cross-site GET
and stored. Options are now built as elements, with the label as both the
value and the text. (#3381) - loginmgr: YggTorrent credentials go only to one configured origin. The daily
refresh had been posting the account id and password in the clear to the base
class placeholder address, which is a domain registered by someone else, and
the account claimed any https host shaped like ygg*., so a feed or search
result naming such a host was handed them too. The origin is $yggTorrentOrigin
in the new plugins/loginmgr/conf.php; it ships empty, and until it is set the
account claims no URL, sends nothing, and logs why. (#3376) - HTTP client (Snoopy): a response body is bounded. A gzip reply that inflated
without limit could exhaust the memory limit and end the request; the bound is
applied as the body arrives and again once inflated, and an oversized body is
refused rather than handed back truncated under its own 200. The limit is
$httpMaxResponseLength in conf/config.php — raise it where legitimate
downloads are bigger, since the metainfo of a very large torrent runs to
several megabytes of piece hashes alone. (#3370, #3379) - CSRF check: Host and X-Forwarded-Host are read as authorities rather than cut
at the first colon. An IPv6 literal such as [fd00::5]:8080 became "[" and
matched nothing, so with $enableCSRFCheck set every POST made through an IPv6
address answered 403. Host comparison folds case and trailing dots on both
sides. (#3374) - An invalid RU_PROFILE_MASK goes to the error log instead of into the response
body, where it broke the JSON and JavaScript answers it was printed in front
of, and the entry now names the value it rejected. (#3368)
Core
- A client posting to plugins/httprpc/action.php without first loading the
interface got "invalid parameters: invalid target". Only the entry points that
load the UI ask rtorrent for its version and command aliases; everything else
reads the settings cache, and where that file had never been written the alias
map was empty, so the empty target argument d.multicall has taken since
rtorrent 0.16.16 was not prepended. The settings are now probed when the cache
reports no version. (#3380) - Concurrent cache writers no longer erase each other. A cache file is
identified by inode, mtime and size; mtime resolves to the second, size
repeats whenever a row changes to a value of the same length, and rename()
frees the loaded inode so the next writer is handed that number again. Where
the stamp repeats, a digest of the file decides. (#3375) - Editing a torrent no longer rewrites its authorship. Changing a tracker, a
comment or the private flag stamped "created by" and "creation date" with
ruTorrent's own values — inventing both where the original had none — so
rtorrent then served the wrong creation date. Torrents ruTorrent builds are
stamped as before, and the info hash is unaffected either way. (#3369)
Interface
- Touch detection uses current capability tests. $.support.touchable rested on
document.createTouch, which Chrome removed and Safari keeps only as legacy, so
it read false on most touch devices and true on a desktop Mac: desktop Safari
had no Delete, Ctrl+A or Ctrl+Z over the torrent list. The question is now
asked three ways — whether touch events can arrive, whether touch is the
primary input, and whether the browser fires contextmenu — so a touchscreen
laptop keeps its keyboard shortcuts. (#3386) - Tapping a status bar pane opens its title in a bubble above the finger and
leaves it there until the next tap. A title tooltip never opens on a touch
screen, so the disk space, CPU load and port status panes gave nothing back.
(#3361)
Plugins
- erasedata: "Remove and delete data" publishes its deletion list only for an
erase rtorrent confirmed. The list was published before rtorrent was asked and
the collector never checked whether the hash was gone, so a download rtorrent
was still seeding or writing could have its files unlinked underneath it. A
request that faults or goes unanswered now leaves no list and a log line.
(#3377) - mobile: add-torrent results are reported again. Since the result became data
the plugin's parser did not match it, so a successful upload and a refused one
both finished silently, the form was not cleared, and a lost response left the
controls disabled. (#3367) - seedingtime: an opt-in highlight marks torrents finished for longer than a
chosen time, and downloads already complete before the plugin first ran get
their seeding time filled in from addtime. No event fires for those again, so
the Finished column, the highlight and the feeds plugin's pubDate had been
permanently empty for them. (#3319, #3354) - dump: the plugin says why it could not read a torrent. Five conditions all
arrived as "Can't retrieve information", and a failed request started a task
on an unset filename. The permissions case names the path and the account that
was refused. (#3384) - create: the transmissioncli backend is removed — it ran transmission-cli -n,
which no Transmission version still accepts, then reported a failure to
correct a torrent that had never been created. transmissioncreate now looks up
transmission-create, the name Transmission installs, instead of disabling
itself over a command that does not exist. (#3385, #3387) - extsearch: the Add torrent dialog opened from a search result offers the
existing labels, as the main dialog does. (#3365)
Localization
- Norwegian Nynorsk (nn) is available, for the core interface and every bundled
plugin, and the Norwegian (no) translation is updated. (#3356, #3357, #3378) - Browser language tags are matched one subtag at a time, longest first, against
an alias table following what CLDR resolves each tag to, so nb, nb-NO, pt, zh,
zh-Hans-CN, zh-SG, zh-Hant-TW, zh-HK and zh-MO reach a translation instead of
falling back to English. Aliases stay out of the language selector. (#3382)
What's Changed
- Seedingtime: Add optional row highlight for finished torrents by @mariotacke in #3319
- Say which class a refused cache file names by @xirvik in #3351
- Authenticate the editorconfig-checker download by @xirvik in #3352
- build(deps-dev): bump brace-expansion from 1.1.18 to 1.1.21 in /tests by @dependabot[bot] in #3353
- Feature/seedingtime backfill by @xirvik in #3354
- Update Norwegian translations and fix language file syntax by @jakobbg in #3356
- feat(i18n): add Norwegian Nynorsk language support by @jakobbg in #3357
- Skip the register_argc_argv check on PHP 8.5 by @noctuum in #3359
- Feature/status bar touch tooltip by @xirvik in #3361
- Ci/php 8.5 by @xirvik in #3362
- Keep profile-mask diagnostics out of HTTP responses by @IvanShift in #3368
- Escape normalized torrent names before adding label markup by @IvanShift in #3366
- loginmgr: send YggTorrent credentials only to its configured origin by @IvanShift in #3376
- erasedata: publish a list only for an erase rtorrent confirmed by @IvanShift in #3377
- Preserve torrent authorship when editing decoded metainfo by @IvanShift in #3369
- Read the Host header as an authority in the CSRF check by @IvanShift in #3374
- cache: compare the bytes when a cache file's stamp repeats by @IvanShift in #3375
- tests: exec the built-in server fixtures so proc_terminate stops them by @IvanShift in #3371
- tests: run the PHP suite from any directory and refuse an empty one by @IvanShift in #3372
- tests: make the TimeFormat strftime check pass in every time zone by @IvanShift in #3373
- Add Nynorsk translations for all plugins by @jakobbg in #3378
- extsearch: offer existing labels in the Load dialog by @fejese in #3365
- Snoopy: bound the inflated size of a gzip response body by @IvanShift in #3370
- Make Snoopy's response-body bound configurable by @xirvik in #3379
- Probe rtorrent when the settings cache is empty by @xirvik in #3380
- Stop a torrent label being parsed as markup by @xirvik in #3381
- Fix mobile add-torrent result notifications by @IvanShift in #3367
- I18n locale and parity by @xirvik in #3382
- Test gaps by @xirvik in #3383
- Say why the dump plugin could not read a torrent by @xirvik in #3384
- Five small fixes by @xirvik in #3385
- Detect touch with current capability tests by @xirvik in #3386
- Fix/create external programs by @xirvik in #3387
- Bump version to 5.3.17 by @xirvik in #3388
New Contributors
Full Changelog: v5.3.16...v5.3.17