Merge branch 'main' into ts-54

This commit is contained in:
erik-krogh
2024-02-25 21:20:43 +01:00
1315 changed files with 80439 additions and 48696 deletions

View File

@@ -1022,7 +1022,6 @@ flowStep
| tst.js:4:9:4:12 | "hi" | tst.js:4:5:4:12 | y |
| tst.js:9:2:9:2 | x | tst.js:9:1:9:3 | (x) |
| tst.js:10:4:10:4 | y | tst.js:10:1:10:4 | x, y |
| tst.js:11:1:11:1 | x | tst.js:11:1:11:6 | x && y |
| tst.js:11:1:11:1 | x | tst.js:12:1:12:1 | x |
| tst.js:11:1:11:1 | x | tst.js:12:1:12:1 | x |
| tst.js:11:6:11:6 | y | tst.js:11:1:11:6 | x && y |

View File

@@ -0,0 +1,8 @@
testFailures
ambiguousPreferredPredecessor
| pack2/lib.js:1:1:3:1 | def moduleImport("pack2").getMember("exports").getMember("lib").getMember("LibClass").getInstance() |
| pack2/lib.js:8:22:8:34 | def moduleImport("pack2").getMember("exports").getMember("lib").getMember("LibClass").getMember("foo") |
| pack2/main.js:1:1:3:1 | def moduleImport("pack2").getMember("exports").getMember("MainClass").getInstance() |
ambiguousSinkName
ambiguousFunctionName
failures

View File

@@ -0,0 +1,40 @@
import javascript
import semmle.javascript.RestrictedLocations
import semmle.javascript.Lines
import semmle.javascript.endpoints.EndpointNaming as EndpointNaming
import testUtilities.InlineExpectationsTest
import EndpointNaming::Debug
private predicate isIgnored(DataFlow::FunctionNode function) {
function.getFunction() = any(ConstructorDeclaration decl | decl.isSynthetic()).getBody()
}
module TestConfig implements TestSig {
string getARelevantTag() { result = ["name", "alias"] }
predicate hasActualResult(Location location, string element, string tag, string value) {
element = "" and
tag = "name" and
exists(DataFlow::SourceNode function, string package, string name |
EndpointNaming::functionHasPrimaryName(function, package, name) and
not isIgnored(function) and
location = function.getAstNode().getLocation() and
value = EndpointNaming::renderName(package, name)
)
or
element = "" and
tag = "alias" and
exists(
API::Node aliasDef, string primaryPackage, string primaryName, string aliasPackage,
string aliasName
|
EndpointNaming::aliasDefinition(aliasPackage, aliasName, primaryPackage, primaryName, aliasDef) and
value =
EndpointNaming::renderName(aliasPackage, aliasName) + "==" +
EndpointNaming::renderName(primaryPackage, primaryName) and
location = aliasDef.asSink().asExpr().getLocation()
)
}
}
import MakeTest<TestConfig>

View File

@@ -0,0 +1,15 @@
export class PublicClass {} // $ name=(pack1).PublicClass
class PrivateClass {}
export const ExportedConst = class ExportedConstClass {} // $ name=(pack1).ExportedConst
class ClassWithEscapingInstance {
m() {} // $ name=(pack1).ClassWithEscapingInstance.prototype.m
}
export function getEscapingInstance() {
return new ClassWithEscapingInstance();
} // $ name=(pack1).getEscapingInstance
export function publicFunction() {} // $ name=(pack1).publicFunction

View File

@@ -0,0 +1,4 @@
{
"name": "pack1",
"main": "./main.js"
}

View File

@@ -0,0 +1 @@
export default class FooClass {} // $ name=(pack10).Foo

View File

@@ -0,0 +1,3 @@
import { default as Foo } from "./foo";
export { Foo }

View File

@@ -0,0 +1,4 @@
{
"name": "pack10",
"main": "./index.js"
}

View File

@@ -0,0 +1,59 @@
const f1 = {
m() {} // $ name=(pack11).C1.publicField.really.long.name.m
};
export class C1 {
private static privateField = f1;
public static publicField = {
really: {
long: {
name: f1
}
}
}
} // $ name=(pack11).C1
const f2 = {
m() {} // $ name=(pack11).C2.publicField.really.long.name.m
}
export class C2 {
static #privateField = f2;
static publicField = {
really: {
long: {
name: f2
}
}
}
} // $ name=(pack11).C2
function f3() {} // $ name=(pack11).C3.publicField.really.long.name
export class C3 {
private static privateField = f3;
public static publicField = {
really: {
long: {
name: f3
}
}
}
} // $ name=(pack11).C3
const f4 = {
m() {} // $ name=(pack11).C4.really.long.name.m
};
export const C4 = {
[Math.random()]: f4,
really: {
long: {
name: f4
}
}
}

View File

@@ -0,0 +1,4 @@
{
"name": "pack11",
"main": "./index.js"
}

View File

@@ -0,0 +1,10 @@
function wrap(fn) {
return x => fn(x);
}
function f() {}
export const f1 = wrap(f); // $ name=(pack12).f1
export const f2 = wrap(f); // $ name=(pack12).f2
function g() {}
export const g1 = wrap(g); // $ name=(pack12).g1

View File

@@ -0,0 +1,4 @@
{
"name": "pack12",
"main": "./index.js"
}

View File

