Skip to content

Commit 2a28953

Browse files
committed
Java: Implement ContentApprox
1 parent 4d2436d commit 2a28953

File tree

3 files changed

+109
-45
lines changed

3 files changed

+109
-45
lines changed

java/ql/lib/semmle/code/java/dataflow/internal/DataFlowNodes.qll

Lines changed: 65 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,77 @@
11
private import java
22
private import semmle.code.java.dataflow.InstanceAccess
3+
private import semmle.code.java.dataflow.ExternalFlow
34
private import semmle.code.java.dataflow.FlowSummary
45
private import semmle.code.java.dataflow.TypeFlow
56
private import DataFlowPrivate
7+
private import DataFlowUtil
68
private import FlowSummaryImpl as FlowSummaryImpl
79
private import DataFlowImplCommon as DataFlowImplCommon
810

11+
/** Gets a string for approximating the name of a field. */
12+
string approximateFieldContent(FieldContent fc) { result = fc.getField().getName().prefix(1) }
13+
914
cached
10-
newtype TNode =
11-
TExprNode(Expr e) {
12-
DataFlowImplCommon::forceCachingInSameStage() and
13-
not e.getType() instanceof VoidType and
14-
not e.getParent*() instanceof Annotation
15-
} or
16-
TExplicitParameterNode(Parameter p) { exists(p.getCallable().getBody()) } or
17-
TImplicitVarargsArray(Call c) {
18-
c.getCallee().isVarargs() and
19-
not exists(Argument arg | arg.getCall() = c and arg.isExplicitVarargsArray())
20-
} or
21-
TInstanceParameterNode(Callable c) { exists(c.getBody()) and not c.isStatic() } or
22-
TImplicitInstanceAccess(InstanceAccessExt ia) { not ia.isExplicit(_) } or
23-
TMallocNode(ClassInstanceExpr cie) or
24-
TExplicitExprPostUpdate(Expr e) {
25-
explicitInstanceArgument(_, e)
26-
or
27-
e instanceof Argument and not e.getType() instanceof ImmutableType
28-
or
29-
exists(FieldAccess fa | fa.getField() instanceof InstanceField and e = fa.getQualifier())
30-
or
31-
exists(ArrayAccess aa | e = aa.getArray())
32-
} or
33-
TImplicitExprPostUpdate(InstanceAccessExt ia) {
34-
implicitInstanceArgument(_, ia)
35-
or
36-
exists(FieldAccess fa |
37-
fa.getField() instanceof InstanceField and ia.isImplicitFieldQualifier(fa)
38-
)
39-
} or
40-
TSummaryInternalNode(SummarizedCallable c, FlowSummaryImpl::Private::SummaryNodeState state) {
41-
FlowSummaryImpl::Private::summaryNodeRange(c, state)
42-
} or
43-
TSummaryParameterNode(SummarizedCallable c, int pos) {
44-
FlowSummaryImpl::Private::summaryParameterNodeRange(c, pos)
45-
} or
46-
TFieldValueNode(Field f)
15+
private module Cached {
16+
cached
17+
newtype TNode =
18+
TExprNode(Expr e) {
19+
DataFlowImplCommon::forceCachingInSameStage() and
20+
not e.getType() instanceof VoidType and
21+
not e.getParent*() instanceof Annotation
22+
} or
23+
TExplicitParameterNode(Parameter p) { exists(p.getCallable().getBody()) } or
24+
TImplicitVarargsArray(Call c) {
25+
c.getCallee().isVarargs() and
26+
not exists(Argument arg | arg.getCall() = c and arg.isExplicitVarargsArray())
27+
} or
28+
TInstanceParameterNode(Callable c) { exists(c.getBody()) and not c.isStatic() } or
29+
TImplicitInstanceAccess(InstanceAccessExt ia) { not ia.isExplicit(_) } or
30+
TMallocNode(ClassInstanceExpr cie) or
31+
TExplicitExprPostUpdate(Expr e) {
32+
explicitInstanceArgument(_, e)
33+
or
34+
e instanceof Argument and not e.getType() instanceof ImmutableType
35+
or
36+
exists(FieldAccess fa | fa.getField() instanceof InstanceField and e = fa.getQualifier())
37+
or
38+
exists(ArrayAccess aa | e = aa.getArray())
39+
} or
40+
TImplicitExprPostUpdate(InstanceAccessExt ia) {
41+
implicitInstanceArgument(_, ia)
42+
or
43+
exists(FieldAccess fa |
44+
fa.getField() instanceof InstanceField and ia.isImplicitFieldQualifier(fa)
45+
)
46+
} or
47+
TSummaryInternalNode(SummarizedCallable c, FlowSummaryImpl::Private::SummaryNodeState state) {
48+
FlowSummaryImpl::Private::summaryNodeRange(c, state)
49+
} or
50+
TSummaryParameterNode(SummarizedCallable c, int pos) {
51+
FlowSummaryImpl::Private::summaryParameterNodeRange(c, pos)
52+
} or
53+
TFieldValueNode(Field f)
54+
55+
cached
56+
newtype TContent =
57+
TFieldContent(InstanceField f) or
58+
TArrayContent() or
59+
TCollectionContent() or
60+
TMapKeyContent() or
61+
TMapValueContent() or
62+
TSyntheticFieldContent(SyntheticField s)
63+
64+
cached
65+
newtype TContentApprox =
66+
TFieldContentApprox(string firstChar) { firstChar = approximateFieldContent(_) } or
67+
TArrayContentApprox() or
68+
TCollectionContentApprox() or
69+
TMapKeyContentApprox() or
70+
TMapValueContentApprox() or
71+
TSyntheticFieldApproxContent()
72+
}
73+
74+
import Cached
4775

