native function validator for your consideration

This commit is contained in:
Gus Caplan 2020-07-26 00:03:44 -05:00 committed by Rick Waldron
parent 156186aee2
commit 5f99d05c6a
4 changed files with 535 additions and 113 deletions

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,290 @@
// Copyright (C) 2018 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: |
An Array of all representable Well-Known Intrinsic Objects
defines: [WellKnownIntrinsicObjects]
---*/
const WellKnownIntrinsicObjects = [
{
name: '%AggregateError%',
source: 'AggregateError',
},
{
name: '%Array%',
source: 'Array',
},
{
name: '%ArrayBuffer%',
source: 'ArrayBuffer',
},
{
name: '%ArrayIteratorPrototype%',
source: 'Object.getPrototypeOf([][Symbol.iterator]())',
},
{
name: '%AsyncFromSyncIteratorPrototype%',
source: 'undefined',
},
{
name: '%AsyncFunction%',
source: '(async function() {}).constructor',
},
{
name: '%AsyncGeneratorFunction%',
source: 'Object.getPrototypeOf(async function * () {})',
},
{
name: '%AsyncIteratorPrototype%',
source: '((async function * () {})())[Symbol.asyncIterator]()',
},
{
name: '%Atomics%',
source: 'Atomics',
},
{
name: '%BigInt%',
source: 'BigInt',
},
{
name: '%BigInt64Array%',
source: 'BigInt64Array',
},
{
name: '%BigUint64Array%',
source: 'BigUint64Array',
},
{
name: '%Boolean%',
source: 'Boolean',
},
{
name: '%DataView%',
source: 'DataView',
},
{
name: '%Date%',
source: 'Date',
},
{
name: '%decodeURI%',
source: 'decodeURI',
},
{
name: '%decodeURIComponent%',
source: 'decodeURIComponent',
},
{
name: '%encodeURI%',
source: 'encodeURI',
},
{
name: '%encodeURIComponent%',
source: 'encodeURIComponent',
},
{
name: '%Error%',
source: 'Error',
},
{
name: '%eval%',
source: 'eval',
},
{
name: '%EvalError%',
source: 'EvalError',
},
{
name: '%FinalizationRegistry%',
source: 'FinalizationRegistry',
},
{
name: '%Float32Array%',
source: 'Float32Array',
},
{
name: '%Float64Array%',
source: 'Float64Array',
},
{
name: '%ForInIteratorPrototype%',
source: '',
},
{
name: '%Function%',
source: 'Function',
},
{
name: '%GeneratorFunction%',
source: 'Object.getPrototypeOf(function * () {})',
},
{
name: '%Int8Array%',
source: 'Int8Array',
},
{
name: '%Int16Array%',
source: 'Int16Array',
},
{
name: '%Int32Array%',
source: 'Int32Array',
},
{
name: '%isFinite%',
source: 'isFinite',
},
{
name: '%isNaN%',
source: 'isNaN',
},
{
name: '%IteratorPrototype%',
source: 'Object.getPrototypeOf(Object.getPrototypeOf([][Symbol.iterator]()))',
},
{
name: '%JSON%',
source: 'JSON',
},
{
name: '%Map%',
source: 'Map',
},
{
name: '%MapIteratorPrototype%',
source: 'Object.getPrototypeOf(new Map()[Symbol.iterator]())',
},
{
name: '%Math%',
source: 'Math',
},
{
name: '%Number%',
source: 'Number',
},
{
name: '%Object%',
source: 'Object',
},
{
name: '%parseFloat%',
source: 'parseFloat',
},
{
name: '%parseInt%',
source: 'parseInt',
},
{
name: '%Promise%',
source: 'Promise',
},
{
name: '%Proxy%',
source: 'Proxy',
},
{
name: '%RangeError%',
source: 'RangeError',
},
{
name: '%ReferenceError%',
source: 'ReferenceError',
},
{
name: '%Reflect%',
source: 'Reflect',
},
{
name: '%RegExp%',
source: 'RegExp',
},
{
name: '%RegExpStringIteratorPrototype%',
source: 'RegExp.prototype[Symbol.matchAll]("")',
},
{
name: '%Set%',
source: 'Set',
},
{
name: '%SetIteratorPrototype%',
source: 'Object.getPrototypeOf(new Set()[Symbol.iterator]())',
},
{
name: '%SharedArrayBuffer%',
source: 'SharedArrayBuffer',
},
{
name: '%String%',
source: 'String',
},
{
name: '%StringIteratorPrototype%',
source: 'Object.getPrototypeOf(new String()[Symbol.iterator]())',
},
{
name: '%Symbol%',
source: 'Symbol',
},
{
name: '%SyntaxError%',
source: 'SyntaxError',
},
{
name: '%ThrowTypeError%',
source: '(function() { "use strict"; return Object.getOwnPropertyDescriptor(arguments, "callee").get })()',
},
{
name: '%TypedArray%',
source: 'Object.getPrototypeOf(Uint8Array)',
},
{
name: '%TypeError%',
source: 'TypeError',
},
{
name: '%Uint8Array%',
source: 'Uint8Array',
},
{
name: '%Uint8ClampedArray%',
source: 'Uint8ClampedArray',
},
{
name: '%Uint16Array%',
source: 'Uint16Array',
},
{
name: '%Uint32Array%',
source: 'Uint32Array',
},
{
name: '%URIError%',
source: 'URIError',
},
{
name: '%WeakMap%',
source: 'WeakMap',
},
{
name: '%WeakRef%',
source: 'WeakRef',
},
{
name: '%WeakSet%',
source: 'WeakSet',
},
];
WellKnownIntrinsicObjects.forEach((wkio) => {
var actual;
try {
actual = new Function("return " + wkio.source)();
} catch (exception) {
// Nothing to do here.
}
wkio.value = actual;
});

