Skip to content

Commit e0b6831

Browse files
committed
use the class hierarchy from TypeScript in the callgraph
1 parent 4aa6275 commit e0b6831

File tree

6 files changed

+57
-0
lines changed

6 files changed

+57
-0
lines changed

javascript/ql/lib/semmle/javascript/dataflow/internal/CallGraphs.qll

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,35 @@ module CallGraph {
5555
or
5656
imprecision = 0 and
5757
result = callgraphStep(function, t)
58+
or
59+
t.start() and
60+
imprecision = 0 and
61+
function = getTypedCallee(result)
62+
}
63+
64+
/**
65+
* Gets a class that implements (or is) the given `type`.
66+
*/
67+
private ClassDefinition getAnImplementationClass(Type type) {
68+
exists(InterfaceType inter | inter = type |
69+
result.getSuperClassDefinition*().getASuperInterface().getType() = inter
70+
)
71+
or
72+
exists(ClassType classType | classType = type |
73+
result.getSuperClassDefinition*() = classType.getClass()
74+
)
75+
}
76+
77+
/**
78+
* Gets a function that the given `callee` refers to through the TypeScript class hierarchy.
79+
*/
80+
private DataFlow::FunctionNode getTypedCallee(DataFlow::PropRead callee) {
81+
exists(Type baseType, ClassDefinition impl, string name |
82+
callee.getBase().asExpr().getType() = baseType and
83+
impl = getAnImplementationClass(baseType) and
84+
callee.getPropertyName() = name and
85+
impl.getInstanceMethod(name) = result.getFunction()
86+
)
5887
}
5988

6089
/**

javascript/ql/test/library-tests/TaintTracking/BasicTaintTracking.expected

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,7 @@ typeInferenceMismatch
231231
| tst.js:2:13:2:20 | source() | tst.js:47:10:47:30 | Buffer. ... 'hex') |
232232
| tst.js:2:13:2:20 | source() | tst.js:48:10:48:22 | new Buffer(x) |
233233
| tst.js:2:13:2:20 | source() | tst.js:51:10:51:31 | seriali ... ript(x) |
234+
| typed.ts:23:18:23:25 | source() | typed.ts:11:14:11:14 | s |
234235
| xml.js:5:18:5:25 | source() | xml.js:8:14:8:17 | text |
235236
| xml.js:12:17:12:24 | source() | xml.js:13:14:13:19 | result |
236237
| xml.js:23:18:23:25 | source() | xml.js:20:14:20:17 | attr |

javascript/ql/test/library-tests/TaintTracking/DataFlowTracking.expected

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,3 +109,4 @@
109109
| thisAssignments.js:4:17:4:24 | source() | thisAssignments.js:5:10:5:18 | obj.field |
110110
| thisAssignments.js:7:19:7:26 | source() | thisAssignments.js:8:10:8:20 | this.field2 |
111111
| tst.js:2:13:2:20 | source() | tst.js:4:10:4:10 | x |
112+
| typed.ts:23:18:23:25 | source() | typed.ts:11:14:11:14 | s |

javascript/ql/test/library-tests/TaintTracking/tsconfig.json

Whitespace-only changes.
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
declare function source(): any;
2+
declare function sink(taint: any): any;
3+
4+
5+
interface Thing {
6+
do(s: string): void;
7+
}
8+
9+
class ThingImpl implements Thing {
10+
do(s: string): void {
11+
sink(s);
12+
}
13+
}
14+
15+
class ThingDoer {
16+
thing: Thing;
17+
doThing(s: string): void {
18+
this.thing.do(s);
19+
}
20+
}
21+
22+
export function run(doer: ThingDoer): void {
23+
doer.doThing(source());
24+
}
25+

javascript/ql/test/library-tests/TypeScript/CallGraph/CallGraph.expected

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
| tst.ts:4:5:4:21 | x.method("Hello") | tst.ts:15:3:17:3 | public ... x);\\n } |
2+
| tst.ts:4:5:4:21 | x.method("Hello") | tst.ts:21:3:23:3 | public ... ");\\n } |
23
| tst.ts:9:17:9:33 | new AngryLogger() | tst.ts:20:34:20:33 | (...arg ... rgs); } |
34
| tst.ts:10:5:10:49 | (newLog ... hello") | tst.ts:15:3:17:3 | public ... x);\\n } |
45
| tst.ts:10:5:10:49 | (newLog ... hello") | tst.ts:21:3:23:3 | public ... ");\\n } |

0 commit comments

Comments
 (0)