Skip to content

Commit

Permalink
perf_hooks: convert maxSize to IDL value in setResourceTimingBufferSize
Browse files Browse the repository at this point in the history
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.

Backport-PR-URL: #45829
Refs: https://webidl.spec.whatwg.org/#dfn-create-operation-function
Refs: https://webidl.spec.whatwg.org/#es-overloads
PR-URL: #44902
Reviewed-By: James M Snell <jasnell@gmail.com>
  • Loading branch information
legendecas authored and ruyadorno committed Sep 1, 2023
1 parent 5260f53 commit 121f74c
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 0 deletions.
3 changes: 3 additions & 0 deletions lib/internal/perf/observe.js
Original file line number Diff line number Diff line change
Expand Up @@ -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');
Expand Down Expand Up @@ -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.
Expand Down
58 changes: 58 additions & 0 deletions test/parallel/test-internal-webidl-converttoint.js
Original file line number Diff line number Diff line change
@@ -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);
11 changes: 11 additions & 0 deletions test/parallel/test-performance-resourcetimingbuffersize.js
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down

0 comments on commit 121f74c

Please sign in to comment.