Skip to content

Commit 7b901b4

Browse files
committed
Update library used by java query.
1 parent 0ee090b commit 7b901b4

File tree

1 file changed

+151
-141
lines changed
  • extensions/ql-vscode/src/data-extensions-editor/queries

1 file changed

+151
-141
lines changed

extensions/ql-vscode/src/data-extensions-editor/queries/java.ts

Lines changed: 151 additions & 141 deletions
Original file line numberDiff line numberDiff line change
@@ -33,147 +33,157 @@ select apiName, supported, usage
3333
dependencies: {
3434
"ExternalApi.qll": `/** Provides classes and predicates related to handling APIs from external libraries. */
3535
36-
private import java
37-
private import semmle.code.java.dataflow.DataFlow
38-
private import semmle.code.java.dataflow.ExternalFlow
39-
private import semmle.code.java.dataflow.FlowSources
40-
private import semmle.code.java.dataflow.FlowSummary
41-
private import semmle.code.java.dataflow.internal.DataFlowPrivate
42-
private import semmle.code.java.dataflow.TaintTracking
43-
44-
pragma[nomagic]
45-
private predicate isTestPackage(Package p) {
46-
p.getName()
47-
.matches([
48-
"org.junit%", "junit.%", "org.mockito%", "org.assertj%",
49-
"com.github.tomakehurst.wiremock%", "org.hamcrest%", "org.springframework.test.%",
50-
"org.springframework.mock.%", "org.springframework.boot.test.%", "reactor.test%",
51-
"org.xmlunit%", "org.testcontainers.%", "org.opentest4j%", "org.mockserver%",
52-
"org.powermock%", "org.skyscreamer.jsonassert%", "org.rnorth.visibleassertions",
53-
"org.openqa.selenium%", "com.gargoylesoftware.htmlunit%", "org.jboss.arquillian.testng%",
54-
"org.testng%"
55-
])
56-
}
57-
58-
/**
59-
* A test library.
60-
*/
61-
private class TestLibrary extends RefType {
62-
TestLibrary() { isTestPackage(this.getPackage()) }
63-
}
64-
65-
private string containerAsJar(Container container) {
66-
if container instanceof JarFile then result = container.getBaseName() else result = "rt.jar"
67-
}
68-
69-
/** Holds if the given callable is not worth supporting. */
70-
private predicate isUninteresting(Callable c) {
71-
c.getDeclaringType() instanceof TestLibrary or
72-
c.(Constructor).isParameterless()
73-
}
74-
75-
/**
76-
* An external API from either the Standard Library or a 3rd party library.
77-
*/
78-
class ExternalApi extends Callable {
79-
ExternalApi() { not this.fromSource() and not isUninteresting(this) }
80-
81-
/**
82-
* Gets information about the external API in the form expected by the MaD modeling framework.
83-
*/
84-
string getApiName() {
85-
result =
86-
this.getDeclaringType().getPackage() + "." + this.getDeclaringType().getSourceDeclaration() +
87-
"#" + this.getName() + paramsString(this)
88-
}
89-
90-
/**
91-
* Gets the jar file containing this API. Normalizes the Java Runtime to "rt.jar" despite the presence of modules.
92-
*/
93-
string jarContainer() { result = containerAsJar(this.getCompilationUnit().getParentContainer*()) }
94-
95-
/** Gets a node that is an input to a call to this API. */
96-
private DataFlow::Node getAnInput() {
97-
exists(Call call | call.getCallee().getSourceDeclaration() = this |
98-
result.asExpr().(Argument).getCall() = call or
99-
result.(ArgumentNode).getCall().asCall() = call
100-
)
101-
}
102-
103-
/** Gets a node that is an output from a call to this API. */
104-
private DataFlow::Node getAnOutput() {
105-
exists(Call call | call.getCallee().getSourceDeclaration() = this |
106-
result.asExpr() = call or
107-
result.(DataFlow::PostUpdateNode).getPreUpdateNode().(ArgumentNode).getCall().asCall() = call
108-
)
109-
}
110-
111-
/** Holds if this API has a supported summary. */
112-
pragma[nomagic]
113-
predicate hasSummary() {
114-
this = any(SummarizedCallable sc).asCallable() or
115-
TaintTracking::localAdditionalTaintStep(this.getAnInput(), _)
116-
}
117-
118-
pragma[nomagic]
119-
predicate isSource() {
120-
this.getAnOutput() instanceof RemoteFlowSource or sourceNode(this.getAnOutput(), _)
121-
}
122-
123-
/** Holds if this API is a known sink. */
124-
pragma[nomagic]
125-
predicate isSink() { sinkNode(this.getAnInput(), _) }
126-
127-
/** Holds if this API is supported by existing CodeQL libraries, that is, it is either a recognized source or sink or has a flow summary. */
128-
predicate isSupported() { this.hasSummary() or this.isSource() or this.isSink() }
129-
}
130-
131-
/** DEPRECATED: Alias for ExternalApi */
132-
deprecated class ExternalAPI = ExternalApi;
133-
134-
/**
135-
* Gets the limit for the number of results produced by a telemetry query.
136-
*/
137-
int resultLimit() { result = 1000 }
138-
139-
/**
140-
* Holds if it is relevant to count usages of \`api\`.
141-
*/
142-
signature predicate relevantApi(ExternalApi api);
143-
144-
/**
145-
* Given a predicate to count relevant API usages, this module provides a predicate
146-
* for restricting the number or returned results based on a certain limit.
147-
*/
148-
module Results<relevantApi/1 getRelevantUsages> {
149-
private int getUsages(string apiName) {
150-
result =
151-
strictcount(Call c, ExternalApi api |
152-
c.getCallee().getSourceDeclaration() = api and
153-
not c.getFile() instanceof GeneratedFile and
154-
apiName = api.getApiName() and
155-
getRelevantUsages(api)
156-
)
157-
}
158-
159-
private int getOrder(string apiInfo) {
160-
apiInfo =
161-
rank[result](string info, int usages |
162-
usages = getUsages(info)
163-
|
164-
info order by usages desc, info
165-
)
166-
}
167-
168-
/**
169-
* Holds if there exists an API with \`apiName\` that is being used \`usages\` times
170-
* and if it is in the top results (guarded by resultLimit).
171-
*/
172-
predicate restrict(string apiName, int usages) {
173-
usages = getUsages(apiName) and
174-
getOrder(apiName) <= resultLimit()
175-
}
176-
}
36+
private import java
37+
private import semmle.code.java.dataflow.DataFlow
38+
private import semmle.code.java.dataflow.ExternalFlow
39+
private import semmle.code.java.dataflow.FlowSources
40+
private import semmle.code.java.dataflow.FlowSummary
41+
private import semmle.code.java.dataflow.internal.DataFlowPrivate
42+
private import semmle.code.java.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl
43+
private import semmle.code.java.dataflow.TaintTracking
44+
45+
pragma[nomagic]
46+
private predicate isTestPackage(Package p) {
47+
p.getName()
48+
.matches([
49+
"org.junit%", "junit.%", "org.mockito%", "org.assertj%",
50+
"com.github.tomakehurst.wiremock%", "org.hamcrest%", "org.springframework.test.%",
51+
"org.springframework.mock.%", "org.springframework.boot.test.%", "reactor.test%",
52+
"org.xmlunit%", "org.testcontainers.%", "org.opentest4j%", "org.mockserver%",
53+
"org.powermock%", "org.skyscreamer.jsonassert%", "org.rnorth.visibleassertions",
54+
"org.openqa.selenium%", "com.gargoylesoftware.htmlunit%", "org.jboss.arquillian.testng%",
55+
"org.testng%"
56+
])
57+
}
58+
59+
/**
60+
* A test library.
61+
*/
62+
private class TestLibrary extends RefType {
63+
TestLibrary() { isTestPackage(this.getPackage()) }
64+
}
65+
66+
private string containerAsJar(Container container) {
67+
if container instanceof JarFile then result = container.getBaseName() else result = "rt.jar"
68+
}
69+
70+
/** Holds if the given callable is not worth supporting. */
71+
private predicate isUninteresting(Callable c) {
72+
c.getDeclaringType() instanceof TestLibrary or
73+
c.(Constructor).isParameterless()
74+
}
75+
76+
/**
77+
* An external API from either the Standard Library or a 3rd party library.
78+
*/
79+
class ExternalApi extends Callable {
80+
ExternalApi() { not this.fromSource() and not isUninteresting(this) }
81+
82+
/**
83+
* Gets information about the external API in the form expected by the MaD modeling framework.
84+
*/
85+
string getApiName() {
86+
result =
87+
this.getDeclaringType().getPackage() + "." + this.getDeclaringType().getSourceDeclaration() +
88+
"#" + this.getName() + paramsString(this)
89+
}
90+
91+
/**
92+
* Gets the jar file containing this API. Normalizes the Java Runtime to "rt.jar" despite the presence of modules.
93+
*/
94+
string jarContainer() { result = containerAsJar(this.getCompilationUnit().getParentContainer*()) }
95+
96+
/** Gets a node that is an input to a call to this API. */
97+
private DataFlow::Node getAnInput() {
98+
exists(Call call | call.getCallee().getSourceDeclaration() = this |
99+
result.asExpr().(Argument).getCall() = call or
100+
result.(ArgumentNode).getCall().asCall() = call
101+
)
102+
}
103+
104+
/** Gets a node that is an output from a call to this API. */
105+
private DataFlow::Node getAnOutput() {
106+
exists(Call call | call.getCallee().getSourceDeclaration() = this |
107+
result.asExpr() = call or
108+
result.(DataFlow::PostUpdateNode).getPreUpdateNode().(ArgumentNode).getCall().asCall() = call
109+
)
110+
}
111+
112+
/** Holds if this API has a supported summary. */
113+
pragma[nomagic]
114+
predicate hasSummary() {
115+
this = any(SummarizedCallable sc).asCallable() or
116+
TaintTracking::localAdditionalTaintStep(this.getAnInput(), _)
117+
}
118+
119+
pragma[nomagic]
120+
predicate isSource() {
121+
this.getAnOutput() instanceof RemoteFlowSource or sourceNode(this.getAnOutput(), _)
122+
}
123+
124+
/** Holds if this API is a known sink. */
125+
pragma[nomagic]
126+
predicate isSink() { sinkNode(this.getAnInput(), _) }
127+
128+
/** Holds if this API is a known neutral. */
129+
pragma[nomagic]
130+
predicate isNeutral() { this = any(FlowSummaryImpl::Public::NeutralCallable nsc).asCallable() }
131+
132+
/**
133+
* Holds if this API is supported by existing CodeQL libraries, that is, it is either a
134+
* recognized source, sink or neutral or it has a flow summary.
135+
*/
136+
predicate isSupported() {
137+
this.hasSummary() or this.isSource() or this.isSink() or this.isNeutral()
138+
}
139+
}
140+
141+
/** DEPRECATED: Alias for ExternalApi */
142+
deprecated class ExternalAPI = ExternalApi;
143+
144+
/**
145+
* Gets the limit for the number of results produced by a telemetry query.
146+
*/
147+
int resultLimit() { result = 1000 }
148+
149+
/**
150+
* Holds if it is relevant to count usages of \`api\`.
151+
*/
152+
signature predicate relevantApi(ExternalApi api);
153+
154+
/**
155+
* Given a predicate to count relevant API usages, this module provides a predicate
156+
* for restricting the number or returned results based on a certain limit.
157+
*/
158+
module Results<relevantApi/1 getRelevantUsages> {
159+
private int getUsages(string apiName) {
160+
result =
161+
strictcount(Call c, ExternalApi api |
162+
c.getCallee().getSourceDeclaration() = api and
163+
not c.getFile() instanceof GeneratedFile and
164+
apiName = api.getApiName() and
165+
getRelevantUsages(api)
166+
)
167+
}
168+
169+
private int getOrder(string apiInfo) {
170+
apiInfo =
171+
rank[result](string info, int usages |
172+
usages = getUsages(info)
173+
|
174+
info order by usages desc, info
175+
)
176+
}
177+
178+
/**
179+
* Holds if there exists an API with \`apiName\` that is being used \`usages\` times
180+
* and if it is in the top results (guarded by resultLimit).
181+
*/
182+
predicate restrict(string apiName, int usages) {
183+
usages = getUsages(apiName) and
184+
getOrder(apiName) <= resultLimit()
185+
}
186+
}
177187
`,
178188
},
179189
};

0 commit comments

Comments
 (0)