JavaScript: Make ModuleVarNode and ExportsVarNode more easily accessible.

This commit is contained in:
Max Schaefer
2021-07-12 15:31:40 +01:00
parent c47d680d65
commit 70c82c83ac
2 changed files with 53 additions and 50 deletions

View File

@@ -617,11 +617,11 @@ module API {
cached
predicate use(TApiNode nd, DataFlow::Node ref) {
exists(string m, Module mod | nd = MkModuleDef(m) and mod = importableModule(m) |
ref.(ModuleVarNode).getModule() = mod
ref = DataFlow::moduleVarNode(mod)
)
or
exists(string m, Module mod | nd = MkModuleExport(m) and mod = importableModule(m) |
ref.(ExportsVarNode).getModule() = mod
ref = DataFlow::exportsVarNode(mod)
or
exists(DataFlow::Node base | use(MkModuleDef(m), base) |
ref = trackUseNode(base).getAPropertyRead("exports")
@@ -742,12 +742,9 @@ module API {
or
// additional backwards step from `require('m')` to `exports` or `module.exports` in m
exists(Import imp | imp.getImportedModuleNode() = trackDefNode(nd, t.continue()) |
result.(ExportsVarNode).getModule() = imp.getImportedModule()
result = DataFlow::exportsVarNode(imp.getImportedModule())
or
exists(ModuleVarNode mod |
mod.getModule() = imp.getImportedModule() and
result = mod.(DataFlow::SourceNode).getAPropertyRead("exports")
)
result = DataFlow::moduleVarNode(imp.getImportedModule()).getAPropertyRead("exports")
)
or
t = defStep(nd, result)
@@ -981,46 +978,3 @@ private module Label {
/** Gets the `promisedError` edge label connecting a promise to its rejected value. */
string promisedError() { result = "promisedError" }
}
private class NodeModuleSourcesNodes extends DataFlow::SourceNode::Range {
Variable v;
NodeModuleSourcesNodes() {
exists(NodeModule m |
this = DataFlow::ssaDefinitionNode(SSA::implicitInit(v)) and
v = [m.getModuleVariable(), m.getExportsVariable()]
)
}
Variable getVariable() { result = v }
}
/**
* A CommonJS/AMD `module` variable.
*/
private class ModuleVarNode extends DataFlow::Node {
Module m;
ModuleVarNode() {
this.(NodeModuleSourcesNodes).getVariable() = m.(NodeModule).getModuleVariable()
or
DataFlow::parameterNode(this, m.(AmdModule).getDefine().getModuleParameter())
}
Module getModule() { result = m }
}
/**
* A CommonJS/AMD `exports` variable.
*/
private class ExportsVarNode extends DataFlow::Node {
Module m;
ExportsVarNode() {
this.(NodeModuleSourcesNodes).getVariable() = m.(NodeModule).getExportsVariable()
or
DataFlow::parameterNode(this, m.(AmdModule).getDefine().getExportsParameter())
}
Module getModule() { result = m }
}

View File

@@ -347,6 +347,55 @@ module SourceNode {
}
}
private class NodeModuleSourcesNodes extends SourceNode::Range {
Variable v;
NodeModuleSourcesNodes() {
exists(NodeModule m |
this = DataFlow::ssaDefinitionNode(SSA::implicitInit(v)) and
v = [m.getModuleVariable(), m.getExportsVariable()]
)
}
Variable getVariable() { result = v }
}
/**
* A CommonJS/AMD `module` variable.
*/
private class ModuleVarNode extends DataFlow::Node {
Module m;
ModuleVarNode() {
this.(NodeModuleSourcesNodes).getVariable() = m.(NodeModule).getModuleVariable()
or
DataFlow::parameterNode(this, m.(AmdModule).getDefine().getModuleParameter())
}
Module getModule() { result = m }
}
/**
* A CommonJS/AMD `exports` variable.
*/
private class ExportsVarNode extends DataFlow::Node {
Module m;
ExportsVarNode() {
this.(NodeModuleSourcesNodes).getVariable() = m.(NodeModule).getExportsVariable()
or
DataFlow::parameterNode(this, m.(AmdModule).getDefine().getExportsParameter())
}
Module getModule() { result = m }
}
/** Gets the CommonJS/AMD `module` variable for module `m`. */
SourceNode moduleVarNode(Module m) { result.(ModuleVarNode).getModule() = m }
/** Gets the CommonJS/AMD `exports` variable for module `m`. */
SourceNode exportsVarNode(Module m) { result.(ExportsVarNode).getModule() = m }
deprecated class DefaultSourceNode extends SourceNode {
DefaultSourceNode() { this instanceof SourceNode::DefaultRange }
}