Skip to content

formatBytes can print "1024 KiB" #92

Description

@DuoshouCom

packages/console/src/lib/format.ts:14-19:

  while (value >= 1024 && unit < units.length - 1) {
    value /= 1024;
    unit += 1;
  }
  const digits = value >= 100 || unit === 0 ? 0 : value >= 10 ? 1 : 2;
  return `${value.toFixed(digits)} ${units[unit]}`;

The loop stops while value < 1024, but the rounding happens after, and rounding can push it back to 1024. Anything in [1023.5, 1024) at a given unit renders as 1024 <that unit> instead of 1.00 <next unit>.

Worked example: formatBytes(1048063) → 1048063/1024 = 1023.499 KiB → not >= 1024, loop exits → digits is 0 because value >= 100"1023 KiB", fine. But formatBytes(1048300) → 1023.73 KiB → "1024 KiB". Same at every boundary: 1073215488 bytes prints "1024 MiB", and so on up to "1024 TiB".

This is user-visible in three places that all use this helper on real filesystem numbers, so hitting the half-KiB-below-a-power window is routine rather than exotic:

  • FileTreePane.tsx:162 — every file size in the tree
  • FilePreviewPane.tsx:263 — the preview header
  • the disks/metrics cards under features/overview

It reads as a bug to anyone who knows the units ("1024 MiB" is a thing you never see from du -h), and it also breaks column alignment since the string is one character wider than every neighbour.

Fix is one line — re-check after choosing the precision:

let digits = value >= 100 || unit === 0 ? 0 : value >= 10 ? 1 : 2;
if (Number(value.toFixed(digits)) >= 1024 && unit < units.length - 1) {
  value /= 1024;
  unit += 1;
  digits = 2;
}

Worth a table-driven unit test while you are in there; I did not find one for this module, and the sibling pctOf at line 23 has the same exposure to boundary inputs.

Activity

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

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions