Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
private import java
private import DataFlowPrivate
private import DataFlowUtil
private import semmle.code.java.dataflow.InstanceAccess
import semmle.code.java.dispatch.VirtualDispatch

private module DispatchImpl {
Expand All @@ -17,6 +19,13 @@ private module DispatchImpl {
not p.isVarargs() and
c = ma.getEnclosingCallable()
)
or
exists(OwnInstanceAccess ia |
2 <= strictcount(viableImpl(ma)) and
(ia.isExplicit(ma.getQualifier()) or ia.isImplicitMethodQualifier(ma)) and
i = -1 and
c = ma.getEnclosingCallable()
)
}

/**
Expand All @@ -37,18 +46,32 @@ private module DispatchImpl {
* relevant call context.
*/
private predicate contextArgHasType(Call ctx, int i, RefType t, boolean exact) {
exists(Expr arg, Expr src |
relevantContext(ctx, i) and
ctx.getArgument(i) = arg and
src = variableTrack(arg) and
exists(RefType srctype | srctype = src.getType() |
exists(TypeVariable v | v = srctype |
t = v.getUpperBoundType+() and not t instanceof TypeVariable
)
relevantContext(ctx, i) and
exists(RefType srctype |
exists(Expr arg, Expr src |
i = -1 and
ctx.getQualifier() = arg
or
t = srctype and not srctype instanceof TypeVariable
) and
if src instanceof ClassInstanceExpr then exact = true else exact = false
ctx.getArgument(i) = arg
|
src = variableTrack(arg) and
srctype = src.getType() and
if src instanceof ClassInstanceExpr then exact = true else exact = false
)
or
exists(Node arg |
i = -1 and
not exists(ctx.getQualifier()) and
getInstanceArgument(ctx) = arg and
arg.getTypeBound() = srctype and
if ctx instanceof ClassInstanceExpr then exact = true else exact = false
)
|
exists(TypeVariable v | v = srctype |
t = v.getUpperBoundType+() and not t instanceof TypeVariable
)
or
t = srctype and not srctype instanceof TypeVariable
)
}

Expand Down
63 changes: 63 additions & 0 deletions java/ql/test/library-tests/dataflow/callctx/A.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
public class A {
static void sink(Object x) { }

static Object source() { return null; }

static class C1 {
C1() { }

C1(Object x) {
foo(x);
}

void wrapFoo1(Object x) {
foo(x);
}

void wrapFoo2(Object x) {
this.foo(x);
}

void foo(Object x) {
Object c1 = x;
sink(c1);
}
}

static class C2 extends C1 {
C2() { }

C2(Object x) {
super(x);
}

void foo(Object x) {
Object c2 = x;
sink(c2);
}

void callWrapFoo2() {
wrapFoo2(source());
}
}

static void wrapFoo3(C1 c1, Object x) {
c1.foo(x);
}

void test(C1 c) {
c.wrapFoo1(source());
c.wrapFoo2(source());
wrapFoo3(c, source());

new C1(source());
new C1().wrapFoo1(source());
new C1().wrapFoo2(source());
wrapFoo3(new C1(), source());

new C2(source());
new C2().wrapFoo1(source());
new C2().wrapFoo2(source());
wrapFoo3(new C2(), source());
}
}
15 changes: 15 additions & 0 deletions java/ql/test/library-tests/dataflow/callctx/test.expected
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
| A.java:40:16:40:23 | source(...) | A.java:36:12:36:13 | c2 |
| A.java:49:16:49:23 | source(...) | A.java:23:12:23:13 | c1 |
| A.java:49:16:49:23 | source(...) | A.java:36:12:36:13 | c2 |
| A.java:50:16:50:23 | source(...) | A.java:23:12:23:13 | c1 |
| A.java:50:16:50:23 | source(...) | A.java:36:12:36:13 | c2 |
| A.java:51:17:51:24 | source(...) | A.java:23:12:23:13 | c1 |
| A.java:51:17:51:24 | source(...) | A.java:36:12:36:13 | c2 |
| A.java:53:12:53:19 | source(...) | A.java:23:12:23:13 | c1 |
| A.java:54:23:54:30 | source(...) | A.java:23:12:23:13 | c1 |
| A.java:55:23:55:30 | source(...) | A.java:23:12:23:13 | c1 |
| A.java:56:24:56:31 | source(...) | A.java:23:12:23:13 | c1 |
| A.java:58:12:58:19 | source(...) | A.java:36:12:36:13 | c2 |
| A.java:59:23:59:30 | source(...) | A.java:36:12:36:13 | c2 |
| A.java:60:23:60:30 | source(...) | A.java:36:12:36:13 | c2 |
| A.java:61:24:61:31 | source(...) | A.java:36:12:36:13 | c2 |
15 changes: 15 additions & 0 deletions java/ql/test/library-tests/dataflow/callctx/test.ql
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import java
import semmle.code.java.dataflow.DataFlow
import DataFlow

class Conf extends Configuration {
Conf() { this = "qqconf" }

override predicate isSource(Node n) { n.asExpr().(MethodAccess).getMethod().hasName("source") }

override predicate isSink(Node n) { n.asExpr().(Argument).getCall().getCallee().hasName("sink") }
}

from Node src, Node sink, Conf c
where c.hasFlow(src, sink)
select src, sink