View File

@ -16,7 +16,7 @@ info: |
get
set
includes: [nativeFunctionMatcher.js, fnGlobalObject.js]
includes: [nativeFunctionMatcher.js, wellKnownIntrinsicObjects.js]
features: [arrow-function, Reflect]
---*/
@ -50,70 +50,7 @@ function visit(ns, path) {
});
}
[
// Function Properties of the Global Object
'eval',
'isFinite',
'isNaN',
'parseFloat',
'parseInt',
'decodeURI',
'decodeURIComponent',
'encodeURI',
'encodeURIComponent',
// Constructor Properties of the Global Object
'AggregateError',
'Array',
'ArrayBuffer',
'Boolean',
'BigInt',
'BigInt64Array',
'BigUint64Array',
'DataView',
'Date',
'Error',
'EvalError',
'FinalizationRegistry',
'Float32Array',
'Float64Array',
'Function',
'Int8Array',
'Int16Array',
'Int32Array',
'Map',
'Number',
'Object',
'Promise',
'Proxy',
'RangeError',
'ReferenceError',
'RegExp',
'Set',
'SharedArrayBuffer',
'String',
'Symbol',
'SyntaxError',
'TypeError',
'Uint8Array',
'Uint8ClampedArray',
'Uint16Array',
'Uint32Array',
'URIError',
'WeakMap',
'WeakRef',
'WeakSet',
// Other Properties of the Global Object
'Atomics',
'JSON',
'Math',
'Reflect',
].forEach((n) => {
const ref = fnGlobalObject()[n];
if (ref === undefined) {
return;
}
visit(ref, `globalThis.${n}`);
WellKnownIntrinsicObjects.forEach((intrinsic) => {
visit(intrinsic.value, intrinsic.name);
});
assert.notSameValue(visited.length, 0);

View File

@ -8,42 +8,53 @@ description: >
includes: [nativeFunctionMatcher.js]
---*/
if (!NATIVE_FUNCTION_RE.test('function(){[native code]}')) {
$ERROR('expected string to pass: "function(){[native code]}"');
}
[
'function(){[native code]}',
'function(){ [native code] }',
'function ( ) { [ native code ] }',
'function a(){ [native code] }',
'function a(){ /* } */ [native code] }',
`function a() {
// test
[native code]
/* test */
}`,
'function(a, b = function() { []; }) { [native code] }',
'function [Symbol.xyz]() { [native code] }',
'function [x[y][z[d]()]]() { [native code] }',
'function ["]"] () { [native code] }',
'function [\']\'] () { [native code] }',
'/* test */ function() { [native code] }',
'function() { [native code] } /* test */',
'function() { [native code] } // test',
].forEach((s) => {
try {
validateNativeFunctionSource(s);
} catch (unused) {
$ERROR(`${JSON.stringify(s)} should pass`);
}
});
if (!NATIVE_FUNCTION_RE.test('function(){ [native code] }')) {
$ERROR('expected string to pass: "function(){ [native code] }"');
}
if (!NATIVE_FUNCTION_RE.test('function ( ) { [ native code ] }')) {
$ERROR('expected string to pass: "function ( ) { [ native code ] }"');
}
if (!NATIVE_FUNCTION_RE.test('function a(){ [native code] }')) {
$ERROR('expected string to pass: "function a(){ [native code] }"');
}
if (!NATIVE_FUNCTION_RE.test('function a(){ /* } */ [native code] }')) {
$ERROR('expected string to pass: "function a(){ /* } */ [native code] }"');
}
if (NATIVE_FUNCTION_RE.test('')) {
$ERROR('expected string to fail: ""');
}
if (NATIVE_FUNCTION_RE.test('native code')) {
$ERROR('expected string to fail: "native code"');
}
if (NATIVE_FUNCTION_RE.test('function(){}')) {
$ERROR('expected string to fail: "function(){}"');
}
if (NATIVE_FUNCTION_RE.test('function(){ "native code" }')) {
$ERROR('expected string to fail: "function(){ "native code" }"');
}
if (NATIVE_FUNCTION_RE.test('function(){ [] native code }')) {
$ERROR('expected string to fail: "function(){ [] native code }"');
}
[
'native code',
'function() {}',
'function(){ "native code" }',
'function(){ [] native code }',
'function()) { [native code] }',
'function(() { [native code] }',
'function []] () { [native code] }',
'function [[] () { [native code] }',
'function ["]] () { [native code] }',
'function [\']] () { [native code] }',
'function() { [native code] /* }',
'// function() { [native code] }',
].forEach((s) => {
let fail = false;
try {
validateNativeFunctionSource(s);
fail = true;
} catch (unused) {}
if (fail) {
$ERROR(`${JSON.stringify(s)} should fail`);
}
});