From cc729e8c405fa8dfc92f9ec1488b5dcea43abf0a Mon Sep 17 00:00:00 2001 From: DeepView Autofix <276251120+deepview-autofix@users.noreply.github.com> Date: Mon, 20 Apr 2026 06:50:54 +0300 Subject: [PATCH] lib: fix `evenRound` sign for fractional values in (-1, 1) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `evenRound` derived the rounding direction from `MathSign(i)` where `i = integerPart(x)`. For any `x` whose truncated integer part is zero (e.g. `0.7`, `-0.7`), `sign` was `0`, so the non-halfway branch returned `i + sign === 0` instead of rounding away from zero. This produced incorrect `[Clamp]` WebIDL integer conversions for fractional inputs in `(-1, 0) ∪ (0, 1)` that are not exactly `±0.5`, observable e.g. via `new Blob([Uint8Array.of(1,2,3)]).slice(-0.9999999)` returning the whole blob instead of a 1-byte slice. Use `MathSign(x)` so the rounding direction follows the sign of the original value. Co-Authored-By: Claude Co-Authored-By: DeepView Autofix <276251120+deepview-autofix@users.noreply.github.com> Co-Authored-By: Nikita Skovoroda Signed-off-by: Nikita Skovoroda --- lib/internal/webidl.js | 2 +- test/parallel/test-internal-webidl-converttoint.js | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/internal/webidl.js b/lib/internal/webidl.js index d6bfea8e8479fa..e8dd6a675273c8 100644 --- a/lib/internal/webidl.js +++ b/lib/internal/webidl.js @@ -80,7 +80,7 @@ function evenRound(x) { // Convert -0 to +0. const i = integerPart(x) + 0; const reminder = MathAbs(x % 1); - const sign = MathSign(i); + const sign = MathSign(x); if (reminder === 0.5) { return i % 2 === 0 ? i : i + sign; } diff --git a/test/parallel/test-internal-webidl-converttoint.js b/test/parallel/test-internal-webidl-converttoint.js index 7e7c024387a0ec..0134700be7c49e 100644 --- a/test/parallel/test-internal-webidl-converttoint.js +++ b/test/parallel/test-internal-webidl-converttoint.js @@ -13,6 +13,13 @@ assert.strictEqual(evenRound(3.4), 3); assert.strictEqual(evenRound(4.6), 5); assert.strictEqual(evenRound(5), 5); assert.strictEqual(evenRound(6), 6); +// Fractional values in (-1, 0) ∪ (0, 1) whose truncated integer part is 0. +assert.strictEqual(evenRound(0.7), 1); +assert.strictEqual(evenRound(-0.7), -1); +assert.strictEqual(evenRound(0.3), 0); +assert.strictEqual(evenRound(-0.3), 0); +assert.strictEqual(convertToInt('x', -0.9999999, 64, { signed: true, clamp: true }), -1); +assert.strictEqual(convertToInt('x', 0.9999999, 64, { clamp: true }), 1); // https://webidl.spec.whatwg.org/#abstract-opdef-converttoint assert.strictEqual(convertToInt('x', 0, 64), 0);