diff --git a/lib/web/webidl/index.js b/lib/web/webidl/index.js index e5ee5cbb6e7..05a6a4bce58 100644 --- a/lib/web/webidl/index.js +++ b/lib/web/webidl/index.js @@ -188,10 +188,10 @@ webidl.util.ConvertToInt = function (V, bitLength, signedness, flags) { } else { // 3. Otherwise: - // 1. Let lowerBound be -2^bitLength − 1. - lowerBound = Math.pow(-2, bitLength) - 1 + // 1. Let lowerBound be -2^(bitLength − 1). + lowerBound = -Math.pow(2, bitLength - 1) - // 2. Let upperBound be 2^bitLength − 1 − 1. + // 2. Let upperBound be 2^(bitLength − 1) − 1. upperBound = Math.pow(2, bitLength - 1) - 1 } @@ -270,9 +270,9 @@ webidl.util.ConvertToInt = function (V, bitLength, signedness, flags) { // 10. Set x to x modulo 2^bitLength. x = x % Math.pow(2, bitLength) - // 11. If signedness is "signed" and x ≥ 2^bitLength − 1, + // 11. If signedness is "signed" and x ≥ 2^(bitLength − 1), // then return x − 2^bitLength. - if (signedness === 'signed' && x >= Math.pow(2, bitLength) - 1) { + if (signedness === 'signed' && x >= Math.pow(2, bitLength - 1)) { return x - Math.pow(2, bitLength) } diff --git a/test/webidl/util.js b/test/webidl/util.js index 3860154d35d..30b01a0a745 100644 --- a/test/webidl/util.js +++ b/test/webidl/util.js @@ -125,4 +125,23 @@ test('webidl.util.ConvertToInt(V)', () => { } assert.equal(ConvertToInt(111, 2, 'signed'), -1) + + // https://webidl.spec.whatwg.org/#abstract-opdef-converttoint + // For N-bit signed integers, lowerBound is -2^(N-1) and the modulo wrap + // threshold (step 11) is 2^(N-1). + assert.equal(ConvertToInt(128, 8, 'signed'), -128, '8-bit signed wrap at 128') + assert.equal(ConvertToInt(200, 8, 'signed'), -56, '8-bit signed wrap at 200') + assert.equal( + ConvertToInt(-128, 8, 'signed', webidl.attributes.EnforceRange), + -128, + '8-bit signed EnforceRange lower bound' + ) + assert.throws(() => { + ConvertToInt(-129, 8, 'signed', webidl.attributes.EnforceRange) + }, TypeError, '8-bit signed EnforceRange below lower bound throws') + assert.equal( + ConvertToInt(-(2 ** 31), 32, 'signed', webidl.attributes.EnforceRange), + -(2 ** 31), + '32-bit signed EnforceRange lower bound' + ) })