mirror of
https://github.com/github/codeql.git
synced 2026-03-05 15:16:47 +01:00
118 lines
3.3 KiB
Plaintext
118 lines
3.3 KiB
Plaintext
import java
|
|
import semmle.code.java.dataflow.ExternalFlow
|
|
import semmle.code.java.dataflow.internal.ContainerFlow
|
|
|
|
Method superImpl(Method m) {
|
|
result = m.getAnOverride() and
|
|
not exists(result.getAnOverride()) and
|
|
not m instanceof ToStringMethod
|
|
}
|
|
|
|
class TargetAPI extends Callable {
|
|
TargetAPI() {
|
|
this.isPublic() and
|
|
this.fromSource() and
|
|
(
|
|
this.getDeclaringType().isPublic() or
|
|
superImpl(this).getDeclaringType().isPublic()
|
|
) and
|
|
isRelevantForModels(this)
|
|
}
|
|
}
|
|
|
|
private string isExtensible(RefType ref) {
|
|
if ref.isFinal() then result = "false" else result = "true"
|
|
}
|
|
|
|
predicate isRelevantForModels(Callable api) {
|
|
not isInTestFile(api.getCompilationUnit().getFile()) and
|
|
not isJdkInternal(api.getCompilationUnit())
|
|
}
|
|
|
|
private predicate isInTestFile(File file) {
|
|
file.getAbsolutePath().matches("%src/test/%") or
|
|
file.getAbsolutePath().matches("%/guava-tests/%") or
|
|
file.getAbsolutePath().matches("%/guava-testlib/%")
|
|
}
|
|
|
|
private predicate isJdkInternal(CompilationUnit cu) {
|
|
cu.getPackage().getName().matches("com.sun") or
|
|
cu.getPackage().getName().matches("sun") or
|
|
cu.getPackage().getName().matches("")
|
|
}
|
|
|
|
bindingset[input, output]
|
|
string asTaintModel(Callable api, string input, string output) {
|
|
result = asSummaryModel(api, input, output, "taint")
|
|
}
|
|
|
|
bindingset[input, output]
|
|
string asValueModel(Callable api, string input, string output) {
|
|
result = asSummaryModel(api, input, output, "value")
|
|
}
|
|
|
|
bindingset[input, output, kind]
|
|
string asSummaryModel(Callable api, string input, string output, string kind) {
|
|
result =
|
|
asPartialModel(api) + input + ";" //
|
|
+ output + ";" //
|
|
+ kind + ";" //
|
|
}
|
|
|
|
bindingset[input, kind]
|
|
string asSinkModel(Callable api, string input, string kind) {
|
|
result =
|
|
asPartialModel(api) + input + ";" //
|
|
+ kind + ";" //
|
|
}
|
|
|
|
bindingset[output, kind]
|
|
string asSourceModel(Callable api, string output, string kind) {
|
|
result =
|
|
asPartialModel(api) + output + ";" //
|
|
+ kind + ";" //
|
|
}
|
|
|
|
/**
|
|
* Computes the first 6 columns for CSV rows.
|
|
*/
|
|
private string asPartialModel(Callable api) {
|
|
result =
|
|
typeAsSummaryModel(api) + ";" //
|
|
+ isExtensible(bestTypeForModel(api)) + ";" //
|
|
+ api.getName() + ";" //
|
|
+ paramsString(api) + ";" //
|
|
+ /* ext + */ ";" //
|
|
}
|
|
|
|
/**
|
|
* Returns the appropriate type name for the model. Either the type
|
|
* declaring the method or the supertype introducing the method.
|
|
*/
|
|
private string typeAsSummaryModel(Callable api) { result = typeAsModel(bestTypeForModel(api)) }
|
|
|
|
private RefType bestTypeForModel(Callable api) {
|
|
if exists(superImpl(api))
|
|
then superImpl(api).fromSource() and result = superImpl(api).getDeclaringType()
|
|
else result = api.getDeclaringType()
|
|
}
|
|
|
|
private string typeAsModel(RefType type) {
|
|
result = type.getCompilationUnit().getPackage().getName() + ";" + type.nestedName()
|
|
}
|
|
|
|
string parameterAccess(Parameter p) {
|
|
if
|
|
p.getType() instanceof Array and
|
|
not isPrimitiveTypeUsedForBulkData(p.getType().(Array).getElementType())
|
|
then result = "ArrayElement of Argument[" + p.getPosition() + "]"
|
|
else
|
|
if p.getType() instanceof ContainerType
|
|
then result = "Element of Argument[" + p.getPosition() + "]"
|
|
else result = "Argument[" + p.getPosition() + "]"
|
|
}
|
|
|
|
predicate isPrimitiveTypeUsedForBulkData(Type t) {
|
|
t.getName().regexpMatch("byte|char|Byte|Character")
|
|
}
|