Skip to content

[BUG] On Firefox web interface crashes upon opening details dialog for torrent with too many cached pieces #809

Open

Description

@event

Web interface crashes on firefox (v. 152, but likely happens with older ones as well) when clicking "DETAILS" button for torrent with >10k pieces cached. Same torrent on Chromium show sad face in place of piece map

To Reproduce
Steps to reproduce the behavior:

  1. Configure big cache in torrserver, e.g. 5GB
  2. Add big torrent with a lot of pieces >10_000
  3. Open torrserver main page in Firefox
  4. Click "DETAILS" for this torrent
  5. Dialog opens, loading animation spins`` for a while, then white screen is shown
  6. On chromium, error canvas is shown in place of cache piece map (see attached screenshot)
    Expected behavior
    Normal details dialog is shown

Screenshots

Image

Desktop (please complete the following information):

  • OS: Ubuntu Linux 24.04
  • TorrServer Version MatriX.142
  • Browser: Firefox 152, Chromium 149.0.7827.114

Activity

  1. tsynik commented on Jul 28, 2026

    @tsynik
    Collaborator

    We will not limit pieces amount as exact parts which must be shown are unknown.

  2. reopened this on Jul 28, 2026
  3. nfvelten commented on Sep 1, 2026

    @nfvelten
    Contributor

    I tried to pin this down and ended up ruling out the obvious cause, so posting the measurements rather than a patch.

    The map's canvas is sized in TorrentCache/index.jsx:

    const piecesInOneRow = Math.floor(canvasWidth / pieceSizeWithGap)   // 14 + 3 = 17
    const height = Math.ceil(source.length / piecesInOneRow) * pieceSizeWithGap

    Measured canvas limits here (Chromium 6.1 and LibreWolf, Firefox engine): max height 65535 in both, max square side 16384 in Chromium and 23168 in Firefox.

    At a normal dialog width that is nowhere near the limit:

    pieces        320      480      640      900     1200     1600
     10000       9452     6086     4607     3281     2431     1819
     25000      23613    15181    11492     8177     6086     4522
     50000      47226    30362    22984    16354    12155     9044
    

    So 10k pieces in a 900px dialog is a 3281px canvas, which allocates fine. Rebuilding the map and redrawing costs about 83 ms per poll at 10k pieces and 161 ms at 50k, which is sluggish but not fatal. Neither explains a white screen.

    What does break is a narrow measured width, because piecesInOneRow collapses and the height explodes:

    N=10000   breaks once width <= 50px
    N=25000   breaks once width <= 118px
    N=50000   breaks once width <= 220px
    

    and those sizes genuinely fail to allocate, verified rather than assumed:

    canvas 900x3281   usable = true
    canvas 51x56117   usable = true
    canvas 221x66079  usable = false
    canvas 900x100000 usable = false
    

    There is also a latent divide-by-zero next to it. For any canvasWidth between 1 and 16, piecesInOneRow is 0, so height becomes Infinity. The if (!canvasWidth || !height) return guard does not catch it because Infinity is truthy, and every x then comes out NaN via i % 0. Chromium silently clamps that canvas to height 0, so the map just renders blank.

    That would fit "dialog opens, spinner, then white screen" if the width is measured while the dialog is still animating open, since react-measure reports the intermediate size. But I could not confirm that is what you hit, because at a steady 900px your 10k pieces should be fine.

    @event could you check, with the DETAILS dialog open on the problem torrent: the torrent's total piece count (not just cached), your window width, and devicePixelRatio? That would say whether this is the narrow-width path or something else.

    Either way both look worth guarding: floor piecesInOneRow at 1, and cap the canvas height, shrinking the drawn piece size to fit instead of growing the canvas. That keeps every piece on screen, so it does not run into the objection above about limiting the piece count. Happy to send that as a PR if you want it.

  4. mikilion commented on Nov 3, 2026

    @mikilion

    Here are the requested diagnostic details captured from Firefox:

    • Window width (window.innerWidth): 2287
    • Device pixel ratio (window.devicePixelRatio): 0.8955223880597015
    • Total piece count (PiecesCount): 1366

    Console Error Log

    DOMException: CanvasRenderingContext2D.translate: Canvas is already in error state.
        qe index.jsx:89
        qe index.jsx:65
        Bl React
        unstable_runWithPriority scheduler.production.min.js:18
        React 4
        unstable_runWithPriority scheduler.production.min.js:18
        React 4
        unstable_runWithPriority scheduler.production.min.js:18
        React 3
        F scheduler.production.min.js:16
        onmessage scheduler.production.min.js:12
        EventHandlerNonNull* scheduler.production.min.js:12
        l (index):1
        <anonymous> index.js:4
        l (index):1
        <anonymous> React
        l (index):1
        <anonymous> React
        l (index):1
        447 main.4e5714d6.chunk.js:1
        l (index):1
        t (index):1
        r (index):1
        <anonymous> main.4e5714d6.chunk.js:1
    2.7912f39c.chunk.js:2:1017670
    Uncaught DOMException: CanvasRenderingContext2D.translate: Canvas is already in error state.
        qe index.jsx:89
        qe index.jsx:65
        Bl React
        unstable_runWithPriority scheduler.production.min.js:18
        React 4
        unstable_runWithPriority scheduler.production.min.js:18
        React 4
        unstable_runWithPriority scheduler.production.min.js:18
        React 3
        F scheduler.production.min.js:16
        onmessage scheduler.production.min.js:12
        EventHandlerNonNull* scheduler.production.min.js:12
        l (index):1
        <anonymous> index.js:4
        l (index):1
        <anonymous> React
        l (index):1
        <anonymous> React
        l (index):1
        447 main.4e5714d6.chunk.js:1
        l (index):1
        t (index):1
        r (index):1
        <anonymous> main.4e5714d6.chunk.js:1
    main.4e5714d6.chunk.js:1:311223
    
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions