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 get
set set
includes: [nativeFunctionMatcher.js, fnGlobalObject.js] includes: [nativeFunctionMatcher.js, wellKnownIntrinsicObjects.js]
features: [arrow-function, Reflect] features: [arrow-function, Reflect]
---*/ ---*/
@ -50,70 +50,7 @@ function visit(ns, path) {
}); });
} }
[ WellKnownIntrinsicObjects.forEach((intrinsic) => {
// Function Properties of the Global Object visit(intrinsic.value, intrinsic.name);
'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}`);
}); });
assert.notSameValue(visited.length, 0); assert.notSameValue(visited.length, 0);

View File

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