Skip to content

Commit f2ecb63

Browse files
committed
add a direct Export step as a PreCallGraphStep
1 parent 29457c5 commit f2ecb63

File tree

6 files changed

+44
-0
lines changed

6 files changed

+44
-0
lines changed

javascript/ql/src/semmle/javascript/frameworks/NodeJSLib.qll

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -638,6 +638,20 @@ module NodeJSLib {
638638
}
639639
}
640640

641+
private import semmle.javascript.PackageExports as Exports
642+
643+
/**
644+
* A direct step from an named export to a property-read reading the exported value.
645+
*/
646+
private class ExportsStep extends PreCallGraphStep {
647+
override predicate step(DataFlow::Node pred, DataFlow::Node succ) {
648+
exists(Import imp, string name |
649+
succ = DataFlow::valueNode(imp).(DataFlow::SourceNode).getAPropertyRead(name) and
650+
pred = Exports::getAnExportedValue(imp.getImportedModule(), name)
651+
)
652+
}
653+
}
654+
641655
/**
642656
* A call to a method from module `child_process`.
643657
*/

javascript/ql/test/library-tests/TypeTracking/PredicateStyle.expected

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,3 +70,8 @@ dataValue
7070
| tst.js:51:30:51:33 | data |
7171
| tst.js:58:16:58:16 | x |
7272
| tst.js:68:16:68:19 | data |
73+
reexport
74+
| reexport/a.js:2:10:2:26 | function foo() {} | reexport/a.js:2:10:2:26 | function foo() {} |
75+
| reexport/a.js:2:10:2:26 | function foo() {} | reexport/test.js:3:13:3:17 | b.foo |
76+
| reexport/b.js:4:10:4:26 | function bar() {} | reexport/b.js:4:10:4:26 | function bar() {} |
77+
| reexport/b.js:4:10:4:26 | function bar() {} | reexport/test.js:4:13:4:17 | b.bar |

javascript/ql/test/library-tests/TypeTracking/PredicateStyle.ql

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,15 @@ DataFlow::SourceNode dataValue(DataFlow::TypeTracker t) {
4646
}
4747

4848
query DataFlow::SourceNode dataValue() { result = dataValue(DataFlow::TypeTracker::end()) }
49+
50+
DataFlow::SourceNode reexport(DataFlow::TypeTracker t, DataFlow::FunctionNode func) {
51+
t.start() and
52+
func = result and
53+
func.getFile().getParentContainer().getBaseName() = "reexport"
54+
or
55+
exists(DataFlow::TypeTracker t2 | result = reexport(t2, func).track(t2, t))
56+
}
57+
58+
query DataFlow::SourceNode reexport(DataFlow::FunctionNode func) {
59+
result = reexport(DataFlow::TypeTracker::end(), func)
60+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module.exports = {
2+
foo: function foo() {}
3+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
const a = require("./a");
2+
3+
module.exports = {
4+
bar: function bar() {}, // name: bar
5+
...a
6+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
const b = require("./b");
2+
3+
const foo = b.foo;
4+
const bar = b.bar;

0 commit comments

Comments
 (0)