4876
private predicate explicitInstanceArgument(Call call, Expr instarg) {
4977
call instanceof MethodAccess and

java/ql/lib/semmle/code/java/dataflow/internal/DataFlowPrivate.qll

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ private import semmle.code.java.dataflow.FlowSteps
99
private import semmle.code.java.dataflow.FlowSummary
1010
private import FlowSummaryImpl as FlowSummaryImpl
1111
private import DataFlowImplConsistency
12+
private import DataFlowNodes
1213
import DataFlowNodes::Private
1314

1415
private newtype TReturnKind = TNormalReturnKind()
@@ -420,6 +421,48 @@ predicate allowParameterReturnInSelf(ParameterNode p) {
420421
FlowSummaryImpl::Private::summaryAllowParameterReturnInSelf(p)
421422
}
422423

424+
/** An approximated `Content`. */
425+
class ContentApprox extends TContentApprox {
426+
/** Gets a textual representation of this approximated `Content`. */
427+
string toString() {
428+
exists(string firstChar |
429+
this = TFieldContentApprox(firstChar) and
430+
result = "approximated field " + firstChar
431+
)
432+
or
433+
this = TArrayContentApprox() and
434+
result = "[]"
435+
or
436+
this = TCollectionContentApprox() and
437+
result = "<element>"
438+
or
439+
this = TMapKeyContentApprox() and
440+
result = "<map.key>"
441+
or
442+
this = TMapValueContentApprox() and
443+
result = "<map.value>"
444+
or
445+
this = TSyntheticFieldApproxContent() and
446+
result = "approximated synthetic field"
447+
}
448+
}
449+
450+
/** Gets an approximated value for content `c`. */
451+
pragma[nomagic]
452+
ContentApprox getContentApprox(Content c) {
453+
result = TFieldContentApprox(approximateFieldContent(c))
454+
or
455+
c instanceof ArrayContent and result = TArrayContentApprox()
456+
or
457+
c instanceof CollectionContent and result = TCollectionContentApprox()
458+
or
459+
c instanceof MapKeyContent and result = TMapKeyContentApprox()
460+
or
461+
c instanceof MapValueContent and result = TMapValueContentApprox()
462+
or
463+
c instanceof SyntheticFieldContent and result = TSyntheticFieldApproxContent()
464+
}
465+
423466
private class MyConsistencyConfiguration extends Consistency::ConsistencyConfiguration {
424467
override predicate argHasPostUpdateExclude(ArgumentNode n) {
425468
n.getType() instanceof ImmutableType or n instanceof ImplicitVarargsArray

java/ql/lib/semmle/code/java/dataflow/internal/DataFlowUtil.qll

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ private import semmle.code.java.dataflow.FlowSummary
1212
private import semmle.code.java.dataflow.InstanceAccess
1313
private import FlowSummaryImpl as FlowSummaryImpl
1414
private import TaintTrackingUtil as TaintTrackingUtil
15+
private import DataFlowNodes
1516
import DataFlowNodes::Public
1617
import semmle.code.Unit
1718

@@ -186,14 +187,6 @@ private predicate simpleLocalFlowStep0(Node node1, Node node2) {
186187
FlowSummaryImpl::Private::Steps::summaryLocalStep(node1, node2, true)
187188
}
188189

189-
private newtype TContent =
190-
TFieldContent(InstanceField f) or
191-
TArrayContent() or
192-
TCollectionContent() or
193-
TMapKeyContent() or
194-
TMapValueContent() or
195-
TSyntheticFieldContent(SyntheticField s)
196-
197190
/**
198191
* A description of the way data may be stored inside an object. Examples
199192
* include instance fields, the contents of a collection object, or the contents

0 commit comments

Comments
 (0)