Skip to content

Commit

Permalink
feat(getStaticValue): added more safe calls (#76)
Browse files Browse the repository at this point in the history
  • Loading branch information
RunDevelopment committed Mar 17, 2023
1 parent 5b1d059 commit e916558
Show file tree
Hide file tree
Showing 2 changed files with 143 additions and 0 deletions.
57 changes: 57 additions & 0 deletions src/get-static-value.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,24 @@ const builtinNames = Object.freeze(
const callAllowed = new Set(
[
Array.isArray,
Array.of,
Array.prototype.at,
Array.prototype.concat,
Array.prototype.entries,
Array.prototype.every,
Array.prototype.filter,
Array.prototype.find,
Array.prototype.findIndex,
Array.prototype.flat,
Array.prototype.includes,
Array.prototype.indexOf,
Array.prototype.join,
Array.prototype.keys,
Array.prototype.lastIndexOf,
Array.prototype.slice,
Array.prototype.some,
Array.prototype.toString,
Array.prototype.values,
typeof BigInt === "function" ? BigInt : undefined,
Boolean,
Date,
Expand All @@ -78,6 +96,12 @@ const callAllowed = new Set(
isFinite,
isNaN,
isPrototypeOf,
Map,
Map.prototype.entries,
Map.prototype.get,
Map.prototype.has,
Map.prototype.keys,
Map.prototype.values,
...Object.getOwnPropertyNames(Math)
.filter((k) => k !== "random")
.map((k) => Math[k])
Expand All @@ -87,6 +111,10 @@ const callAllowed = new Set(
Number.isNaN,
Number.parseFloat,
Number.parseInt,
Number.prototype.toExponential,
Number.prototype.toFixed,
Number.prototype.toPrecision,
Number.prototype.toString,
Object,
Object.entries,
Object.is,
Expand All @@ -98,10 +126,39 @@ const callAllowed = new Set(
parseFloat,
parseInt,
RegExp,
Set,
Set.prototype.entries,
Set.prototype.has,
Set.prototype.keys,
Set.prototype.values,
String,
String.fromCharCode,
String.fromCodePoint,
String.raw,
String.prototype.at,
String.prototype.charAt,
String.prototype.charCodeAt,
String.prototype.codePointAt,
String.prototype.concat,
String.prototype.endsWith,
String.prototype.includes,
String.prototype.indexOf,
String.prototype.lastIndexOf,
String.prototype.normalize,
String.prototype.padEnd,
String.prototype.padStart,
String.prototype.slice,
String.prototype.startsWith,
String.prototype.substr,
String.prototype.substring,
String.prototype.toLowerCase,
String.prototype.toString,
String.prototype.toUpperCase,
String.prototype.trim,
String.prototype.trimEnd,
String.prototype.trimLeft,
String.prototype.trimRight,
String.prototype.trimStart,
Symbol.for,
Symbol.keyFor,
unescape,
Expand Down
86 changes: 86 additions & 0 deletions test/get-static-value.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,17 @@ describe("The 'getStaticValue' function", () => {
{ code: "1 ^ 15", expected: { value: 14 } },
{ code: "3 & 2", expected: { value: 2 } },
{ code: "a + 1", expected: null },
{
code: "(123.456).toExponential()",
expected: { value: "1.23456e+2" },
},
{ code: "(123.456).toExponential(3)", expected: { value: "1.235e+2" } },
{ code: "(123.456).toFixed()", expected: { value: "123" } },
{ code: "(123.456).toFixed(1)", expected: { value: "123.5" } },
{ code: "(123.456).toPrecision()", expected: { value: "123.456" } },
{ code: "(123.456).toPrecision(2)", expected: { value: "1.2e+2" } },
{ code: "(123.456).toString()", expected: { value: "123.456" } },
{ code: "(123).toString(16)", expected: { value: "7b" } },
{ code: "String(7)", expected: { value: "7" } },
{ code: "Math.round(0.7)", expected: { value: 1 } },
{ code: "Math['round'](0.4)", expected: { value: 0 } },
Expand Down Expand Up @@ -84,6 +95,50 @@ describe("The 'getStaticValue' function", () => {
{ code: "Object.xxx", expected: { value: undefined } },
{ code: "new Array(2)", expected: null },
{ code: "new Array(len)", expected: null },
{ code: "Array.of()", expected: { value: [] } },
{ code: "Array.of(1)", expected: { value: [1] } },
{ code: "Array.of(1, 2)", expected: { value: [1, 2] } },
{
code: "[0,1,2].at(-1)",
expected: Array.prototype.at ? { value: 2 } : null,
},
{
code: "[0,1,2].concat([3,4], [5])",
expected: { value: [0, 1, 2, 3, 4, 5] },
},
{ code: "[0,1,2].every(Boolean)", expected: { value: false } },
{ code: "[0,1,2].filter(Boolean)", expected: { value: [1, 2] } },
{ code: "[0,1,2].find((i) => i === 2)", expected: null },
{ code: "[0,1,2].findIndex((i) => i === 2)", expected: null },
{
code: "[-1, [0,1,2], [[4]]].flat()",
expected: { value: [-1, 0, 1, 2, [4]] },
},
{ code: "[0,1,2].includes(4)", expected: { value: false } },
{ code: "[0,1,2].indexOf(4)", expected: { value: -1 } },
{ code: "[0,1,2].join()", expected: { value: "0,1,2" } },
{ code: "[0,1,2].join('|')", expected: { value: "0|1|2" } },
{ code: "[1,1,1].lastIndexOf(1)", expected: { value: 2 } },
{ code: "[0,1,2].slice(1)", expected: { value: [1, 2] } },
{ code: "[0,1,2].some(Boolean)", expected: { value: true } },
{ code: "[0,1,2].toString()", expected: { value: "0,1,2" } },
{ code: "String([0,1,2])", expected: { value: "0,1,2" } },
{ code: "[...[0,1,,2].keys()]", expected: { value: [0, 1, 2, 3] } },
{
code: "[...[0,1,,2].values()]",
expected: { value: [0, 1, undefined, 2] },
},
{
code: "[...[0,1,,2].entries()]",
expected: {
value: [
[0, 0],
[1, 1],
[2, undefined],
[3, 2],
],
},
},
{ code: "({})", expected: { value: {} } },
{
code: "({a: 1, b: 2, c: 3})",
Expand All @@ -105,6 +160,12 @@ describe("The 'getStaticValue' function", () => {
{ code: "String.raw`\\unicode`", expected: { value: "\\unicode" } },
{ code: "`he${a}o`", expected: null }, //eslint-disable-line no-template-curly-in-string
{ code: "x`hello`", expected: null },
{ code: "' foo '.trim()", expected: { value: "foo" } },
{ code: "' foo '.trim().toUpperCase()", expected: { value: "FOO" } },
{ code: "' foo '.indexOf('f')", expected: { value: 2 } },
{ code: "' foo '.charAt(4)", expected: { value: "o" } },
{ code: "' foo '.charCodeAt(400)", expected: { value: NaN } },
{ code: "' foo '.repeat(1e12)", expected: null },
{ code: "-1", expected: { value: -1 } },
{ code: "+'1'", expected: { value: 1 } },
{ code: "!0", expected: { value: true } },
Expand Down Expand Up @@ -243,6 +304,31 @@ const aMap = Object.freeze({
code: "({'a': 1, 1e+1: 2, 2n: 3})",
expected: { value: { a: 1, 10: 2, 2: 3 } },
},
{
code: "new Set([1,2])",
expected: { value: new Set([1, 2]) },
},
{
code: "new Set([1,2]).has(2)",
expected: { value: true },
},
{
code: "new Map([[1,2], [4,6]])",
expected: {
value: new Map([
[1, 2],
[4, 6],
]),
},
},
{
code: "const m = new Map([[1,2], [4,6]]); m.get(1)",
expected: { value: 2 },
},
{
code: "const m = new Map([[1,2], [4,6]]); m.has(2)",
expected: { value: false },
},
...(semver.gte(eslint.Linter.version, "8.0.0")
? [
{
Expand Down

0 comments on commit e916558

Please sign in to comment.