@@ -660,10 +660,21 @@ /** | ||
| * @param {Function} relative The function before the invocation point. | ||
| * @returns {string} The invocation location. | ||
| * @returns {{ sourceFile: string; sourceLine: number; sourceColumn: number; }} The invocation location. | ||
| */ | ||
| function getInvocationLocation(relative = getInvocationLocation) { | ||
| const dummyObject = {}; | ||
| Error.captureStackTrace(dummyObject, relative); | ||
| const { stack } = dummyObject; | ||
| return stack.split("\n")[1].replace(/.*?\(/u, "").replace(/\)$/u, ""); | ||
| let location; | ||
| const { prepareStackTrace } = Error; | ||
| Error.prepareStackTrace = (_, [callSite]) => { | ||
| location = { | ||
| sourceFile: | ||
| callSite.getFileName() ?? | ||
| `${callSite.getEvalOrigin()}, <anonymous>`, | ||
| sourceLine: callSite.getLineNumber() ?? 1, | ||
| sourceColumn: callSite.getColumnNumber() ?? 1, | ||
| }; | ||
| }; | ||
| Error.captureStackTrace(dummyObject, relative); // invoke Error.prepareStackTrace in Bun | ||
| void dummyObject.stack; // invoke Error.prepareStackTrace in Node.js | ||
| Error.prepareStackTrace = prepareStackTrace; | ||
| return location; | ||
| } | ||
@@ -681,10 +692,6 @@ | ||
| if (testLocations === null) { | ||
| let [sourceFile, sourceLine = "1", sourceColumn = "1"] = | ||
| invocationLocation | ||
| .replace(/:\\/u, "\\\\") // Windows workaround for C:\\ | ||
| .split(":"); | ||
| sourceFile = sourceFile.replace(/\\\\/u, ":\\"); | ||
| sourceLine = Number(sourceLine); | ||
| sourceColumn = Number(sourceColumn); | ||
| testLocations = { root: invocationLocation }; | ||
| const { sourceFile, sourceLine, sourceColumn } = invocationLocation; | ||
| testLocations = { | ||
| root: `${sourceFile}:${sourceLine}:${sourceColumn}`, | ||
| }; | ||
@@ -705,6 +712,6 @@ if (existsSync(sourceFile)) { | ||
| const validStartIndex = content.findIndex(line => | ||
| /\bvalid:/u.test(line), | ||
| /\bvalid\s*:/u.test(line), | ||
| ); | ||
| const invalidStartIndex = content.findIndex(line => | ||
| /\binvalid:/u.test(line), | ||
| /\binvalid\s*:/u.test(line), | ||
| ); | ||
@@ -711,0 +718,0 @@ |
+89
-24
@@ -349,31 +349,96 @@ /** | ||
| /** | ||
| * Checks if a variable is inside the initializer of scopeVar. | ||
| * Finds the uppermost expression node that can evaluate to the given one. | ||
| * | ||
| * To avoid reporting at declarations such as `var a = function a() {};`. | ||
| * But it should report `var a = function(a) {};` or `var a = function() { function a() {} };`. | ||
| * @param {Object} variable The variable to check. | ||
| * @param {Object} scopeVar The scope variable to look for. | ||
| * @returns {boolean} Whether or not the variable is inside initializer of scopeVar. | ||
| * Examples: | ||
| * If given `a` in `a || foo`, it returns the `a || foo` node. | ||
| * If given `a` in `foo ? a : bar`, it returns the `foo ? a : bar` node. | ||
| * If given `a` in `foo ? bar : (baz && a)`, it returns the `foo ? bar : (baz && a)` node. | ||
| * If given `a` in `a ? foo : bar`, it returns the `a` node. | ||
| * If given `a` in `foo(a)`, it returns the `a` node. | ||
| * @param {ASTNode} expression The expression node to unwrap. | ||
| * @returns {ASTNode} The uppermost ancestor that can evaluate to the given node | ||
| * or the given node if there is no such ancestor. | ||
| */ | ||
| function isOnInitializer(variable, scopeVar) { | ||
| const outerScope = scopeVar.scope; | ||
| const outerDef = scopeVar.defs[0]; | ||
| const outer = outerDef && outerDef.parent && outerDef.parent.range; | ||
| const innerScope = variable.scope; | ||
| const innerDef = variable.defs[0]; | ||
| const inner = innerDef && innerDef.name.range; | ||
| function unwrapExpression(expression) { | ||
| const { parent } = expression; | ||
| return ( | ||
| outer && | ||
| inner && | ||
| outer[0] < inner[0] && | ||
| inner[1] < outer[1] && | ||
| ((innerDef.type === "FunctionName" && | ||
| innerDef.node.type === "FunctionExpression") || | ||
| innerDef.node.type === "ClassExpression") && | ||
| outerScope === innerScope.upper | ||
| ); | ||
| const shouldUnwrap = | ||
| parent.type === "LogicalExpression" || | ||
| (parent.type === "ConditionalExpression" && | ||
| parent.test !== expression); | ||
| return shouldUnwrap ? unwrapExpression(parent) : expression; | ||
| } | ||
| /** | ||
| * Checks if inner variable is the name of a function or class | ||
| * that is assigned to outer variable as its initializer. | ||
| * | ||
| * To avoid reporting at declarations such as: | ||
| * var a = function a() {}; | ||
| * var A = class A {}; | ||
| * var a = foo || function a() {}; | ||
| * var a = foo ? function a() {} : bar; | ||
| * var { a = function a() {} } = foo; | ||
| * | ||
| * But it should report at declarations such as: | ||
| * var a = function(a) {}; | ||
| * var a = function() { function a() {} }; | ||
| * var a = wrap(function a() {}); | ||
| * @param {Object} innerVariable The inner variable to check. | ||
| * @param {Object} outerVariable The outer variable. | ||
| * @returns {boolean} Whether or not inner variable is the name of a | ||
| * function or class that is assigned to outer variable as its initializer. | ||
| */ | ||
| function isFunctionNameInitializerException( | ||
| innerVariable, | ||
| outerVariable, | ||
| ) { | ||
| const outerDef = outerVariable.defs[0]; | ||
| const innerDef = innerVariable.defs[0]; | ||
| if (!outerDef || !innerDef) { | ||
| return false; | ||
| } | ||
| if ( | ||
| !( | ||
| (innerDef.type === "FunctionName" && | ||
| innerDef.node.type === "FunctionExpression") || | ||
| (innerDef.type === "ClassName" && | ||
| innerDef.node.type === "ClassExpression") | ||
| ) | ||
| ) { | ||
| return false; | ||
| } | ||
| const outerIdentifier = outerDef.name; | ||
| let initializerNode; | ||
| if (outerIdentifier.parent.type === "VariableDeclarator") { | ||
| initializerNode = outerIdentifier.parent.init; | ||
| } else if (outerIdentifier.parent.type === "AssignmentPattern") { | ||
| initializerNode = outerIdentifier.parent.right; | ||
| } | ||
| if (!initializerNode) { | ||
| return false; | ||
| } | ||
| const nodeToCheck = innerDef.node; // FunctionExpression or ClassExpression node | ||
| // Exit early if the node to check isn't inside the initializer | ||
| if ( | ||
| !( | ||
| initializerNode.range[0] <= nodeToCheck.range[0] && | ||
| nodeToCheck.range[1] <= initializerNode.range[1] | ||
| ) | ||
| ) { | ||
| return false; | ||
| } | ||
| return initializerNode === unwrapExpression(nodeToCheck); | ||
| } | ||
| /** | ||
| * Get a range of a variable's identifier node. | ||
@@ -581,3 +646,3 @@ * @param {Object} variable The variable to get. | ||
| (builtinGlobals && "writeable" in shadowed)) && | ||
| !isOnInitializer(variable, shadowed) && | ||
| !isFunctionNameInitializerException(variable, shadowed) && | ||
| !( | ||
@@ -584,0 +649,0 @@ ignoreOnInitialization && |
@@ -73,2 +73,3 @@ /** | ||
| ViolationReport, | ||
| MessagePlaceholderData, | ||
| } from "@eslint/core"; | ||
@@ -1462,3 +1463,3 @@ | ||
| desc?: string; | ||
| data?: Record<string, unknown> | undefined; | ||
| data?: MessagePlaceholderData | undefined; | ||
| output: string; | ||
@@ -1475,3 +1476,3 @@ } | ||
| messageId?: string; | ||
| data?: any; | ||
| data?: MessagePlaceholderData | undefined; | ||
| line?: number | undefined; | ||
@@ -1478,0 +1479,0 @@ column?: number | undefined; |
+3
-3
| { | ||
| "name": "eslint", | ||
| "version": "10.0.0-rc.0", | ||
| "version": "10.0.0-rc.1", | ||
| "author": "Nicholas C. Zakas <nicholas+npm@nczconsulting.com>", | ||
@@ -123,5 +123,5 @@ "description": "An AST-based pattern checker for JavaScript.", | ||
| "escape-string-regexp": "^4.0.0", | ||
| "eslint-scope": "^9.0.0", | ||
| "eslint-scope": "^9.1.0", | ||
| "eslint-visitor-keys": "^5.0.0", | ||
| "espree": "^11.0.0", | ||
| "espree": "^11.1.0", | ||
| "esquery": "^1.5.0", | ||
@@ -128,0 +128,0 @@ "esutils": "^2.0.2", |
+1
-1
@@ -345,3 +345,3 @@ [](https://www.npmjs.com/package/eslint) | ||
| <p><a href="https://qlty.sh/"><img src="https://images.opencollective.com/qltysh/33d157d/logo.png" alt="Qlty Software" height="96"></a> <a href="https://shopify.engineering/"><img src="https://avatars.githubusercontent.com/u/8085" alt="Shopify" height="96"></a></p><h3>Silver Sponsors</h3> | ||
| <p><a href="https://vite.dev/"><img src="https://images.opencollective.com/vite/e6d15e1/logo.png" alt="Vite" height="64"></a> <a href="https://liftoff.io/"><img src="https://images.opencollective.com/liftoff/2d6c3b6/logo.png" alt="Liftoff" height="64"></a> <a href="https://americanexpress.io"><img src="https://avatars.githubusercontent.com/u/3853301" alt="American Express" height="64"></a> <a href="https://stackblitz.com"><img src="https://avatars.githubusercontent.com/u/28635252" alt="StackBlitz" height="64"></a></p><h3>Bronze Sponsors</h3> | ||
| <p><a href="https://vite.dev/"><img src="https://images.opencollective.com/vite/d472863/logo.png" alt="Vite" height="64"></a> <a href="https://liftoff.io/"><img src="https://images.opencollective.com/liftoff/2d6c3b6/logo.png" alt="Liftoff" height="64"></a> <a href="https://americanexpress.io"><img src="https://avatars.githubusercontent.com/u/3853301" alt="American Express" height="64"></a> <a href="https://stackblitz.com"><img src="https://avatars.githubusercontent.com/u/28635252" alt="StackBlitz" height="64"></a></p><h3>Bronze Sponsors</h3> | ||
| <p><a href="https://cybozu.co.jp/"><img src="https://images.opencollective.com/cybozu/933e46d/logo.png" alt="Cybozu" height="32"></a> <a href="https://www.crawljobs.com/"><img src="https://images.opencollective.com/crawljobs-poland/fa43a17/logo.png" alt="CrawlJobs" height="32"></a> <a href="https://syntax.fm"><img src="https://github.com/syntaxfm.png" alt="Syntax" height="32"></a> <a href="https://www.n-ix.com/"><img src="https://images.opencollective.com/n-ix-ltd/575a7a5/logo.png" alt="N-iX Ltd" height="32"></a> <a href="https://icons8.com/"><img src="https://images.opencollective.com/icons8/7fa1641/logo.png" alt="Icons8" height="32"></a> <a href="https://discord.com"><img src="https://images.opencollective.com/discordapp/f9645d9/logo.png" alt="Discord" height="32"></a> <a href="https://www.gitbook.com"><img src="https://avatars.githubusercontent.com/u/7111340" alt="GitBook" height="32"></a> <a href="https://nx.dev"><img src="https://avatars.githubusercontent.com/u/23692104" alt="Nx" height="32"></a> <a href="https://herocoders.com"><img src="https://avatars.githubusercontent.com/u/37549774" alt="HeroCoders" height="32"></a> <a href="https://www.lambdatest.com"><img src="https://avatars.githubusercontent.com/u/171592363" alt="LambdaTest" height="32"></a></p> | ||
@@ -348,0 +348,0 @@ <h3>Technology Sponsors</h3> |
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 3 instances in 1 package
Debug access
Supply chain riskUses debug, reflection and dynamic code execution features.
Found 2 instances in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 3 instances in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 3 instances in 1 package
Debug access
Supply chain riskUses debug, reflection and dynamic code execution features.
Found 2 instances in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 3 instances in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
2884259
0.08%93487
0.07%227
-0.44%Updated
Updated