Skip to content

Commit a2d9f4f

Browse files
committed
Java: Introduce language specific file for model generator code.
1 parent a1c6426 commit a2d9f4f

File tree

2 files changed

+196
-195
lines changed

2 files changed

+196
-195
lines changed
Lines changed: 1 addition & 195 deletions
Original file line numberDiff line numberDiff line change
@@ -1,195 +1 @@
1-
import java
2-
private import semmle.code.java.dataflow.ExternalFlow
3-
private import semmle.code.java.dataflow.internal.ContainerFlow
4-
private import semmle.code.java.dataflow.internal.DataFlowImplCommon
5-
private import semmle.code.java.dataflow.DataFlow
6-
private import semmle.code.java.dataflow.internal.DataFlowPrivate
7-
8-
Method superImpl(Method m) {
9-
result = m.getAnOverride() and
10-
not exists(result.getAnOverride()) and
11-
not m instanceof ToStringMethod
12-
}
13-
14-
private predicate isInTestFile(File file) {
15-
file.getAbsolutePath().matches("%src/test/%") or
16-
file.getAbsolutePath().matches("%/guava-tests/%") or
17-
file.getAbsolutePath().matches("%/guava-testlib/%")
18-
}
19-
20-
private predicate isJdkInternal(CompilationUnit cu) {
21-
cu.getPackage().getName().matches("org.graalvm%") or
22-
cu.getPackage().getName().matches("com.sun%") or
23-
cu.getPackage().getName().matches("javax.swing%") or
24-
cu.getPackage().getName().matches("java.awt%") or
25-
cu.getPackage().getName().matches("sun%") or
26-
cu.getPackage().getName().matches("jdk.%") or
27-
cu.getPackage().getName().matches("java2d.%") or
28-
cu.getPackage().getName().matches("build.tools.%") or
29-
cu.getPackage().getName().matches("propertiesparser.%") or
30-
cu.getPackage().getName().matches("org.jcp.%") or
31-
cu.getPackage().getName().matches("org.w3c.%") or
32-
cu.getPackage().getName().matches("org.ietf.jgss.%") or
33-
cu.getPackage().getName().matches("org.xml.sax%") or
34-
cu.getPackage().getName() = "compileproperties" or
35-
cu.getPackage().getName() = "netscape.javascript" or
36-
cu.getPackage().getName() = ""
37-
}
38-
39-
predicate isRelevantForModels(Callable api) {
40-
not isInTestFile(api.getCompilationUnit().getFile()) and
41-
not isJdkInternal(api.getCompilationUnit()) and
42-
not api instanceof MainMethod
43-
}
44-
45-
class TargetApi extends Callable {
46-
TargetApi() {
47-
this.isPublic() and
48-
this.fromSource() and
49-
(
50-
this.getDeclaringType().isPublic() or
51-
superImpl(this).getDeclaringType().isPublic()
52-
) and
53-
isRelevantForModels(this)
54-
}
55-
}
56-
57-
private string isExtensible(RefType ref) {
58-
if ref.isFinal() then result = "false" else result = "true"
59-
}
60-
61-
private string typeAsModel(RefType type) {
62-
result = type.getCompilationUnit().getPackage().getName() + ";" + type.nestedName()
63-
}
64-
65-
private RefType bestTypeForModel(TargetApi api) {
66-
if exists(superImpl(api))
67-
then superImpl(api).fromSource() and result = superImpl(api).getDeclaringType()
68-
else result = api.getDeclaringType()
69-
}
70-
71-
/**
72-
* Returns the appropriate type name for the model. Either the type
73-
* declaring the method or the supertype introducing the method.
74-
*/
75-
private string typeAsSummaryModel(TargetApi api) { result = typeAsModel(bestTypeForModel(api)) }
76-
77-
/**
78-
* Computes the first 6 columns for CSV rows.
79-
*/
80-
private string asPartialModel(TargetApi api) {
81-
result =
82-
typeAsSummaryModel(api) + ";" //
83-
+ isExtensible(bestTypeForModel(api)) + ";" //
84-
+ api.getName() + ";" //
85-
+ paramsString(api) + ";" //
86-
+ /* ext + */ ";" //
87-
}
88-
89-
bindingset[input, output]
90-
string asValueModel(TargetApi api, string input, string output) {
91-
result = asSummaryModel(api, input, output, "value")
92-
}
93-
94-
bindingset[input, output, kind]
95-
string asSummaryModel(TargetApi api, string input, string output, string kind) {
96-
result =
97-
asPartialModel(api) + input + ";" //
98-
+ output + ";" //
99-
+ kind
100-
}
101-
102-
bindingset[input, output]
103-
string asTaintModel(TargetApi api, string input, string output) {
104-
result = asSummaryModel(api, input, output, "taint")
105-
}
106-
107-
bindingset[input, kind]
108-
string asSinkModel(TargetApi api, string input, string kind) {
109-
result = asPartialModel(api) + input + ";" + kind
110-
}
111-
112-
bindingset[output, kind]
113-
string asSourceModel(TargetApi api, string output, string kind) {
114-
result = asPartialModel(api) + output + ";" + kind
115-
}
116-
117-
private predicate isPrimitiveTypeUsedForBulkData(Type t) {
118-
t.getName().regexpMatch("byte|char|Byte|Character")
119-
}
120-
121-
predicate isRelevantType(Type t) {
122-
not t instanceof TypeClass and
123-
not t instanceof EnumType and
124-
not t instanceof PrimitiveType and
125-
not t instanceof BoxedType and
126-
not t.(RefType).getAnAncestor().hasQualifiedName("java.lang", "Number") and
127-
not t.(RefType).getAnAncestor().hasQualifiedName("java.nio.charset", "Charset") and
128-
(
129-
not t.(Array).getElementType() instanceof PrimitiveType or
130-
isPrimitiveTypeUsedForBulkData(t.(Array).getElementType())
131-
) and
132-
(
133-
not t.(Array).getElementType() instanceof BoxedType or
134-
isPrimitiveTypeUsedForBulkData(t.(Array).getElementType())
135-
) and
136-
(
137-
not t.(CollectionType).getElementType() instanceof BoxedType or
138-
isPrimitiveTypeUsedForBulkData(t.(CollectionType).getElementType())
139-
)
140-
}
141-
142-
predicate isRelevantTaintStep(DataFlow::Node node1, DataFlow::Node node2) {
143-
exists(DataFlow::Content f |
144-
readStep(node1, f, node2) and
145-
if f instanceof DataFlow::FieldContent
146-
then isRelevantType(f.(DataFlow::FieldContent).getField().getType())
147-
else
148-
if f instanceof DataFlow::SyntheticFieldContent
149-
then isRelevantType(f.(DataFlow::SyntheticFieldContent).getField().getType())
150-
else any()
151-
)
152-
or
153-
exists(DataFlow::Content f | storeStep(node1, f, node2) |
154-
f instanceof DataFlow::ArrayContent or
155-
f instanceof DataFlow::CollectionContent or
156-
f instanceof DataFlow::MapKeyContent or
157-
f instanceof DataFlow::MapValueContent
158-
)
159-
}
160-
161-
predicate isRelevantContent(DataFlow::Content f) {
162-
isRelevantType(f.(DataFlow::FieldContent).getField().getType()) or
163-
f instanceof DataFlow::ArrayContent or
164-
f instanceof DataFlow::CollectionContent or
165-
f instanceof DataFlow::MapKeyContent or
166-
f instanceof DataFlow::MapValueContent
167-
}
168-
169-
private string parameterAccess(Parameter p) {
170-
if
171-
p.getType() instanceof Array and
172-
not isPrimitiveTypeUsedForBulkData(p.getType().(Array).getElementType())
173-
then result = "Argument[" + p.getPosition() + "].ArrayElement"
174-
else
175-
if p.getType() instanceof ContainerType
176-
then result = "Argument[" + p.getPosition() + "].Element"
177-
else result = "Argument[" + p.getPosition() + "]"
178-
}
179-
180-
string parameterNodeAsInput(DataFlow::ParameterNode p) {
181-
result = parameterAccess(p.asParameter())
182-
or
183-
result = "Argument[-1]" and p instanceof DataFlow::InstanceParameterNode
184-
}
185-
186-
string returnNodeAsOutput(ReturnNodeExt node) {
187-
if node.getKind() instanceof ValueReturnKind
188-
then result = "ReturnValue"
189-
else
190-
exists(int pos | pos = node.getKind().(ParamUpdateReturnKind).getPosition() |
191-
result = parameterAccess(node.getEnclosingCallable().getParameter(pos))
192-
or
193-
result = "Argument[-1]" and pos = -1
194-
)
195-
}
1+
import ModelGeneratorUtilsSpecific
Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
import java
2+
private import semmle.code.java.dataflow.ExternalFlow
3+
private import semmle.code.java.dataflow.internal.ContainerFlow
4+
private import semmle.code.java.dataflow.internal.DataFlowImplCommon
5+
private import semmle.code.java.dataflow.DataFlow
6+
private import semmle.code.java.dataflow.internal.DataFlowPrivate
7+
8+
Method superImpl(Method m) {
9+
result = m.getAnOverride() and
10+
not exists(result.getAnOverride()) and
11+
not m instanceof ToStringMethod
12+
}
13+
14+
private predicate isInTestFile(File file) {
15+
file.getAbsolutePath().matches("%src/test/%") or
16+
file.getAbsolutePath().matches("%/guava-tests/%") or
17+
file.getAbsolutePath().matches("%/guava-testlib/%")
18+
}
19+
20+
private predicate isJdkInternal(CompilationUnit cu) {
21+
cu.getPackage().getName().matches("org.graalvm%") or
22+
cu.getPackage().getName().matches("com.sun%") or
23+
cu.getPackage().getName().matches("javax.swing%") or
24+
cu.getPackage().getName().matches("java.awt%") or
25+
cu.getPackage().getName().matches("sun%") or
26+
cu.getPackage().getName().matches("jdk.%") or
27+
cu.getPackage().getName().matches("java2d.%") or
28+
cu.getPackage().getName().matches("build.tools.%") or
29+
cu.getPackage().getName().matches("propertiesparser.%") or
30+
cu.getPackage().getName().matches("org.jcp.%") or
31+
cu.getPackage().getName().matches("org.w3c.%") or
32+
cu.getPackage().getName().matches("org.ietf.jgss.%") or
33+
cu.getPackage().getName().matches("org.xml.sax%") or
34+
cu.getPackage().getName() = "compileproperties" or
35+
cu.getPackage().getName() = "netscape.javascript" or
36+
cu.getPackage().getName() = ""
37+
}
38+
39+
predicate isRelevantForModels(Callable api) {
40+
not isInTestFile(api.getCompilationUnit().getFile()) and
41+
not isJdkInternal(api.getCompilationUnit()) and
42+
not api instanceof MainMethod
43+
}
44+
45+
class TargetApi extends Callable {
46+
TargetApi() {
47+
this.isPublic() and
48+
this.fromSource() and
49+
(
50+
this.getDeclaringType().isPublic() or
51+
superImpl(this).getDeclaringType().isPublic()
52+
) and
53+
isRelevantForModels(this)
54+
}
55+
}
56+
57+
private string isExtensible(RefType ref) {
58+
if ref.isFinal() then result = "false" else result = "true"
59+
}
60+
61+
private string typeAsModel(RefType type) {
62+
result = type.getCompilationUnit().getPackage().getName() + ";" + type.nestedName()
63+
}
64+
65+
private RefType bestTypeForModel(TargetApi api) {
66+
if exists(superImpl(api))
67+
then superImpl(api).fromSource() and result = superImpl(api).getDeclaringType()
68+
else result = api.getDeclaringType()
69+
}
70+
71+
/**
72+
* Returns the appropriate type name for the model. Either the type
73+
* declaring the method or the supertype introducing the method.
74+
*/
75+
private string typeAsSummaryModel(TargetApi api) { result = typeAsModel(bestTypeForModel(api)) }
76+
77+
/**
78+
* Computes the first 6 columns for CSV rows.
79+
*/
80+
private string asPartialModel(TargetApi api) {
81+
result =
82+
typeAsSummaryModel(api) + ";" //
83+
+ isExtensible(bestTypeForModel(api)) + ";" //
84+
+ api.getName() + ";" //
85+
+ paramsString(api) + ";" //
86+
+ /* ext + */ ";" //
87+
}
88+
89+
bindingset[input, output]
90+
string asValueModel(TargetApi api, string input, string output) {
91+
result = asSummaryModel(api, input, output, "value")
92+
}
93+
94+
bindingset[input, output, kind]
95+
string asSummaryModel(TargetApi api, string input, string output, string kind) {
96+
result =
97+
asPartialModel(api) + input + ";" //
98+
+ output + ";" //
99+
+ kind
100+
}
101+
102+
bindingset[input, output]
103+
string asTaintModel(TargetApi api, string input, string output) {
104+
result = asSummaryModel(api, input, output, "taint")
105+
}
106+
107+
bindingset[input, kind]
108+
string asSinkModel(TargetApi api, string input, string kind) {
109+
result = asPartialModel(api) + input + ";" + kind
110+
}
111+
112+
bindingset[output, kind]
113+
string asSourceModel(TargetApi api, string output, string kind) {
114+
result = asPartialModel(api) + output + ";" + kind
115+
}
116+
117+
private predicate isPrimitiveTypeUsedForBulkData(Type t) {
118+
t.getName().regexpMatch("byte|char|Byte|Character")
119+
}
120+
121+
predicate isRelevantType(Type t) {
122+
not t instanceof TypeClass and
123+
not t instanceof EnumType and
124+
not t instanceof PrimitiveType and
125+
not t instanceof BoxedType and
126+
not t.(RefType).getAnAncestor().hasQualifiedName("java.lang", "Number") and
127+
not t.(RefType).getAnAncestor().hasQualifiedName("java.nio.charset", "Charset") and
128+
(
129+
not t.(Array).getElementType() instanceof PrimitiveType or
130+
isPrimitiveTypeUsedForBulkData(t.(Array).getElementType())
131+
) and
132+
(
133+
not t.(Array).getElementType() instanceof BoxedType or
134+
isPrimitiveTypeUsedForBulkData(t.(Array).getElementType())
135+
) and
136+
(
137+
not t.(CollectionType).getElementType() instanceof BoxedType or
138+
isPrimitiveTypeUsedForBulkData(t.(CollectionType).getElementType())
139+
)
140+
}
141+
142+
predicate isRelevantTaintStep(DataFlow::Node node1, DataFlow::Node node2) {
143+
exists(DataFlow::Content f |
144+
readStep(node1, f, node2) and
145+
if f instanceof DataFlow::FieldContent
146+
then isRelevantType(f.(DataFlow::FieldContent).getField().getType())
147+
else
148+
if f instanceof DataFlow::SyntheticFieldContent
149+
then isRelevantType(f.(DataFlow::SyntheticFieldContent).getField().getType())
150+
else any()
151+
)
152+
or
153+
exists(DataFlow::Content f | storeStep(node1, f, node2) |
154+
f instanceof DataFlow::ArrayContent or
155+
f instanceof DataFlow::CollectionContent or
156+
f instanceof DataFlow::MapKeyContent or
157+
f instanceof DataFlow::MapValueContent
158+
)
159+
}
160+
161+
predicate isRelevantContent(DataFlow::Content f) {
162+
isRelevantType(f.(DataFlow::FieldContent).getField().getType()) or
163+
f instanceof DataFlow::ArrayContent or
164+
f instanceof DataFlow::CollectionContent or
165+
f instanceof DataFlow::MapKeyContent or
166+
f instanceof DataFlow::MapValueContent
167+
}
168+
169+
private string parameterAccess(Parameter p) {
170+
if
171+
p.getType() instanceof Array and
172+
not isPrimitiveTypeUsedForBulkData(p.getType().(Array).getElementType())
173+
then result = "Argument[" + p.getPosition() + "].ArrayElement"
174+
else
175+
if p.getType() instanceof ContainerType
176+
then result = "Argument[" + p.getPosition() + "].Element"
177+
else result = "Argument[" + p.getPosition() + "]"
178+
}
179+
180+
string parameterNodeAsInput(DataFlow::ParameterNode p) {
181+
result = parameterAccess(p.asParameter())
182+
or
183+
result = "Argument[-1]" and p instanceof DataFlow::InstanceParameterNode
184+
}
185+
186+
string returnNodeAsOutput(ReturnNodeExt node) {
187+
if node.getKind() instanceof ValueReturnKind
188+
then result = "ReturnValue"
189+
else
190+
exists(int pos | pos = node.getKind().(ParamUpdateReturnKind).getPosition() |
191+
result = parameterAccess(node.getEnclosingCallable().getParameter(pos))
192+
or
193+
result = "Argument[-1]" and pos = -1
194+
)
195+
}

0 commit comments

Comments
 (0)