From e72d403a30a1718c8b3457cf1e17e1060a73b035 Mon Sep 17 00:00:00 2001 From: Jerod Hodgkin Date: Wed, 22 Jul 2026 23:40:28 +0000 Subject: [PATCH] Guard formatCapacity against NaN/negative/used>total and a rounding edge case Adversarial review of PR #20 flagged two narrow edge cases: malformed remote-script output could produce NaN and render literally, and a used>total race could show e.g. "510/500 GB". Also fixed a cosmetic rounding bug where a value like 99.96 took the one-decimal branch and toFixed(1) rounded it up to "100.0" instead of "100". Co-Authored-By: Claude Sonnet 5 --- apps/web/src/components/HostCard.tsx | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/apps/web/src/components/HostCard.tsx b/apps/web/src/components/HostCard.tsx index a8c9145..5f356a6 100644 --- a/apps/web/src/components/HostCard.tsx +++ b/apps/web/src/components/HostCard.tsx @@ -18,7 +18,10 @@ function Bar({ label, pct }: { label: string; pct: number | null }) { // Picks a unit off total capacity, applies it to both sides so "used/total" // reads as e.g. "12.3/32 GB" instead of mixing MB and GB. function formatCapacity(used: number | null, total: number | null): string | null { - if (used === null || total === null || total <= 0) return null; + if (used === null || total === null || !Number.isFinite(used) || !Number.isFinite(total) || total <= 0) { + return null; + } + const clampedUsed = Math.min(Math.max(used, 0), total); const units: [number, string][] = [ [1024 ** 4, "TB"], [1024 ** 3, "GB"], @@ -26,8 +29,13 @@ function formatCapacity(used: number | null, total: number | null): string | nul [1024, "KB"], ]; const [divisor, unit] = units.find(([d]) => total >= d) ?? [1, "B"]; - const fmt = (n: number) => (n / divisor >= 100 ? (n / divisor).toFixed(0) : (n / divisor).toFixed(1)); - return `${fmt(used)}/${fmt(total)} ${unit}`; + // Decide decimal places off the *rounded* value -- otherwise e.g. 99.96 + // takes the one-decimal branch and toFixed(1) rounds it up to "100.0". + const fmt = (n: number) => { + const scaled = n / divisor; + return Math.round(scaled) >= 100 ? scaled.toFixed(0) : scaled.toFixed(1); + }; + return `${fmt(clampedUsed)}/${fmt(total)} ${unit}`; } function formatUptime(sec: number | null): string {