@@ -0,0 +1,8 @@
class AmbiguousClass {
instanceMethod(foo) {} // $ name=(pack2).lib.LibClass.prototype.instanceMethod
} // $ name=(pack2).lib.LibClass
export default AmbiguousClass; // $ alias=(pack2).lib.default==(pack2).lib.LibClass
export { AmbiguousClass as LibClass }
AmbiguousClass.foo = function() {} // $ name=(pack2).lib.LibClass.foo

View File

@@ -0,0 +1,9 @@
class AmbiguousClass {
instanceMethod() {} // $ name=(pack2).MainClass.prototype.instanceMethod
} // $ name=(pack2).MainClass
export default AmbiguousClass; // $ alias=(pack2).default==(pack2).MainClass
export { AmbiguousClass as MainClass }
import * as lib from "./lib";
export { lib }

View File

@@ -0,0 +1,4 @@
{
"name": "pack2",
"main": "./main.js"
}

View File

@@ -0,0 +1 @@
export default function(x,y,z) {} // $ name=(pack3).libFunction alias=(pack3).libFunction.default==(pack3).libFunction

View File

@@ -0,0 +1,7 @@
function ambiguousFunction(x, y, z) {} // $ name=(pack3).namedFunction
export default ambiguousFunction; // $ alias=(pack3).default==(pack3).namedFunction
export { ambiguousFunction as namedFunction };
import libFunction from "./lib";
export { libFunction };

View File

@@ -0,0 +1,4 @@
{
"name": "pack3",
"main": "./main.js"
}

View File

@@ -0,0 +1 @@
export default class C {} // $ name=(pack4)

View File

@@ -0,0 +1,4 @@
{
"name": "pack4",
"main": "./index.js"
}

View File

@@ -0,0 +1,4 @@
{
"name": "pack5",
"main": "./dist/index.js"
}

View File

@@ -0,0 +1 @@
export default class C {} // $ name=(pack5)

View File

@@ -0,0 +1,6 @@
class C {
instanceMethod() {} // $ name=(pack6).instanceMethod
static staticMethod() {} // not accessible
}
export default new C();

View File

@@ -0,0 +1,4 @@
{
"name": "pack6",
"main": "./index.js"
}

View File

@@ -0,0 +1,6 @@
export class D {} // $ name=(pack7).D
// In this case we are forced to include ".default" to avoid ambiguity with class D above.
export default {
D: class {} // $ name=(pack7).default.D
};

View File

@@ -0,0 +1,4 @@
{
"name": "pack7",
"main": "./index.js"
}

View File

@@ -0,0 +1,5 @@
class Foo {} // $ name=(pack8).Foo
module.exports = Foo;
module.exports.default = Foo; // $ alias=(pack8).Foo.default==(pack8).Foo
module.exports.Foo = Foo; // $ alias=(pack8).Foo.Foo==(pack8).Foo

View File

@@ -0,0 +1,5 @@
class Main {} // $ name=(pack8)
Main.Foo = require('./foo');
module.exports = Main;

View File

@@ -0,0 +1,4 @@
{
"name": "pack8",
"main": "./index.js"
}

View File

@@ -0,0 +1 @@
export class Foo {}

View File

@@ -0,0 +1,9 @@
// Only the type is exposed. For the time being we do not consider type-only declarations or .d.ts files
// when naming classes.
export type { Foo } from "./foo";
import * as foo from "./foo";
export function expose() {
return new foo.Foo(); // expose an instance of Foo but not the class
} // $ name=(pack9).expose

View File

@@ -0,0 +1,4 @@
{
"name": "pack9",
"main": "./index.js"
}

View File

@@ -154,6 +154,7 @@ typeInferenceMismatch
| json-stringify.js:2:16:2:23 | source() | json-stringify.js:42:8:42:51 | JSON.st ... urce))) |
| json-stringify.js:2:16:2:23 | source() | json-stringify.js:45:8:45:23 | fastJson(source) |
| json-stringify.js:3:15:3:22 | source() | json-stringify.js:8:8:8:31 | jsonStr ... (taint) |
| logical-and.js:2:17:2:24 | source() | logical-and.js:4:10:4:24 | "safe" && taint |
| nested-props.js:4:13:4:20 | source() | nested-props.js:5:10:5:14 | obj.x |
| nested-props.js:9:18:9:25 | source() | nested-props.js:10:10:10:16 | obj.x.y |
| nested-props.js:35:13:35:20 | source() | nested-props.js:36:10:36:20 | doLoad(obj) |

View File

@@ -73,6 +73,7 @@
| importedReactComponent.jsx:4:40:4:47 | source() | exportedReactComponent.jsx:2:10:2:19 | props.text |
| indexOf.js:4:11:4:18 | source() | indexOf.js:9:10:9:10 | x |
| indexOf.js:4:11:4:18 | source() | indexOf.js:13:10:13:10 | x |
| logical-and.js:2:17:2:24 | source() | logical-and.js:4:10:4:24 | "safe" && taint |
| nested-props.js:4:13:4:20 | source() | nested-props.js:5:10:5:14 | obj.x |
| nested-props.js:9:18:9:25 | source() | nested-props.js:10:10:10:16 | obj.x.y |
| nested-props.js:35:13:35:20 | source() | nested-props.js:36:10:36:20 | doLoad(obj) |

View File

@@ -0,0 +1,6 @@
function test() {
var taint = source();
sink("safe" && taint); // NOT OK
sink(taint && "safe"); // OK
}