mirror of
https://github.com/github/codeql.git
synced 2025-12-20 18:56:32 +01:00
Rework filter to exclude simple constructors
This commit is contained in:
@@ -1,48 +0,0 @@
|
||||
/** Provides classes and predicates related to support coverage of external libraries. */
|
||||
|
||||
import java
|
||||
private import semmle.code.java.dataflow.FlowSources
|
||||
|
||||
/**
|
||||
* Gets the coverage support for the given `Callable`. If the `Callable` is not supported, returns "?".
|
||||
*/
|
||||
string supportKind(Callable api) {
|
||||
if api instanceof TaintPreservingCallable
|
||||
then result = "taint-preserving"
|
||||
else
|
||||
if summaryCall(api)
|
||||
then result = "summary"
|
||||
else
|
||||
if sink(api)
|
||||
then result = "sink"
|
||||
else
|
||||
if source(api)
|
||||
then result = "source"
|
||||
else result = "?"
|
||||
}
|
||||
|
||||
private predicate summaryCall(Callable api) {
|
||||
summaryModel(packageName(api), typeName(api), _, api.getName(), _, _, _, _, _)
|
||||
}
|
||||
|
||||
private predicate sink(Callable api) {
|
||||
sinkModel(packageName(api), typeName(api), _, api.getName(), _, _, _, _)
|
||||
}
|
||||
|
||||
private predicate source(Callable api) {
|
||||
sourceModel(packageName(api), typeName(api), _, api.getName(), _, _, _, _)
|
||||
or
|
||||
exists(Call call, DataFlow::Node arg |
|
||||
call.getCallee() = api and
|
||||
[call.getAnArgument(), call.getQualifier()] = arg.asExpr() and
|
||||
arg instanceof RemoteFlowSource
|
||||
)
|
||||
}
|
||||
|
||||
private string packageName(Callable api) {
|
||||
result = api.getCompilationUnit().getPackage().toString()
|
||||
}
|
||||
|
||||
private string typeName(Callable api) {
|
||||
result = api.getDeclaringType().getAnAncestor().getSourceDeclaration().toString()
|
||||
}
|
||||
@@ -1,8 +1,13 @@
|
||||
/** Provides classes and predicates related to handling APIs from external libraries. */
|
||||
|
||||
private import java
|
||||
private import APIUsage
|
||||
private import semmle.code.java.dataflow.DataFlow
|
||||
private import semmle.code.java.dataflow.DataFlow
|
||||
private import semmle.code.java.dataflow.ExternalFlow
|
||||
private import semmle.code.java.dataflow.FlowSources
|
||||
private import semmle.code.java.dataflow.FlowSummary
|
||||
private import semmle.code.java.dataflow.internal.DataFlowPrivate
|
||||
private import semmle.code.java.dataflow.TaintTracking
|
||||
|
||||
/**
|
||||
* An external API from either the Java Standard Library or a 3rd party library.
|
||||
@@ -10,8 +15,16 @@ private import semmle.code.java.dataflow.ExternalFlow
|
||||
class ExternalAPI extends Callable {
|
||||
ExternalAPI() { not this.fromSource() }
|
||||
|
||||
/** Holds if this API is a candidate worth supporting */
|
||||
predicate isWorthSupporting() { not isTestLibrary() and not isParameterlessConstructor() }
|
||||
|
||||
/** Holds if this API is is a constructor without parameters */
|
||||
predicate isParameterlessConstructor() {
|
||||
this instanceof Constructor and this.getNumberOfParameters() = 0
|
||||
}
|
||||
|
||||
/** Holds if this API is part of a common testing library or framework */
|
||||
predicate isTestLibrary() { getDeclaringType() instanceof TestLibrary }
|
||||
private predicate isTestLibrary() { getDeclaringType() instanceof TestLibrary }
|
||||
|
||||
/**
|
||||
* Gets information about the external API in the form expected by the CSV modeling framework.
|
||||
@@ -22,9 +35,6 @@ class ExternalAPI extends Callable {
|
||||
"#" + api.getName() + paramsString(api)
|
||||
}
|
||||
|
||||
/** Holds if this API is not yet supported by existing CodeQL libraries */
|
||||
predicate isSupported() { not supportKind(this) = "?" }
|
||||
|
||||
/**
|
||||
* Gets the jar file containing this API. Normalizes the Java Runtime to "rt.jar" despite the presence of modules.
|
||||
*/
|
||||
@@ -33,6 +43,39 @@ class ExternalAPI extends Callable {
|
||||
private string containerAsJar(Container container) {
|
||||
if container instanceof JarFile then result = container.getBaseName() else result = "rt.jar"
|
||||
}
|
||||
|
||||
/** Gets a node that is an input to a call to this API. */
|
||||
private DataFlow::Node getAnInput() {
|
||||
exists(Call call | call.getCallee().getSourceDeclaration() = this |
|
||||
result.asExpr().(Argument).getCall() = call or
|
||||
result.(ArgumentNode).getCall() = call
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets a node that is an output from a call to this API. */
|
||||
private DataFlow::Node getAnOutput() {
|
||||
exists(Call call | call.getCallee().getSourceDeclaration() = this |
|
||||
result.asExpr() = call or
|
||||
result.(DataFlow::PostUpdateNode).getPreUpdateNode().(ArgumentNode).getCall() = call
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if this API has a supported summary. */
|
||||
predicate hasSummary() {
|
||||
this instanceof SummarizedCallable or
|
||||
TaintTracking::localAdditionalTaintStep(this.getAnInput(), _)
|
||||
}
|
||||
|
||||
/** Holds if this API is a known source. */
|
||||
predicate isSource() {
|
||||
this.getAnOutput() instanceof RemoteFlowSource or sourceNode(this.getAnOutput(), _)
|
||||
}
|
||||
|
||||
/** Holds if this API is a known sink. */
|
||||
predicate isSink() { sinkNode(this.getAnInput(), _) }
|
||||
|
||||
/** 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. */
|
||||
predicate isSupported() { hasSummary() or isSource() or isSink() }
|
||||
}
|
||||
|
||||
private class TestLibrary extends RefType {
|
||||
|
||||
@@ -16,6 +16,6 @@ where
|
||||
c.getCallee() = a and
|
||||
not c.getFile() instanceof GeneratedFile and
|
||||
a.jarContainer() = jarname and
|
||||
not a.isTestLibrary()
|
||||
a.isWorthSupporting()
|
||||
)
|
||||
select jarname, usages order by usages desc
|
||||
|
||||
@@ -7,14 +7,13 @@
|
||||
*/
|
||||
|
||||
import java
|
||||
import APIUsage
|
||||
import ExternalAPI
|
||||
import semmle.code.java.GeneratedFiles
|
||||
|
||||
from ExternalAPI api, int usages
|
||||
where
|
||||
not api.isTestLibrary() and
|
||||
supportKind(api) = "sink" and
|
||||
api.isWorthSupporting() and
|
||||
api.isSink() and
|
||||
usages =
|
||||
strictcount(Call c |
|
||||
c.getCallee().getSourceDeclaration() = api and
|
||||
|
||||
@@ -7,14 +7,13 @@
|
||||
*/
|
||||
|
||||
import java
|
||||
import APIUsage
|
||||
import ExternalAPI
|
||||
import semmle.code.java.GeneratedFiles
|
||||
|
||||
from ExternalAPI api, int usages
|
||||
where
|
||||
not api.isTestLibrary() and
|
||||
supportKind(api) = "source" and
|
||||
api.isWorthSupporting() and
|
||||
api.isSource() and
|
||||
usages =
|
||||
strictcount(Call c |
|
||||
c.getCallee().getSourceDeclaration() = api and
|
||||
|
||||
@@ -7,14 +7,13 @@
|
||||
*/
|
||||
|
||||
import java
|
||||
import APIUsage
|
||||
import ExternalAPI
|
||||
import semmle.code.java.GeneratedFiles
|
||||
|
||||
from ExternalAPI api, int usages
|
||||
where
|
||||
not api.isTestLibrary() and
|
||||
supportKind(api) = ["summary", "taint-preserving"] and
|
||||
api.isWorthSupporting() and
|
||||
api.hasSummary() and
|
||||
usages =
|
||||
strictcount(Call c |
|
||||
c.getCallee().getSourceDeclaration() = api and
|
||||
|
||||
@@ -7,13 +7,12 @@
|
||||
*/
|
||||
|
||||
import java
|
||||
import APIUsage
|
||||
import ExternalAPI
|
||||
import semmle.code.java.GeneratedFiles
|
||||
|
||||
from ExternalAPI api, int usages
|
||||
where
|
||||
not api.isTestLibrary() and
|
||||
api.isWorthSupporting() and
|
||||
not api.isSupported() and
|
||||
usages =
|
||||
strictcount(Call c |
|
||||
|
||||
Reference in New Issue
Block a user