JS: Refactor aliasing relation

This commit is contained in:
Asger F
2024-02-13 09:24:00 +01:00
parent 8d3a19aaad
commit baa3c35d6f
7 changed files with 42 additions and 23 deletions

View File

@@ -168,7 +168,7 @@ predicate sinkHasPrimaryName(API::Node sink, string package, string name) {
*
* This means it is a valid name for it, but was not chosen as the primary name.
*/
predicate sinkHasAlias(API::Node sink, string package, string name) {
private predicate sinkHasAlias(API::Node sink, string package, string name) {
not sinkHasPrimaryName(sink, package, name) and
(
exists(string baseName, string step |
@@ -239,15 +239,6 @@ predicate classObjectHasPrimaryName(DataFlow::ClassNode cls, string package, str
classObjectHasPrimaryName(cls, package, name, _)
}
/** Holds if `(package, name)` is an alias for the class object of `cls`. */
predicate classObjectHasAlias(DataFlow::ClassNode cls, string package, string name) {
not classObjectHasPrimaryName(cls, package, name) and
exists(int badness |
classObjectHasNameCandidate(cls, package, name, badness) and
badness < 100
)
}
/** Holds if an instance of `cls` can be exposed to client code. */
private predicate hasEscapingInstance(DataFlow::ClassNode cls) {
cls.getAnInstanceReference().flowsTo(any(API::Node n).asSink())
@@ -362,14 +353,28 @@ predicate functionHasPrimaryName(DataFlow::FunctionNode function, string package
}
/**
* Holds if `(package, name)` is an alias for the given `function`.
* Holds if `(aliasPackage, aliasName)` is an alias for `(primaryPackage, primaryName)`,
* defined at `aliasDef`.
*/
predicate functionHasAlias(DataFlow::FunctionNode function, string package, string name) {
not functionHasPrimaryName(function, package, name) and
exists(int badness |
functionHasNameCandidate(function, package, name, badness) and
badness < 100
predicate aliasDefinition(
string primaryPackage, string primaryName, string aliasPackage, string aliasName,
API::Node aliasDef
) {
exists(DataFlow::SourceNode source |
classObjectHasPrimaryName(source, primaryPackage, primaryName)
or
functionHasPrimaryName(source, primaryPackage, primaryName)
|
aliasDef.getAValueReachingSink() = source and
sinkHasPrimaryName(aliasDef, aliasPackage, aliasName, _) and
not (
primaryPackage = aliasPackage and
primaryName = aliasName
)
)
or
sinkHasPrimaryName(aliasDef, primaryPackage, primaryName) and
sinkHasAlias(aliasDef, aliasPackage, aliasName)
}
/**

View File

@@ -12,6 +12,8 @@ module TestConfig implements TestSig {
result = "class"
or
result = "method"
or
result = "alias"
}
predicate hasActualResult(Location location, string element, string tag, string value) {
@@ -27,7 +29,6 @@ module TestConfig implements TestSig {
EndpointNaming::classInstanceHasPrimaryName(cls, package, name)
)
or
element = "" and
exists(DataFlow::FunctionNode function |
not function.getFunction() = any(ConstructorDeclaration decl | decl.isSynthetic()).getBody() and
location = function.getFunction().getLocation() and
@@ -35,6 +36,19 @@ module TestConfig implements TestSig {
EndpointNaming::functionHasPrimaryName(function, package, name)
)
)
or
element = "" and
tag = "alias" and
exists(
API::Node aliasDef, string primaryPackage, string primaryName, string aliasPackage,
string aliasName
|
EndpointNaming::aliasDefinition(primaryPackage, primaryName, aliasPackage, aliasName, aliasDef) and
value =
EndpointNaming::renderName(aliasPackage, aliasName) + "==" +
EndpointNaming::renderName(primaryPackage, primaryName) and
location = aliasDef.asSink().asExpr().getLocation()
)
}
}

View File

@@ -2,5 +2,5 @@ class AmbiguousClass {
instanceMethod(foo) {} // $ method=(pack2).lib.LibClass.prototype.instanceMethod
} // $ class=(pack2).lib.LibClass instance=(pack2).lib.LibClass.prototype
export default AmbiguousClass;
export default AmbiguousClass; // $ alias=(pack2).lib.default==(pack2).lib.LibClass
export { AmbiguousClass as LibClass }

View File

@@ -2,7 +2,7 @@ class AmbiguousClass {
instanceMethod() {} // $ method=(pack2).MainClass.prototype.instanceMethod
} // $ class=(pack2).MainClass instance=(pack2).MainClass.prototype
export default AmbiguousClass;
export default AmbiguousClass; // $ alias=(pack2).default==(pack2).MainClass
export { AmbiguousClass as MainClass }
import * as lib from "./lib";

View File

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

View File

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

View File

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