From 62c113a062493a8f14d485a691679f3a5c62815a Mon Sep 17 00:00:00 2001 From: Chengzhong Wu Date: Fri, 14 Oct 2022 01:25:33 +0800 Subject: [PATCH] perf_hooks: convert maxSize to IDL value in setResourceTimingBufferSize ECMAScript values of WebIDL interface parameters should be converted to IDL representatives before the actual implementation, as defined in step 11.5 of the WebIDL Overload resolution algorithm. Refs: https://webidl.spec.whatwg.org/#dfn-create-operation-function Refs: https://webidl.spec.whatwg.org/#es-overloads PR-URL: https://github.com/nodejs/node/pull/44902 Reviewed-By: James M Snell --- lib/internal/perf/observe.js | 3 + .../test-internal-webidl-converttoint.js | 58 +++++++++++++++++++ ...st-performance-resourcetimingbuffersize.js | 11 ++++ 3 files changed, 72 insertions(+) create mode 100644 test/parallel/test-internal-webidl-converttoint.js diff --git a/lib/internal/perf/observe.js b/lib/internal/perf/observe.js index 91067331aba2c4..c170b14805552e 100644 --- a/lib/internal/perf/observe.js +++ b/lib/internal/perf/observe.js @@ -66,6 +66,7 @@ const { const { inspect } = require('util'); const { now } = require('internal/perf/utils'); +const { convertToInt } = require('internal/webidl'); const kDispatch = Symbol('kDispatch'); const kMaybeBuffer = Symbol('kMaybeBuffer'); @@ -430,6 +431,8 @@ function bufferResourceTiming(entry) { // https://w3c.github.io/resource-timing/#dom-performance-setresourcetimingbuffersize function setResourceTimingBufferSize(maxSize) { + // unsigned long + maxSize = convertToInt('maxSize', maxSize, 32); // If the maxSize parameter is less than resource timing buffer current // size, no PerformanceResourceTiming objects are to be removed from the // performance entry buffer. diff --git a/test/parallel/test-internal-webidl-converttoint.js b/test/parallel/test-internal-webidl-converttoint.js new file mode 100644 index 00000000000000..7e7c024387a0ec --- /dev/null +++ b/test/parallel/test-internal-webidl-converttoint.js @@ -0,0 +1,58 @@ +// Flags: --expose-internals +'use strict'; + +require('../common'); +const assert = require('assert'); +const { convertToInt, evenRound } = require('internal/webidl'); + +assert.strictEqual(evenRound(-0.5), 0); +assert.strictEqual(evenRound(0.5), 0); +assert.strictEqual(evenRound(-1.5), -2); +assert.strictEqual(evenRound(1.5), 2); +assert.strictEqual(evenRound(3.4), 3); +assert.strictEqual(evenRound(4.6), 5); +assert.strictEqual(evenRound(5), 5); +assert.strictEqual(evenRound(6), 6); + +// https://webidl.spec.whatwg.org/#abstract-opdef-converttoint +assert.strictEqual(convertToInt('x', 0, 64), 0); +assert.strictEqual(convertToInt('x', 1, 64), 1); +assert.strictEqual(convertToInt('x', -0.5, 64), 0); +assert.strictEqual(convertToInt('x', -0.5, 64, { signed: true }), 0); +assert.strictEqual(convertToInt('x', -1.5, 64, { signed: true }), -1); + +// EnforceRange +const OutOfRangeValues = [ NaN, Infinity, -Infinity, 2 ** 53, -(2 ** 53) ]; +for (const value of OutOfRangeValues) { + assert.throws(() => convertToInt('x', value, 64, { enforceRange: true }), { + name: 'TypeError', + code: 'ERR_INVALID_ARG_VALUE', + }); +} + +// Out of range: clamp +assert.strictEqual(convertToInt('x', NaN, 64, { clamp: true }), 0); +assert.strictEqual(convertToInt('x', Infinity, 64, { clamp: true }), Number.MAX_SAFE_INTEGER); +assert.strictEqual(convertToInt('x', -Infinity, 64, { clamp: true }), 0); +assert.strictEqual(convertToInt('x', -Infinity, 64, { signed: true, clamp: true }), Number.MIN_SAFE_INTEGER); +assert.strictEqual(convertToInt('x', 0x1_0000_0000, 32, { clamp: true }), 0xFFFF_FFFF); +assert.strictEqual(convertToInt('x', 0xFFFF_FFFF, 32, { clamp: true }), 0xFFFF_FFFF); +assert.strictEqual(convertToInt('x', 0x8000_0000, 32, { clamp: true, signed: true }), 0x7FFF_FFFF); +assert.strictEqual(convertToInt('x', 0xFFFF_FFFF, 32, { clamp: true, signed: true }), 0x7FFF_FFFF); +assert.strictEqual(convertToInt('x', 0.5, 64, { clamp: true }), 0); +assert.strictEqual(convertToInt('x', 1.5, 64, { clamp: true }), 2); +assert.strictEqual(convertToInt('x', -0.5, 64, { clamp: true }), 0); +assert.strictEqual(convertToInt('x', -0.5, 64, { signed: true, clamp: true }), 0); +assert.strictEqual(convertToInt('x', -1.5, 64, { signed: true, clamp: true }), -2); + +// Out of range, step 8. +assert.strictEqual(convertToInt('x', NaN, 64), 0); +assert.strictEqual(convertToInt('x', Infinity, 64), 0); +assert.strictEqual(convertToInt('x', -Infinity, 64), 0); +assert.strictEqual(convertToInt('x', 0x1_0000_0000, 32), 0); +assert.strictEqual(convertToInt('x', 0x1_0000_0001, 32), 1); +assert.strictEqual(convertToInt('x', 0xFFFF_FFFF, 32), 0xFFFF_FFFF); + +// Out of range, step 11. +assert.strictEqual(convertToInt('x', 0x8000_0000, 32, { signed: true }), -0x8000_0000); +assert.strictEqual(convertToInt('x', 0xFFF_FFFF, 32, { signed: true }), 0xFFF_FFFF); diff --git a/test/parallel/test-performance-resourcetimingbuffersize.js b/test/parallel/test-performance-resourcetimingbuffersize.js index eba46fa3ce95e0..3b9e77799b3b25 100644 --- a/test/parallel/test-performance-resourcetimingbuffersize.js +++ b/test/parallel/test-performance-resourcetimingbuffersize.js @@ -30,6 +30,17 @@ const initiatorType = ''; const cacheMode = ''; async function main() { + // Invalid buffer size values are converted to 0. + const invalidValues = [ null, undefined, true, false, -1, 0.5, Infinity, NaN, '', 'foo', {}, [], () => {} ]; + for (const value of invalidValues) { + performance.setResourceTimingBufferSize(value); + performance.markResourceTiming(timingInfo, requestedUrl, initiatorType, globalThis, cacheMode); + assert.strictEqual(performance.getEntriesByType('resource').length, 0); + performance.clearResourceTimings(); + } + // Wait for the buffer full event to be cleared. + await waitBufferFullEvent(); + performance.setResourceTimingBufferSize(1); performance.markResourceTiming(timingInfo, requestedUrl, initiatorType, globalThis, cacheMode); // Trigger a resourcetimingbufferfull event.