Merge branch 'main' into rc/3.7

This commit is contained in:
Andrew Eisenberg
2022-09-20 08:33:58 -07:00
2309 changed files with 133758 additions and 43219 deletions

View File

@@ -0,0 +1,7 @@
---
category: deprecated
---
* The predicate `Annotation.getAValue()` has been deprecated because it might lead to obtaining the value of the wrong annotation element by accident. `getValue(string)` (or one of the value type specific predicates) should be used to explicitly specify the name of the annotation element.
* The predicate `Annotation.getAValue(string)` has been renamed to `getAnArrayValue(string)`.
* The predicate `SuppressWarningsAnnotation.getASuppressedWarningLiteral()` has been deprecated because it unnecessarily restricts the result type; `getASuppressedWarning()` should be used instead.
* The predicates `TargetAnnotation.getATargetExpression()` and `RetentionAnnotation.getRetentionPolicyExpression()` have been deprecated because getting the enum constant read expression is rarely useful, instead the corresponding predicates for getting the name of the referenced enum constants should be used.

View File

@@ -0,0 +1,9 @@
---
category: feature
---
* The predicates of the CodeQL class `Annotation` have been improved:
* Convenience value type specific predicates have been added, such as `getEnumConstantValue(string)` or `getStringValue(string)`.
* Convenience predicates for elements with array values have been added, such as `getAnEnumConstantArrayValue(string)`. While the behavior of the existing predicates has not changed, usage of them should be reviewed (or replaced with the newly added predicate) to make sure they work correctly for elements with array values.
* Some internal CodeQL usage of the `Annotation` predicates has been adjusted and corrected; this might affect the results of some queries.
* New predicates have been added to the CodeQL class `Annotatable` to support getting declared and associated annotations. As part of that, `hasAnnotation()` has been changed to also consider inherited annotations, to be consistent with `hasAnnotation(string, string)` and `getAnAnnotation()`. The newly added predicate `hasDeclaredAnnotation()` can be used as replacement for the old functionality.
* New predicates have been added to the CodeQL class `AnnotationType` to simplify getting information about usage of JDK meta-annotations, such as `@Retention`.

View File

@@ -0,0 +1,4 @@
---
category: feature
---
* Added a new predicate, `allowsBackup`, in the `AndroidApplicationXmlElement` class. This predicate detects if the application element does not disable the `android:allowBackup` attribute.

View File

@@ -0,0 +1,5 @@
---
category: minorAnalysis
---
* Added taint flow models for the `java.lang.String.(charAt|getBytes)` methods.
* Improved taint flow models for the `java.lang.String.(replace|replaceFirst|replaceAll)` methods. Additional results may be found where users do not properly sanitize their inputs.

View File

@@ -0,0 +1,10 @@
---
category: minorAnalysis
---
* Added new flow steps for the following Android classes:
* `android.content.ContentResolver`
* `android.content.ContentProviderClient`
* `android.content.ContentProviderOperation`
* `android.content.ContentProviderOperation$Builder`
* `android.content.ContentProviderResult`
* `android.database.Cursor`

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* Added flow summary for `org.springframework.data.repository.CrudRepository.save()`.

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* Added flow sinks, sources and summaries for the Kotlin standard library.

View File

@@ -0,0 +1,5 @@
---
category: minorAnalysis
---
* Added new flow steps for `androidx.core.app.NotificationCompat` and its inner classes.

View File

@@ -0,0 +1,5 @@
---
category: minorAnalysis
---
* Added new sinks to the query `java/android/implict-pendingintents` to take into account the classes `androidx.core.app.NotificationManagerCompat` and `androidx.core.app.AlarmManagerCompat`.

View File

@@ -0,0 +1,4 @@
---
category: fix
---
* Fixed an issue in the taint tracking analysis where implicit reads were not allowed by default in sinks or additional taint steps that used flow states.

View File

@@ -0,0 +1,4 @@
---
category: breaking
---
* The `Member.getQualifiedName()` predicate result now includes the qualified name of the declaring type.

View File

@@ -0,0 +1,4 @@
---
category: majorAnalysis
---
* The virtual dispatch relation used in data flow now favors summary models over source code for dispatch to interface methods from `java.util` unless there is evidence that a specific source implementation is reachable. This should provide increased precision for any projects that include, for example, custom `List` or `Map` implementations.

View File

@@ -19,7 +19,7 @@
### Minor Analysis Improvements
* Added new flow steps for the classes `java.io.Path` and `java.nio.Paths`.
* Added new flow steps for the classes `java.nio.file.Path` and `java.nio.file.Paths`.
* The class `AndroidFragment` now also models the Android Jetpack version of the `Fragment` class (`androidx.fragment.app.Fragment`).
* Java 19 builds can now be extracted. There are no non-preview new language features in this release, so the only user-visible change is that the CodeQL extractor will now correctly trace compilations using the JDK 19 release of `javac`.
* Classes and methods that are seen with several different paths during the extraction process (for example, packaged into different JAR files) now report an arbitrarily selected location via their `getLocation` and `hasLocationInfo` predicates, rather than reporting all of them. This may lead to reduced alert duplication.

View File

@@ -216,7 +216,7 @@ private predicate fixedHasLocation(Top l, Location loc, File f) {
min(Location candidateLoc |
hasLocation(l, candidateLoc)
|
candidateLoc order by candidateLoc.getFile().toString()
candidateLoc order by candidateLoc.getFile().getAbsolutePath()
) and
not hasSourceLocation(l, _, _) and
locations_default(loc, f, _, _, _, _)

View File

@@ -44,12 +44,100 @@ class Annotation extends @annotation, Expr {
result = this.getType().getAnnotationElement(name)
}
/** Gets a value of an annotation element. */
Expr getAValue() { filteredAnnotValue(this, _, result) }
/**
* DEPRECATED: Getting the value of _any_ annotation element is error-prone because
* it could lead to selecting the value of the wrong element by accident (for example
* when an annotation type is extended in the future). Prefer the predicate `getValue(string)`
* and explicitly specify the element name. Use `getValue(_)` if it is really desired to
* get the value of any element.
*
* Gets a value of an annotation element. This includes default values in case
* no explicit value is specified. For elements with an array value type this
* might have an `ArrayInit` as result. To properly handle array values, prefer
* the predicate `getAnArrayValue`.
*/
deprecated Expr getAValue() { filteredAnnotValue(this, _, result) }
/** Gets the value of the annotation element with the specified `name`. */
/**
* Gets the value of the annotation element with the specified `name`.
* This includes default values in case no explicit value is specified.
* For elements with an array value type this might get an `ArrayInit` instance.
* To properly handle array values, prefer the predicate `getAnArrayValue`.
*/
Expr getValue(string name) { filteredAnnotValue(this, this.getAnnotationElement(name), result) }
/**
* Gets the value of the annotation element, if its type is not an array.
* This guarantees that for consistency even elements of type array with a
* single value have no result, to prevent accidental error-prone usage.
*/
private Expr getNonArrayValue(string name) {
result = this.getValue(name) and
not this.getAnnotationElement(name).getType() instanceof Array
}
/**
* If the value type of the annotation element with the specified `name` is an enum type,
* gets the enum constant used as value for that element. This includes default values in
* case no explicit value is specified.
*
* If the element value type is an enum type array, use `getAnEnumConstantArrayValue`.
*/
EnumConstant getEnumConstantValue(string name) {
result = this.getNonArrayValue(name).(FieldRead).getField()
}
/**
* If the value type of the annotation element with the specified `name` is `String`,
* gets the string value used for that element. This includes default values in case no
* explicit value is specified.
*
* If the element value type is a string array, use `getAStringArrayValue`.
*/
string getStringValue(string name) {
// Uses CompileTimeConstantExpr instead of StringLiteral because this can for example
// be a read from a final variable as well.
result = this.getNonArrayValue(name).(CompileTimeConstantExpr).getStringValue()
}
/**
* If the value type of the annotation element with the specified `name` is `int` or
* a smaller integral type or `char`, gets the int value used for that element.
* This includes default values in case no explicit value is specified.
*
* If the element value type is an `int` array or an array of a smaller integral
* type or `char`, use `getAnIntArrayValue`.
*/
int getIntValue(string name) {
// Uses CompileTimeConstantExpr instead of IntegerLiteral because this can for example
// be a read from a final variable as well.
result = this.getNonArrayValue(name).(CompileTimeConstantExpr).getIntValue() and
// Verify that type is integral; ignore floating point elements with IntegerLiteral as value
this.getAnnotationElement(name).getType().hasName(["byte", "short", "int", "char"])
}
/**
* If the value type of the annotation element with the specified `name` is `boolean`,
* gets the boolean value used for that element. This includes default values in case
* no explicit value is specified.
*/
boolean getBooleanValue(string name) {
// Uses CompileTimeConstantExpr instead of BooleanLiteral because this can for example
// be a read from a final variable as well.
result = this.getNonArrayValue(name).(CompileTimeConstantExpr).getBooleanValue()
}
/**
* If the value type of the annotation element with the specified `name` is `java.lang.Class`,
* gets the type referred to by that `Class`. This includes default values in case no explicit
* value is specified.
*
* If the element value type is a `Class` array, use `getATypeArrayValue`.
*/
Type getTypeValue(string name) {
result = this.getNonArrayValue(name).(TypeLiteral).getReferencedType()
}
/** Gets the element being annotated. */
Element getTarget() { result = this.getAnnotatedElement() }
@@ -60,16 +148,83 @@ class Annotation extends @annotation, Expr {
/**
* Gets a value of the annotation element with the specified `name`, which must be declared as an array
* type.
* type. This includes default values in case no explicit value is specified.
*
* If the annotation element is defined with an array initializer, then the returned value will
* be one of the elements of that array. Otherwise, the returned value will be the single
* expression defined for the value.
* If the annotation element is defined with an array initializer, then the result will be one of the
* elements of that array. Otherwise, the result will be the single expression used as value.
*/
Expr getAValue(string name) {
Expr getAnArrayValue(string name) { result = this.getArrayValue(name, _) }
/**
* DEPRECATED: Predicate has been renamed to `getAnArrayValue`
*/
deprecated Expr getAValue(string name) { result = this.getAnArrayValue(name) }
/**
* Gets a value of the annotation element with the specified `name`, which must be declared as an enum
* type array. This includes default values in case no explicit value is specified.
*
* If the annotation element is defined with an array initializer, then the result will be one of the
* elements of that array. Otherwise, the result will be the single expression used as value.
*/
EnumConstant getAnEnumConstantArrayValue(string name) {
result = this.getAnArrayValue(name).(FieldRead).getField()
}
/**
* Gets a value of the annotation element with the specified `name`, which must be declared as a string
* array. This includes default values in case no explicit value is specified.
*
* If the annotation element is defined with an array initializer, then the result will be one of the
* elements of that array. Otherwise, the result will be the single expression used as value.
*/
string getAStringArrayValue(string name) {
result = this.getAnArrayValue(name).(CompileTimeConstantExpr).getStringValue()
}
/**
* Gets a value of the annotation element with the specified `name`, which must be declared as an `int`
* array or an array of a smaller integral type or `char`. This includes default values in case no
* explicit value is specified.
*
* If the annotation element is defined with an array initializer, then the result will be one of the
* elements of that array. Otherwise, the result will be the single expression used as value.
*/
int getAnIntArrayValue(string name) {
result = this.getAnArrayValue(name).(CompileTimeConstantExpr).getIntValue() and
// Verify that type is integral; ignore floating point elements with IntegerLiteral as value
this.getAnnotationElement(name).getType().hasName(["byte[]", "short[]", "int[]", "char[]"])
}
/**
* Gets a value of the annotation element with the specified `name`, which must be declared as a `Class`
* array. This includes default values in case no explicit value is specified.
*
* If the annotation element is defined with an array initializer, then the result will be one of the
* elements of that array. Otherwise, the result will be the single expression used as value.
*/
Type getATypeArrayValue(string name) {
result = this.getAnArrayValue(name).(TypeLiteral).getReferencedType()
}
/**
* Gets the value at a given index of the annotation element with the specified `name`, which must be
* declared as an array type. This includes default values in case no explicit value is specified.
*
* If the annotation element is defined with an array initializer, then the result will be the element
* at the given index of that array, starting at 0. Otherwise, the result will be the single expression
* defined for the value and the `index` will be 0.
*/
Expr getArrayValue(string name, int index) {
this.getType().getAnnotationElement(name).getType() instanceof Array and
exists(Expr value | value = this.getValue(name) |
if value instanceof ArrayInit then result = value.(ArrayInit).getAnInit() else result = value
if value instanceof ArrayInit
then
// TODO: Currently reports incorrect index values in some cases, see https://github.com/github/codeql/issues/8645
result = value.(ArrayInit).getInit(index)
else (
index = 0 and result = value
)
)
}
@@ -99,19 +254,86 @@ private predicate sourceAnnotValue(Annotation a, Method m, Expr val) {
/** An abstract representation of language elements that can be annotated. */
class Annotatable extends Element {
/** Holds if this element has an annotation. */
predicate hasAnnotation() { exists(Annotation a | a.getAnnotatedElement() = this) }
/**
* Holds if this element has an annotation, including inherited annotations.
* The retention policy of the annotation type is not considered.
*/
predicate hasAnnotation() { exists(this.getAnAnnotation()) }
/** Holds if this element has the specified annotation. */
/**
* Holds if this element has a declared annotation, excluding inherited annotations.
* The retention policy of the annotation type is not considered.
*/
predicate hasDeclaredAnnotation() { exists(this.getADeclaredAnnotation()) }
/**
* Holds if this element has the specified annotation, including inherited
* annotations. The retention policy of the annotation type is not considered.
*/
predicate hasAnnotation(string package, string name) {
exists(AnnotationType at | at = this.getAnAnnotation().getType() |
at.nestedName() = name and at.getPackage().getName() = package
)
}
/** Gets an annotation that applies to this element. */
/**
* Gets an annotation that applies to this element, including inherited annotations.
* The results only include _direct_ annotations; _indirect_ annotations, that is
* repeated annotations in an (implicit) container annotation, are not included.
* The retention policy of the annotation type is not considered.
*/
cached
Annotation getAnAnnotation() { result.getAnnotatedElement() = this }
Annotation getAnAnnotation() {
// This predicate is overridden by Class to consider inherited annotations
result = this.getADeclaredAnnotation()
}
/**
* Gets an annotation that is declared on this element, excluding inherited annotations.
* The retention policy of the annotation type is not considered.
*/
Annotation getADeclaredAnnotation() { result.getAnnotatedElement() = this }
/** Gets an _indirect_ (= repeated) annotation. */
private Annotation getAnIndirectAnnotation() {
// 'indirect' as defined by https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/reflect/AnnotatedElement.html
exists(AnnotationType t, Annotation containerAnn |
t = result.getType() and
containerAnn = this.getADeclaredAnnotation() and
containerAnn.getType() = t.getContainingAnnotationType()
|
result = containerAnn.getAnArrayValue("value")
)
}
private Annotation getADeclaredAssociatedAnnotation(AnnotationType t) {
// Direct or indirect annotation
result.getType() = t and
result = [this.getADeclaredAnnotation(), this.getAnIndirectAnnotation()]
}
private Annotation getAnAssociatedAnnotation(AnnotationType t) {
// 'associated' as defined by https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/reflect/AnnotatedElement.html
if exists(this.getADeclaredAssociatedAnnotation(t))
then result = this.getADeclaredAssociatedAnnotation(t)
else (
// Only if neither a direct nor an indirect annotation is present look for an inherited one
t.isInherited() and
// @Inherited only works for classes; cast to Annotatable is necessary because predicate is private
result = this.(Class).getASupertype().(Class).(Annotatable).getAnAssociatedAnnotation(t)
)
}
/**
* Gets an annotation _associated_ with this element, that is:
* - An annotation directly present on this element, or
* - An annotation indirectly present on this element (in the form of a repeated annotation), or
* - If an annotation of a type is neither directly nor indirectly present
* the result is an associated inherited annotation (recursively)
*
* The retention policy of the annotation type is not considered.
*/
Annotation getAnAssociatedAnnotation() { result = this.getAnAssociatedAnnotation(_) }
/**
* Holds if this or any enclosing `Annotatable` has a `@SuppressWarnings("<category>")`
@@ -128,6 +350,11 @@ class Annotatable extends Element {
or
this.(NestedClass).getEnclosingType().suppressesWarningsAbout(category)
or
this.(LocalClassOrInterface)
.getLocalTypeDeclStmt()
.getEnclosingCallable()
.suppressesWarningsAbout(category)
or
this.(LocalVariableDecl).getCallable().suppressesWarningsAbout(category)
}
}
@@ -146,10 +373,79 @@ class AnnotationType extends Interface {
/** Holds if this annotation type is annotated with the meta-annotation `@Inherited`. */
predicate isInherited() {
exists(Annotation ann |
ann.getAnnotatedElement() = this and
ann.getType().hasQualifiedName("java.lang.annotation", "Inherited")
)
this.getADeclaredAnnotation().getType().hasQualifiedName("java.lang.annotation", "Inherited")
}
/** Holds if this annotation type is annotated with the meta-annotation `@Documented`. */
predicate isDocumented() {
this.getADeclaredAnnotation().getType().hasQualifiedName("java.lang.annotation", "Documented")
}
/**
* Gets the retention policy of this annotation type, that is, the name of one of the
* enum constants of `java.lang.annotation.RetentionPolicy`. If this annotation type
* has no `@Retention` annotation, the result is `CLASS`.
*/
string getRetentionPolicy() {
if this.getADeclaredAnnotation() instanceof RetentionAnnotation
then result = this.getADeclaredAnnotation().(RetentionAnnotation).getRetentionPolicy()
else
// If not explicitly specified retention is CLASS
result = "CLASS"
}
/**
* Holds if the element type is a possible target for this annotation type.
* The `elementType` is the name of one of the `java.lang.annotation.ElementType`
* enum constants.
*
* If this annotation type has no `@Target` annotation, it is considered to be applicable
* in all declaration contexts. This matches the behavior of the latest Java versions
* but differs from the behavior of older Java versions. This predicate must only be
* called with names of `ElementType` enum constants; for other values it might hold
* erroneously.
*/
bindingset[elementType]
predicate isATargetType(string elementType) {
/*
* Note: Cannot use a predicate with string as result because annotation type without
* explicit @Target can be applied in all declaration contexts, requiring to hardcode
* element types here; then the results could become outdated if this predicate is not
* updated for future JDK versions, or it could have irritating results, e.g. RECORD_COMPONENT
* for a database created for Java 8.
*
* Could in theory read java.lang.annotation.ElementType constants from database, but might
* be brittle in case ElementType is not present in the database for whatever reason.
*/
if this.getADeclaredAnnotation() instanceof TargetAnnotation
then elementType = this.getADeclaredAnnotation().(TargetAnnotation).getATargetElementType()
else
/*
* Behavior for missing @Target annotation changed between Java versions. In older Java
* versions it allowed usage in most (but not all) declaration contexts. Then for Java 14
* JDK-8231435 changed it to allow usage in all declaration and type contexts. In Java 17
* it was changed by JDK-8261610 to only allow usage in all declaration contexts, but not
* in type contexts anymore. However, during these changes javac did not always comply with
* the specification, see for example JDK-8254023.
*
* For simplicity pretend the latest behavior defined by the JLS applied in all versions;
* that means any declaration context is allowed, but type contexts (represented by TYPE_USE,
* see JLS 17 section 9.6.4.1) are not allowed.
*/
elementType != "TYPE_USE"
}
/** Holds if this annotation type is annotated with the meta-annotation `@Repeatable`. */
predicate isRepeatable() { this.getADeclaredAnnotation() instanceof RepeatableAnnotation }
/**
* If this annotation type is annotated with the meta-annotation `@Repeatable`,
* gets the annotation type which acts as _containing annotation type_.
*/
AnnotationType getContainingAnnotationType() {
result = this.getADeclaredAnnotation().(RepeatableAnnotation).getContainingType()
}
}

View File

@@ -71,7 +71,8 @@ predicate depends(RefType t, RefType dep) {
a.getAnnotatedElement().(Member).getDeclaringType() = t
|
usesType(a.getType(), dep) or
usesType(a.getAValue().getType(), dep)
usesType(a.getValue(_).getType(), dep) or
usesType(a.getAnArrayValue(_).getType(), dep)
)
or
// the type accessed in an `instanceof` expression in `t`.

View File

@@ -90,7 +90,7 @@ predicate numDepends(RefType t, RefType dep, int value) {
|
elem = a and usesType(a.getType(), dep)
or
elem = a.getAValue() and
elem = [a.getValue(_), a.getAnArrayValue(_)] and
elem.getFile().getExtension() = "java" and
usesType(elem.(Expr).getType(), dep)
)

View File

@@ -18,14 +18,16 @@ class OverrideAnnotation extends Annotation {
class SuppressWarningsAnnotation extends Annotation {
SuppressWarningsAnnotation() { this.getType().hasQualifiedName("java.lang", "SuppressWarnings") }
/** Gets the `StringLiteral` of a warning suppressed by this annotation. */
StringLiteral getASuppressedWarningLiteral() {
result = this.getAValue() or
result = this.getAValue().(ArrayInit).getAnInit()
}
/**
* DEPRECATED: This predicate restricts the results to `StringLiteral`; prefer `getASuppressedWarning()`
* to get the name of a suppressed warning.
*
* Gets the `StringLiteral` of a warning suppressed by this annotation.
*/
deprecated StringLiteral getASuppressedWarningLiteral() { result = this.getAnArrayValue("value") }
/** Gets the name of a warning suppressed by this annotation. */
string getASuppressedWarning() { result = this.getASuppressedWarningLiteral().getValue() }
string getASuppressedWarning() { result = this.getAStringArrayValue("value") }
}
/** A `@Target` annotation. */
@@ -33,18 +35,15 @@ class TargetAnnotation extends Annotation {
TargetAnnotation() { this.getType().hasQualifiedName("java.lang.annotation", "Target") }
/**
* DEPRECATED: Getting the field access expression is rarely useful. Use `getATargetElementType()`
* to get the name of the target element.
*
* Gets a target expression within this annotation.
*
* For example, the field access `ElementType.FIELD` is a target expression in
* `@Target({ElementType.FIELD, ElementType.METHOD})`.
*/
Expr getATargetExpression() {
not result instanceof ArrayInit and
(
result = this.getAValue() or
result = this.getAValue().(ArrayInit).getAnInit()
)
}
deprecated Expr getATargetExpression() { result = this.getAnArrayValue("value") }
/**
* Gets the name of a target element type.
@@ -52,14 +51,7 @@ class TargetAnnotation extends Annotation {
* For example, `METHOD` is the name of a target element type in
* `@Target({ElementType.FIELD, ElementType.METHOD})`.
*/
string getATargetElementType() {
exists(EnumConstant ec |
ec = this.getATargetExpression().(VarAccess).getVariable() and
ec.getDeclaringType().hasQualifiedName("java.lang.annotation", "ElementType")
|
result = ec.getName()
)
}
string getATargetElementType() { result = this.getAnEnumConstantArrayValue("value").getName() }
}
/** A `@Retention` annotation. */
@@ -67,12 +59,15 @@ class RetentionAnnotation extends Annotation {
RetentionAnnotation() { this.getType().hasQualifiedName("java.lang.annotation", "Retention") }
/**
* DEPRECATED: Getting the field access expression is rarely useful. Use `getRetentionPolicy()`
* to get the name of the retention policy.
*
* Gets the retention policy expression within this annotation.
*
* For example, the field access `RetentionPolicy.RUNTIME` is the
* retention policy expression in `@Retention(RetentionPolicy.RUNTIME)`.
*/
Expr getRetentionPolicyExpression() { result = this.getValue("value") }
deprecated Expr getRetentionPolicyExpression() { result = this.getValue("value") }
/**
* Gets the name of the retention policy of this annotation.
@@ -80,14 +75,18 @@ class RetentionAnnotation extends Annotation {
* For example, `RUNTIME` is the name of the retention policy
* in `@Retention(RetentionPolicy.RUNTIME)`.
*/
string getRetentionPolicy() {
exists(EnumConstant ec |
ec = this.getRetentionPolicyExpression().(VarAccess).getVariable() and
ec.getDeclaringType().hasQualifiedName("java.lang.annotation", "RetentionPolicy")
|
result = ec.getName()
)
}
string getRetentionPolicy() { result = this.getEnumConstantValue("value").getName() }
}
/** A `@Repeatable` annotation. */
class RepeatableAnnotation extends Annotation {
RepeatableAnnotation() { this.getType().hasQualifiedName("java.lang.annotation", "Repeatable") }
/**
* Gets the annotation type which acts as _containing type_, grouping multiple
* repeatable annotations together.
*/
AnnotationType getContainingType() { result = this.getTypeValue("value") }
}
/**
@@ -119,11 +118,7 @@ abstract class NonReflectiveAnnotation extends Annotation { }
library class StandardNonReflectiveAnnotation extends NonReflectiveAnnotation {
StandardNonReflectiveAnnotation() {
exists(AnnotationType anntp | anntp = this.getType() |
anntp.hasQualifiedName("java.lang", "Override") or
anntp.hasQualifiedName("java.lang", "Deprecated") or
anntp.hasQualifiedName("java.lang", "SuppressWarnings") or
anntp.hasQualifiedName("java.lang", "SafeVarargs")
)
this.getType()
.hasQualifiedName("java.lang", ["Override", "Deprecated", "SuppressWarnings", "SafeVarargs"])
}
}

View File

@@ -27,7 +27,7 @@ class MXBean extends ManagedBean {
class RegisteredManagedBeanImpl extends Class {
RegisteredManagedBeanImpl() {
this.getAnAncestor() instanceof ManagedBean and
exists(JMXRegistrationCall registerCall | registerCall.getObjectArgument().getType() = this)
exists(JmxRegistrationCall registerCall | registerCall.getObjectArgument().getType() = this)
}
/**
@@ -39,32 +39,35 @@ class RegisteredManagedBeanImpl extends Class {
/**
* A call that registers an object with the `MBeanServer`, directly or indirectly.
*/
class JMXRegistrationCall extends MethodAccess {
JMXRegistrationCall() { this.getCallee() instanceof JMXRegistrationMethod }
class JmxRegistrationCall extends MethodAccess {
JmxRegistrationCall() { this.getCallee() instanceof JmxRegistrationMethod }
/**
* Gets the argument that represents the object in the registration call.
*/
Expr getObjectArgument() {
result = this.getArgument(this.getCallee().(JMXRegistrationMethod).getObjectPosition())
result = this.getArgument(this.getCallee().(JmxRegistrationMethod).getObjectPosition())
}
}
/** DEPRECATED: Alias for JmxRegistrationCall */
deprecated class JMXRegistrationCall = JmxRegistrationCall;
/**
* A method used to register `MBean` and `MXBean` instances with the `MBeanServer`.
*
* This is either the `registerMBean` method on `MBeanServer`, or it is a wrapper around that
* registration method.
*/
class JMXRegistrationMethod extends Method {
JMXRegistrationMethod() {
class JmxRegistrationMethod extends Method {
JmxRegistrationMethod() {
// A direct registration with the `MBeanServer`.
this.getDeclaringType().hasQualifiedName("javax.management", "MBeanServer") and
this.getName() = "registerMBean"
or
// The `MBeanServer` is often wrapped by an application specific management class, so identify
// methods that wrap a call to another `JMXRegistrationMethod`.
exists(JMXRegistrationCall c |
// methods that wrap a call to another `JmxRegistrationMethod`.
exists(JmxRegistrationCall c |
// This must be a call to another JMX registration method, where the object argument is an access
// of one of the parameters of this method.
c.getObjectArgument().(VarAccess).getVariable() = this.getAParameter()
@@ -81,25 +84,37 @@ class JMXRegistrationMethod extends Method {
result = 0
or
// Identify the position in this method where the object parameter should be passed.
exists(JMXRegistrationCall c |
exists(JmxRegistrationCall c |
c.getObjectArgument().(VarAccess).getVariable() = this.getParameter(result)
)
}
}
/** DEPRECATED: Alias for JmxRegistrationMethod */
deprecated class JMXRegistrationMethod = JmxRegistrationMethod;
/** The class `javax.management.remote.JMXConnectorFactory`. */
class TypeJMXConnectorFactory extends Class {
TypeJMXConnectorFactory() {
class TypeJmxConnectorFactory extends Class {
TypeJmxConnectorFactory() {
this.hasQualifiedName("javax.management.remote", "JMXConnectorFactory")
}
}
/** DEPRECATED: Alias for TypeJmxConnectorFactory */
deprecated class TypeJMXConnectorFactory = TypeJmxConnectorFactory;
/** The class `javax.management.remote.JMXServiceURL`. */
class TypeJMXServiceURL extends Class {
TypeJMXServiceURL() { this.hasQualifiedName("javax.management.remote", "JMXServiceURL") }
class TypeJmxServiceUrl extends Class {
TypeJmxServiceUrl() { this.hasQualifiedName("javax.management.remote", "JMXServiceURL") }
}
/** DEPRECATED: Alias for TypeJmxServiceUrl */
deprecated class TypeJMXServiceURL = TypeJmxServiceUrl;
/** The class `javax.management.remote.rmi.RMIConnector`. */
class TypeRMIConnector extends Class {
TypeRMIConnector() { this.hasQualifiedName("javax.management.remote.rmi", "RMIConnector") }
class TypeRmiConnector extends Class {
TypeRmiConnector() { this.hasQualifiedName("javax.management.remote.rmi", "RMIConnector") }
}
/** DEPRECATED: Alias for TypeRmiConnector */
deprecated class TypeRMIConnector = TypeRmiConnector;

View File

@@ -20,8 +20,14 @@ class Member extends Element, Annotatable, Modifiable, @member {
/** Gets the type in which this member is declared. */
RefType getDeclaringType() { declaresMember(result, this) }
/** Gets the qualified name of this member. */
string getQualifiedName() { result = this.getDeclaringType().getName() + "." + this.getName() }
/**
* Gets the qualified name of this member.
* This is useful for debugging, but for normal use `hasQualifiedName`
* is recommended, as it is more efficient.
*/
string getQualifiedName() {
result = this.getDeclaringType().getQualifiedName() + "." + this.getName()
}
/**
* Holds if this member has the specified name and is declared in the

View File

@@ -7,7 +7,13 @@ import Element
/** A modifier such as `private`, `static` or `abstract`. */
class Modifier extends Element, @modifier {
/** Gets the element to which this modifier applies. */
Element getElement() { hasModifier(result, this) }
Element getElement() {
hasModifier(result, this) and
// Kotlin "internal" elements may also get "public" modifiers, so we want to filter those out
not exists(Modifier mod2 |
hasModifier(result, mod2) and modifiers(this, "public") and modifiers(mod2, "internal")
)
}
override string getAPrimaryQlClass() { result = "Modifier" }
}
@@ -20,7 +26,7 @@ abstract class Modifiable extends Element {
* For most purposes, the more specialized predicates `isAbstract`, `isPublic`, etc.
* should be used.
*
* Both this method and those specialized predicates take implicit modifiers into account.
* Those specialized predicates also take implicit modifiers into account.
* For instance, non-default instance methods in interfaces are implicitly
* abstract, so `isAbstract()` will hold for them even if `hasModifier("abstract")`
* does not.

View File

@@ -15,7 +15,7 @@ private class SpecialMethodAccess extends MethodAccess {
this.getQualifier().getType().(RefType).hasQualifiedName("java.lang", klass)
}
predicate throwsNFE() {
predicate throwsNfe() {
this.isParseMethod("Byte", "parseByte") or
this.isParseMethod("Short", "parseShort") or
this.isParseMethod("Integer", "parseInt") or
@@ -33,6 +33,9 @@ private class SpecialMethodAccess extends MethodAccess {
this.isValueOfMethod("Float") or
this.isValueOfMethod("Double")
}
/** DEPRECATED: Alias for throwsNfe */
deprecated predicate throwsNFE() { this.throwsNfe() }
}
/** A `ClassInstanceExpr` that constructs a number from its string representation. */
@@ -43,7 +46,7 @@ private class SpecialClassInstanceExpr extends ClassInstanceExpr {
this.getNumArgument() = 1
}
predicate throwsNFE() {
predicate throwsNfe() {
this.isStringConstructor("Byte") or
this.isStringConstructor("Short") or
this.isStringConstructor("Integer") or
@@ -51,6 +54,9 @@ private class SpecialClassInstanceExpr extends ClassInstanceExpr {
this.isStringConstructor("Float") or
this.isStringConstructor("Double")
}
/** DEPRECATED: Alias for throwsNfe */
deprecated predicate throwsNFE() { this.throwsNfe() }
}
/** The class `java.lang.NumberFormatException`. */
@@ -59,7 +65,7 @@ class NumberFormatException extends RefType {
}
/** Holds if `java.lang.NumberFormatException` is caught. */
predicate catchesNFE(TryStmt t) {
predicate catchesNfe(TryStmt t) {
exists(CatchClause cc, LocalVariableDeclExpr v |
t.getACatchClause() = cc and
cc.getVariable() = v and
@@ -67,7 +73,13 @@ predicate catchesNFE(TryStmt t) {
)
}
/** DEPRECATED: Alias for catchesNfe */
deprecated predicate catchesNFE = catchesNfe/1;
/** Holds if `java.lang.NumberFormatException` can be thrown. */
predicate throwsNFE(Expr e) {
e.(SpecialClassInstanceExpr).throwsNFE() or e.(SpecialMethodAccess).throwsNFE()
predicate throwsNfe(Expr e) {
e.(SpecialClassInstanceExpr).throwsNfe() or e.(SpecialMethodAccess).throwsNfe()
}
/** DEPRECATED: Alias for throwsNfe */
deprecated predicate throwsNFE = throwsNfe/1;

View File

@@ -120,7 +120,7 @@ private newtype TPrintAstNode =
shouldPrint(lvde, _) and lvde.getParent() instanceof SingleLocalVarDeclParent
} or
TAnnotationsNode(Annotatable ann) {
shouldPrint(ann, _) and ann.hasAnnotation() and not partOfAnnotation(ann)
shouldPrint(ann, _) and ann.hasDeclaredAnnotation() and not partOfAnnotation(ann)
} or
TParametersNode(Callable c) { shouldPrint(c, _) and not c.hasNoParameters() } or
TBaseTypesNode(ClassOrInterface ty) { shouldPrint(ty, _) } or

View File

@@ -161,15 +161,13 @@ class TestNGTestMethod extends Method {
exists(TestNGTestAnnotation testAnnotation |
testAnnotation = this.getAnAnnotation() and
// The data provider must have the same name as the referenced data provider
result.getDataProviderName() =
testAnnotation.getValue("dataProvider").(StringLiteral).getValue()
result.getDataProviderName() = testAnnotation.getStringValue("dataProvider")
|
// Either the data provider should be on the current class, or a supertype
this.getDeclaringType().getAnAncestor() = result.getDeclaringType()
or
// Or the data provider class should be declared
result.getDeclaringType() =
testAnnotation.getValue("dataProviderClass").(TypeLiteral).getReferencedType()
result.getDeclaringType() = testAnnotation.getTypeValue("dataProviderClass")
)
}
}
@@ -227,9 +225,7 @@ class TestNGListenersAnnotation extends TestNGAnnotation {
/**
* Gets a listener defined in this annotation.
*/
TestNGListenerImpl getAListener() {
result = this.getAValue("value").(TypeLiteral).getReferencedType()
}
TestNGListenerImpl getAListener() { result = this.getATypeArrayValue("value") }
}
/**

View File

@@ -12,6 +12,7 @@
* `namespace; type; subtypes; name; signature; ext; input; output; kind; provenance`
* - Negative Summaries:
* `namespace; type; name; signature; provenance`
* A negative summary is used to indicate that there is no flow via a callable.
*
* The interpretation of a row is similar to API-graphs with a left-to-right
* reading.
@@ -116,10 +117,12 @@ private module Frameworks {
private import semmle.code.java.frameworks.Retrofit
private import semmle.code.java.frameworks.Stream
private import semmle.code.java.frameworks.Strings
private import semmle.code.java.frameworks.Thymeleaf
private import semmle.code.java.frameworks.ratpack.Ratpack
private import semmle.code.java.frameworks.ratpack.RatpackExec
private import semmle.code.java.frameworks.spring.SpringCache
private import semmle.code.java.frameworks.spring.SpringContext
private import semmle.code.java.frameworks.spring.SpringData
private import semmle.code.java.frameworks.spring.SpringHttp
private import semmle.code.java.frameworks.spring.SpringUtil
private import semmle.code.java.frameworks.spring.SpringUi
@@ -139,6 +142,7 @@ private module Frameworks {
private import semmle.code.java.security.LdapInjection
private import semmle.code.java.security.MvelInjection
private import semmle.code.java.security.OgnlInjection
private import semmle.code.java.security.TemplateInjection
private import semmle.code.java.security.XPath
private import semmle.code.java.security.XsltInjection
private import semmle.code.java.frameworks.Jdbc
@@ -151,7 +155,7 @@ private module Frameworks {
private import semmle.code.java.frameworks.JMS
private import semmle.code.java.frameworks.RabbitMQ
private import semmle.code.java.regex.RegexFlowModels
private import semmle.code.java.frameworks.KotlinStdLib
private import semmle.code.java.frameworks.kotlin.StdLib
}
/**
@@ -623,7 +627,7 @@ module CsvValidation {
"open-url", "jndi-injection", "ldap", "sql", "jdbc-url", "logging", "mvel", "xpath",
"groovy", "xss", "ognl-injection", "intent-start", "pending-intent-sent",
"url-open-stream", "url-redirect", "create-file", "write-file", "set-hostname-verifier",
"header-splitting", "information-leak", "xslt", "jexl", "bean-validation"
"header-splitting", "information-leak", "xslt", "jexl", "bean-validation", "ssti"
] and
not kind.matches("regex-use%") and
not kind.matches("qltest%") and

View File

@@ -88,7 +88,7 @@ private class ReverseDnsSource extends RemoteFlowSource {
ReverseDnsSource() {
// Try not to trigger on `localhost`.
exists(MethodAccess m | m = this.asExpr() |
m.getMethod() instanceof ReverseDNSMethod and
m.getMethod() instanceof ReverseDnsMethod and
not exists(MethodAccess l |
(variableStep(l, m.getQualifier()) or l = m.getQualifier()) and
l.getMethod().getName() = "getLocalHost"
@@ -221,8 +221,8 @@ class TypeInetAddr extends RefType {
}
/** A reverse DNS method. */
class ReverseDNSMethod extends Method {
ReverseDNSMethod() {
class ReverseDnsMethod extends Method {
ReverseDnsMethod() {
this.getDeclaringType() instanceof TypeInetAddr and
(
this.getName() = "getHostName" or
@@ -231,6 +231,9 @@ class ReverseDNSMethod extends Method {
}
}
/** DEPRECATED: Alias for ReverseDnsMethod */
deprecated class ReverseDNSMethod = ReverseDnsMethod;
/** Android `Intent` that may have come from a hostile application. */
class AndroidIntentInput extends DataFlow::Node {
Type receiverType;

View File

@@ -53,6 +53,16 @@ private class TypeFlowNode extends TTypeFlowNode {
}
}
private int getNodeKind(TypeFlowNode n) {
result = 1 and n instanceof TField
or
result = 2 and n instanceof TSsa
or
result = 3 and n instanceof TExpr
or
result = 4 and n instanceof TMethod
}
/** Gets `t` if it is a `RefType` or the boxed type if `t` is a primitive type. */
private RefType boxIfNeeded(Type t) {
t.(PrimitiveType).getBoxedType() = result or
@@ -146,46 +156,199 @@ private predicate joinStep(TypeFlowNode n1, TypeFlowNode n2) {
joinStep0(n1, n2) and not isNull(n1)
}
private predicate joinStepRank1(int r, TypeFlowNode n1, TypeFlowNode n2) {
n1 =
rank[r](TypeFlowNode n |
joinStep(n, n2)
|
n order by n.getLocation().getStartLine(), n.getLocation().getStartColumn()
private predicate anyStep(TypeFlowNode n1, TypeFlowNode n2) { joinStep(n1, n2) or step(n1, n2) }
private import SccReduction
/**
* SCC reduction.
*
* This ought to be as easy as `equivalenceRelation(sccEdge/2)(n, scc)`, but
* this HOP is not currently supported for newtypes.
*
* A straightforward implementation would be:
* ```ql
* predicate sccRepr(TypeFlowNode n, TypeFlowNode scc) {
* scc =
* max(TypeFlowNode n2 |
* sccEdge+(n, n2)
* |
* n2
* order by
* n2.getLocation().getStartLine(), n2.getLocation().getStartColumn(), getNodeKind(n2)
* )
* }
*
* ```
* but this is quadratic in the size of the SCCs.
*
* Instead we find local maxima by following SCC edges and determine the SCC
* representatives from those.
* (This is still worst-case quadratic in the size of the SCCs, but generally
* performs better.)
*/
private module SccReduction {
private predicate sccEdge(TypeFlowNode n1, TypeFlowNode n2) {
anyStep(n1, n2) and anyStep+(n2, n1)
}
private predicate sccEdgeWithMax(TypeFlowNode n1, TypeFlowNode n2, TypeFlowNode m) {
sccEdge(n1, n2) and
m =
max(TypeFlowNode n |
n = [n1, n2]
|
n order by n.getLocation().getStartLine(), n.getLocation().getStartColumn(), getNodeKind(n)
)
}
private predicate hasLargerNeighbor(TypeFlowNode n) {
exists(TypeFlowNode n2 |
sccEdgeWithMax(n, n2, n2) and
not sccEdgeWithMax(n, n2, n)
or
sccEdgeWithMax(n2, n, n2) and
not sccEdgeWithMax(n2, n, n)
)
}
private predicate localMax(TypeFlowNode m) {
sccEdgeWithMax(_, _, m) and
not hasLargerNeighbor(m)
}
private predicate sccReprFromLocalMax(TypeFlowNode scc) {
exists(TypeFlowNode m |
localMax(m) and
scc =
max(TypeFlowNode n2 |
sccEdge+(m, n2) and localMax(n2)
|
n2
order by
n2.getLocation().getStartLine(), n2.getLocation().getStartColumn(), getNodeKind(n2)
)
)
}
/** Holds if `n` is part of an SCC of size 2 or more represented by `scc`. */
predicate sccRepr(TypeFlowNode n, TypeFlowNode scc) {
sccEdge+(n, scc) and sccReprFromLocalMax(scc)
}
predicate sccJoinStep(TypeFlowNode n, TypeFlowNode scc) {
exists(TypeFlowNode mid |
joinStep(n, mid) and
sccRepr(mid, scc) and
not sccRepr(n, scc)
)
}
}
private predicate joinStepRank2(int r2, int r1, TypeFlowNode n) {
r1 = rank[r2](int r | joinStepRank1(r, _, n) | r)
private signature predicate edgeSig(TypeFlowNode n1, TypeFlowNode n2);
private signature module RankedEdge {
predicate edgeRank(int r, TypeFlowNode n1, TypeFlowNode n2);
int lastRank(TypeFlowNode n);
}
private predicate joinStepRank(int r, TypeFlowNode n1, TypeFlowNode n2) {
exists(int r1 |
joinStepRank1(r1, n1, n2) and
joinStepRank2(r, r1, n2)
)
private module RankEdge<edgeSig/2 edge> implements RankedEdge {
/**
* Holds if `r` is a ranking of the incoming edges `(n1,n2)` to `n2`. The used
* ordering is not necessarily total, so the ranking may have gaps.
*/
private predicate edgeRank1(int r, TypeFlowNode n1, TypeFlowNode n2) {
n1 =
rank[r](TypeFlowNode n |
edge(n, n2)
|
n order by n.getLocation().getStartLine(), n.getLocation().getStartColumn()
)
}
/**
* Holds if `r2` is a ranking of the ranks from `edgeRank1`. This removes the
* gaps from the ranking.
*/
private predicate edgeRank2(int r2, int r1, TypeFlowNode n) {
r1 = rank[r2](int r | edgeRank1(r, _, n) | r)
}
/** Holds if `r` is a ranking of the incoming edges `(n1,n2)` to `n2`. */
predicate edgeRank(int r, TypeFlowNode n1, TypeFlowNode n2) {
exists(int r1 |
edgeRank1(r1, n1, n2) and
edgeRank2(r, r1, n2)
)
}
int lastRank(TypeFlowNode n) { result = max(int r | edgeRank(r, _, n)) }
}
private int lastRank(TypeFlowNode n) { result = max(int r | joinStepRank(r, _, n)) }
private signature module TypePropagation {
class Typ;
predicate candType(TypeFlowNode n, Typ t);
bindingset[t]
predicate supportsType(TypeFlowNode n, Typ t);
}
/** Implements recursion through `forall` by way of edge ranking. */
private module ForAll<RankedEdge Edge, TypePropagation T> {
/**
* Holds if `t` is a bound that holds on one of the incoming edges to `n` and
* thus is a candidate bound for `n`.
*/
pragma[nomagic]
private predicate candJoinType(TypeFlowNode n, T::Typ t) {
exists(TypeFlowNode mid |
T::candType(mid, t) and
Edge::edgeRank(_, mid, n)
)
}
/**
* Holds if `t` is a candidate bound for `n` that is also valid for data coming
* through the edges into `n` ranked from `1` to `r`.
*/
private predicate flowJoin(int r, TypeFlowNode n, T::Typ t) {
(
r = 1 and candJoinType(n, t)
or
flowJoin(r - 1, n, t) and Edge::edgeRank(r, _, n)
) and
forall(TypeFlowNode mid | Edge::edgeRank(r, mid, n) | T::supportsType(mid, t))
}
/**
* Holds if `t` is a candidate bound for `n` that is also valid for data
* coming through all the incoming edges, and therefore is a valid bound for
* `n`.
*/
predicate flowJoin(TypeFlowNode n, T::Typ t) { flowJoin(Edge::lastRank(n), n, t) }
}
module RankedJoinStep = RankEdge<joinStep/2>;
module RankedSccJoinStep = RankEdge<sccJoinStep/2>;
private predicate exactTypeBase(TypeFlowNode n, RefType t) {
exists(ClassInstanceExpr e |
n.asExpr() = e and
e.getType() = t and
not e instanceof FunctionalExpr and
exists(RefType sub | sub.getASourceSupertype() = t.getSourceDeclaration())
exists(SrcRefType sub | sub.getASourceSupertype() = t.getSourceDeclaration())
)
}
private predicate exactTypeRank(int r, TypeFlowNode n, RefType t) {
forall(TypeFlowNode mid | joinStepRank(r, mid, n) | exactType(mid, t)) and
joinStepRank(r, _, n)
}
private module ExactTypePropagation implements TypePropagation {
class Typ = RefType;
private predicate exactTypeJoin(int r, TypeFlowNode n, RefType t) {
exactTypeRank(1, n, t) and r = 1
or
exactTypeJoin(r - 1, n, t) and exactTypeRank(r, n, t)
predicate candType = exactType/2;
predicate supportsType = exactType/2;
}
/**
@@ -199,43 +362,60 @@ private predicate exactType(TypeFlowNode n, RefType t) {
or
// The following is an optimized version of
// `forex(TypeFlowNode mid | joinStep(mid, n) | exactType(mid, t))`
exactTypeJoin(lastRank(n), n, t)
ForAll<RankedJoinStep, ExactTypePropagation>::flowJoin(n, t)
or
exists(TypeFlowNode scc |
sccRepr(n, scc) and
// Optimized version of
// `forex(TypeFlowNode mid | sccJoinStep(mid, scc) | exactType(mid, t))`
ForAll<RankedSccJoinStep, ExactTypePropagation>::flowJoin(scc, t)
)
}
/**
* Holds if `n` occurs in a position where type information might be discarded;
* `t` is the potentially boxed type of `n`, `t1` is the erasure of `t`, and
* `t2` is the erased type of the implicit or explicit cast.
* `t1` is the type of `n`, `t1e` is the erasure of `t1`, `t2` is the type of
* the implicit or explicit cast, and `t2e` is the erasure of `t2`.
*/
pragma[noinline]
private predicate upcastCand(TypeFlowNode n, RefType t, RefType t1, RefType t2) {
t = boxIfNeeded(n.getType()) and
t.getErasure() = t1 and
(
exists(Variable v | v.getAnAssignedValue() = n.asExpr() and t2 = v.getType().getErasure())
or
exists(CastingExpr c | c.getExpr() = n.asExpr() and t2 = c.getType().getErasure())
or
exists(ReturnStmt ret |
ret.getResult() = n.asExpr() and t2 = ret.getEnclosingCallable().getReturnType().getErasure()
)
or
exists(MethodAccess ma | viableImpl_v1(ma) = n.asMethod() and t2 = ma.getType())
or
exists(Parameter p | privateParamArg(p, n.asExpr()) and t2 = p.getType().getErasure())
or
exists(ChooseExpr cond |
cond.getAResultExpr() = n.asExpr() and
t2 = cond.getType().getErasure()
)
pragma[nomagic]
private predicate upcastCand(TypeFlowNode n, RefType t1, RefType t1e, RefType t2, RefType t2e) {
exists(TypeFlowNode next | step(n, next) or joinStep(n, next) |
n.getType() = t1 and
next.getType() = t2 and
t1.getErasure() = t1e and
t2.getErasure() = t2e and
t1 != t2
)
}
private predicate unconstrained(BoundedType t) {
t.(Wildcard).isUnconstrained()
or
t.getUpperBoundType() instanceof TypeObject and
not t.(Wildcard).hasLowerBound()
or
unconstrained(t.getUpperBoundType())
or
unconstrained(t.(Wildcard).getLowerBoundType())
}
/** Holds if `t` is a raw type or parameterised type with unrestricted type arguments. */
private predicate unbound(RefType t) {
t instanceof RawType
or
exists(ParameterizedType pt | pt = t |
forex(RefType arg | arg = pt.getATypeArgument() | unconstrained(arg))
)
}
/** Holds if `n` occurs in a position where type information is discarded. */
private predicate upcast(TypeFlowNode n, RefType t) {
exists(RefType t1, RefType t2 |
upcastCand(n, t, t1, t2) and
t1.getASourceSupertype+() = t2
private predicate upcast(TypeFlowNode n, RefType t1) {
exists(RefType t1e, RefType t2, RefType t2e | upcastCand(n, t1, t1e, t2, t2e) |
t1e.getASourceSupertype+() = t2e
or
t1e = t2e and
unbound(t2) and
not unbound(t1)
)
}
@@ -322,9 +502,10 @@ predicate arrayInstanceOfGuarded(ArrayAccess aa, RefType t) {
/**
* Holds if `n` has type `t` and this information is discarded, such that `t`
* might be a better type bound for nodes where `n` flows to.
* might be a better type bound for nodes where `n` flows to. This might include
* multiple bounds for a single node.
*/
private predicate typeFlowBase(TypeFlowNode n, RefType t) {
private predicate typeFlowBaseCand(TypeFlowNode n, RefType t) {
exists(RefType srctype |
upcast(n, srctype) or
upcastEnhancedForStmt(n.asSsa(), srctype) or
@@ -340,29 +521,36 @@ private predicate typeFlowBase(TypeFlowNode n, RefType t) {
}
/**
* Holds if `t` is a bound that holds on one of the incoming edges to `n` and
* thus is a candidate bound for `n`.
* Holds if `n` has type `t` and this information is discarded, such that `t`
* might be a better type bound for nodes where `n` flows to. This only includes
* the best such bound for each node.
*/
pragma[noinline]
private predicate typeFlowJoinCand(TypeFlowNode n, RefType t) {
exists(TypeFlowNode mid | joinStep(mid, n) | typeFlow(mid, t))
private predicate typeFlowBase(TypeFlowNode n, RefType t) {
exists(RefType te |
typeFlowBaseCand(n, t) and
te = t.getErasure() and
not exists(RefType better |
typeFlowBaseCand(n, better) and
better != t and
not t.getASupertype+() = better
|
better.getASupertype+() = t or
better.getErasure().(RefType).getASourceSupertype+() = te
)
)
}
/**
* Holds if `t` is a candidate bound for `n` that is also valid for data coming
* through the edges into `n` ranked from `1` to `r`.
*/
private predicate typeFlowJoin(int r, TypeFlowNode n, RefType t) {
(
r = 1 and typeFlowJoinCand(n, t)
or
typeFlowJoin(r - 1, n, t) and joinStepRank(r, _, n)
) and
forall(TypeFlowNode mid | joinStepRank(r, mid, n) |
private module TypeFlowPropagation implements TypePropagation {
class Typ = RefType;
predicate candType = typeFlow/2;
bindingset[t]
predicate supportsType(TypeFlowNode mid, RefType t) {
exists(RefType midtyp | exactType(mid, midtyp) or typeFlow(mid, midtyp) |
pragma[only_bind_out](midtyp).getAnAncestor() = t
)
)
}
}
/**
@@ -374,7 +562,12 @@ private predicate typeFlow(TypeFlowNode n, RefType t) {
or
exists(TypeFlowNode mid | typeFlow(mid, t) and step(mid, n))
or
typeFlowJoin(lastRank(n), n, t)
ForAll<RankedJoinStep, TypeFlowPropagation>::flowJoin(n, t)
or
exists(TypeFlowNode scc |
sccRepr(n, scc) and
ForAll<RankedSccJoinStep, TypeFlowPropagation>::flowJoin(scc, t)
)
}
pragma[nomagic]
@@ -429,6 +622,175 @@ private predicate bestTypeFlow(TypeFlowNode n, RefType t) {
not irrelevantBound(n, t)
}
private predicate bestTypeFlow(TypeFlowNode n, RefType t, boolean exact) {
exactType(n, t) and exact = true
or
not exactType(n, _) and bestTypeFlow(n, t) and exact = false
}
private predicate bestTypeFlowOrTypeFlowBase(TypeFlowNode n, RefType t, boolean exact) {
bestTypeFlow(n, t, exact)
or
typeFlowBase(n, t) and
exact = false and
not bestTypeFlow(n, _, _)
}
/**
* Holds if `n` has type `t` and this information is not propagated as a
* universal bound to a subsequent node, such that `t` might form the basis for
* a union type bound for that node.
*/
private predicate unionTypeFlowBaseCand(TypeFlowNode n, RefType t, boolean exact) {
exists(TypeFlowNode next |
joinStep(n, next) and
bestTypeFlowOrTypeFlowBase(n, t, exact) and
not bestTypeFlowOrTypeFlowBase(next, t, exact) and
not exactType(next, _)
)
}
/**
* Holds if `ioe` checks `v`, its true-successor is `bb`, and `bb` has multiple
* predecessors.
*/
private predicate instanceofDisjunct(InstanceOfExpr ioe, BasicBlock bb, BaseSsaVariable v) {
ioe.getExpr() = v.getAUse() and
strictcount(bb.getABBPredecessor()) > 1 and
exists(ConditionBlock cb | cb.getCondition() = ioe and cb.getTestSuccessor(true) = bb)
}
/** Holds if `bb` is disjunctively guarded by multiple `instanceof` tests on `v`. */
private predicate instanceofDisjunction(BasicBlock bb, BaseSsaVariable v) {
strictcount(InstanceOfExpr ioe | instanceofDisjunct(ioe, bb, v)) =
strictcount(bb.getABBPredecessor())
}
/**
* Holds if `n` is a value that is guarded by a disjunction of
* `instanceof t_i` where `t` is one of those `t_i`.
*/
private predicate instanceofDisjunctionGuarded(TypeFlowNode n, RefType t) {
exists(BasicBlock bb, InstanceOfExpr ioe, BaseSsaVariable v, VarAccess va |
instanceofDisjunction(bb, v) and
bb.bbDominates(va.getBasicBlock()) and
va = v.getAUse() and
instanceofDisjunct(ioe, bb, v) and
t = ioe.getCheckedType() and
n.asExpr() = va
)
}
private module HasUnionTypePropagation implements TypePropagation {
class Typ = Unit;
predicate candType(TypeFlowNode mid, Unit unit) {
exists(unit) and
(unionTypeFlowBaseCand(mid, _, _) or hasUnionTypeFlow(mid))
}
predicate supportsType = candType/2;
}
/**
* Holds if all incoming type flow can be traced back to a
* `unionTypeFlowBaseCand`, such that we can compute a union type bound for `n`.
* Disregards nodes for which we have an exact bound.
*/
private predicate hasUnionTypeFlow(TypeFlowNode n) {
not exactType(n, _) and
(
// Optimized version of
// `forex(TypeFlowNode mid | joinStep(mid, n) | unionTypeFlowBaseCand(mid, _, _) or hasUnionTypeFlow(mid))`
ForAll<RankedJoinStep, HasUnionTypePropagation>::flowJoin(n, _)
or
exists(TypeFlowNode scc |
sccRepr(n, scc) and
// Optimized version of
// `forex(TypeFlowNode mid | sccJoinStep(mid, scc) | unionTypeFlowBaseCand(mid, _, _) or hasUnionTypeFlow(mid))`
ForAll<RankedSccJoinStep, HasUnionTypePropagation>::flowJoin(scc, _)
)
or
exists(TypeFlowNode mid | step(mid, n) and hasUnionTypeFlow(mid))
or
instanceofDisjunctionGuarded(n, _)
)
}
pragma[nomagic]
private RefType getTypeBound(TypeFlowNode n) {
bestTypeFlow(n, result)
or
not bestTypeFlow(n, _) and result = n.getType()
}
pragma[nomagic]
private predicate unionTypeFlow0(TypeFlowNode n, RefType t, boolean exact) {
hasUnionTypeFlow(n) and
(
exists(TypeFlowNode mid | anyStep(mid, n) |
unionTypeFlowBaseCand(mid, t, exact) or unionTypeFlow(mid, t, exact)
)
or
instanceofDisjunctionGuarded(n, t) and exact = false
)
}
/** Holds if we have a union type bound for `n` and `t` is one of its parts. */
private predicate unionTypeFlow(TypeFlowNode n, RefType t, boolean exact) {
unionTypeFlow0(n, t, exact) and
// filter impossible union parts:
if exact = true
then t.getErasure().(RefType).getASourceSupertype*() = getTypeBound(n).getErasure()
else haveIntersection(getTypeBound(n), t)
}
/**
* Holds if the inferred union type bound for `n` contains the best universal
* bound and thus is irrelevant.
*/
private predicate irrelevantUnionType(TypeFlowNode n) {
exists(RefType t, RefType nt, RefType te, RefType nte |
unionTypeFlow(n, t, false) and
nt = getTypeBound(n) and
te = t.getErasure() and
nte = nt.getErasure()
|
nt.getASupertype*() = t
or
nte.getASourceSupertype+() = te
or
nte = te and unbound(t)
)
}
/**
* Holds if `t` is an irrelevant part of the union type bound for `n` due to
* being contained in another part of the union type bound.
*/
private predicate irrelevantUnionTypePart(TypeFlowNode n, RefType t, boolean exact) {
unionTypeFlow(n, t, exact) and
not irrelevantUnionType(n) and
exists(RefType weaker |
unionTypeFlow(n, weaker, false) and
t.getASupertype*() = weaker
|
exact = true or not weaker.getASupertype*() = t
)
}
/**
* Holds if the runtime type of `n` is bounded by a union type and if this
* bound is likely to be better than the static type of `n`. The union type is
* made up of the types `t` related to `n` by this predicate, and the flag
* `exact` indicates whether `t` is an exact bound or merely an upper bound.
*/
private predicate bestUnionType(TypeFlowNode n, RefType t, boolean exact) {
unionTypeFlow(n, t, exact) and
not irrelevantUnionType(n) and
not irrelevantUnionTypePart(n, t, exact)
}
cached
private module TypeFlowBounds {
/**
@@ -440,11 +802,7 @@ private module TypeFlowBounds {
predicate fieldTypeFlow(Field f, RefType t, boolean exact) {
exists(TypeFlowNode n |
n.asField() = f and
(
exactType(n, t) and exact = true
or
not exactType(n, _) and bestTypeFlow(n, t) and exact = false
)
bestTypeFlow(n, t, exact)
)
}
@@ -457,11 +815,21 @@ private module TypeFlowBounds {
predicate exprTypeFlow(Expr e, RefType t, boolean exact) {
exists(TypeFlowNode n |
n.asExpr() = e and
(
exactType(n, t) and exact = true
or
not exactType(n, _) and bestTypeFlow(n, t) and exact = false
)
bestTypeFlow(n, t, exact)
)
}
/**
* Holds if the runtime type of `e` is bounded by a union type and if this
* bound is likely to be better than the static type of `e`. The union type is
* made up of the types `t` related to `e` by this predicate, and the flag
* `exact` indicates whether `t` is an exact bound or merely an upper bound.
*/
cached
predicate exprUnionTypeFlow(Expr e, RefType t, boolean exact) {
exists(TypeFlowNode n |
n.asExpr() = e and
bestUnionType(n, t, exact)
)
}
}

View File

@@ -4,11 +4,31 @@ private import DataFlowUtil
private import semmle.code.java.dataflow.InstanceAccess
private import semmle.code.java.dataflow.FlowSummary
private import semmle.code.java.dispatch.VirtualDispatch as VirtualDispatch
private import semmle.code.java.dataflow.TypeFlow
private import semmle.code.java.dispatch.internal.Unification
private module DispatchImpl {
private predicate hasHighConfidenceTarget(Call c) {
exists(SummarizedCallable sc |
sc = c.getCallee().getSourceDeclaration() and not sc.isAutoGenerated()
)
or
exists(Callable srcTgt |
srcTgt = VirtualDispatch::viableCallable(c) and
not VirtualDispatch::lowConfidenceDispatchTarget(c, srcTgt)
)
}
private Callable sourceDispatch(Call c) {
result = VirtualDispatch::viableCallable(c) and
if VirtualDispatch::lowConfidenceDispatchTarget(c, result)
then not hasHighConfidenceTarget(c)
else any()
}
/** Gets a viable implementation of the target of the given `Call`. */
DataFlowCallable viableCallable(DataFlowCall c) {
result.asCallable() = VirtualDispatch::viableCallable(c.asCall())
result.asCallable() = sourceDispatch(c.asCall())
or
result.asSummarizedCallable() = c.asCall().getCallee().getSourceDeclaration()
}
@@ -20,7 +40,7 @@ private module DispatchImpl {
*/
private predicate mayBenefitFromCallContext(MethodAccess ma, Callable c, int i) {
exists(Parameter p |
2 <= strictcount(VirtualDispatch::viableImpl(ma)) and
2 <= strictcount(sourceDispatch(ma)) and
ma.getQualifier().(VarAccess).getVariable() = p and
p.getPosition() = i and
c.getAParameter() = p and
@@ -29,7 +49,7 @@ private module DispatchImpl {
)
or
exists(OwnInstanceAccess ia |
2 <= strictcount(VirtualDispatch::viableImpl(ma)) and
2 <= strictcount(sourceDispatch(ma)) and
(ia.isExplicit(ma.getQualifier()) or ia.isImplicitMethodQualifier(ma)) and
i = -1 and
c = ma.getEnclosingCallable()
@@ -45,7 +65,7 @@ private module DispatchImpl {
private predicate relevantContext(Call ctx, int i) {
exists(Callable c |
mayBenefitFromCallContext(_, c, i) and
c = VirtualDispatch::viableCallable(ctx)
c = sourceDispatch(ctx)
)
}
@@ -62,15 +82,21 @@ private module DispatchImpl {
private predicate contextArgHasType(Call ctx, int i, RefType t, boolean exact) {
relevantContext(ctx, i) and
exists(RefType srctype |
exists(Expr arg, Expr src |
exists(Expr arg |
i = -1 and
ctx.getQualifier() = arg
or
ctx.getArgument(i) = arg
|
src = VirtualDispatch::variableTrack(arg) and
srctype = getPreciseType(src) and
if src instanceof ClassInstanceExpr then exact = true else exact = false
exprTypeFlow(arg, srctype, exact)
or
not exprTypeFlow(arg, _, _) and
exprUnionTypeFlow(arg, srctype, exact)
or
not exprTypeFlow(arg, _, _) and
not exprUnionTypeFlow(arg, _, _) and
srctype = getPreciseType(arg) and
if arg instanceof ClassInstanceExpr then exact = true else exact = false
)
or
exists(Node arg |
@@ -115,74 +141,20 @@ private module DispatchImpl {
exact = false and
exists(RefType t2 |
result.asCallable() = VirtualDispatch::viableMethodImpl(def, t.getSourceDeclaration(), t2) and
not failsUnification(t, t2)
not Unification::failsUnification(t, t2)
)
or
result.asSummarizedCallable() = def
)
}
pragma[noinline]
private predicate unificationTargetLeft(ParameterizedType t1, GenericType g) {
contextArgHasType(_, _, t1, _) and t1.getGenericType() = g
private predicate unificationTargetLeft(ParameterizedType t1) { contextArgHasType(_, _, t1, _) }
private predicate unificationTargetRight(ParameterizedType t2) {
exists(VirtualDispatch::viableMethodImpl(_, _, t2))
}
pragma[noinline]
private predicate unificationTargetRight(ParameterizedType t2, GenericType g) {
exists(VirtualDispatch::viableMethodImpl(_, _, t2)) and t2.getGenericType() = g
}
private predicate unificationTargets(Type t1, Type t2) {
exists(GenericType g | unificationTargetLeft(t1, g) and unificationTargetRight(t2, g))
or
exists(Array a1, Array a2 |
unificationTargets(a1, a2) and
t1 = a1.getComponentType() and
t2 = a2.getComponentType()
)
or
exists(ParameterizedType pt1, ParameterizedType pt2, int pos |
unificationTargets(pt1, pt2) and
not pt1.getSourceDeclaration() != pt2.getSourceDeclaration() and
t1 = pt1.getTypeArgument(pos) and
t2 = pt2.getTypeArgument(pos)
)
}
pragma[noinline]
private predicate typeArgsOfUnificationTargets(
ParameterizedType t1, ParameterizedType t2, int pos, RefType arg1, RefType arg2
) {
unificationTargets(t1, t2) and
arg1 = t1.getTypeArgument(pos) and
arg2 = t2.getTypeArgument(pos)
}
private predicate failsUnification(Type t1, Type t2) {
unificationTargets(t1, t2) and
(
exists(RefType arg1, RefType arg2 |
typeArgsOfUnificationTargets(t1, t2, _, arg1, arg2) and
failsUnification(arg1, arg2)
)
or
failsUnification(t1.(Array).getComponentType(), t2.(Array).getComponentType())
or
not (
t1 instanceof Array and t2 instanceof Array
or
t1.(PrimitiveType) = t2.(PrimitiveType)
or
t1.(Class).getSourceDeclaration() = t2.(Class).getSourceDeclaration()
or
t1.(Interface).getSourceDeclaration() = t2.(Interface).getSourceDeclaration()
or
t1 instanceof BoundedType and t2 instanceof RefType
or
t1 instanceof RefType and t2 instanceof BoundedType
)
)
}
private module Unification = MkUnification<unificationTargetLeft/1, unificationTargetRight/1>;
private int parameterPosition() { result in [-1, any(Parameter p).getPosition()] }

View File

@@ -226,15 +226,6 @@ module Public {
none()
}
/**
* Holds if values stored inside `content` are cleared on objects passed as
* arguments at position `pos` to this callable.
*
* TODO: Remove once all languages support `WithoutContent` tokens.
*/
pragma[nomagic]
predicate clearsContent(ParameterPosition pos, ContentSet content) { none() }
/**
* Holds if the summary is auto generated.
*/
@@ -328,23 +319,6 @@ module Private {
SummaryComponentStack::singleton(TArgumentSummaryComponent(_))) and
preservesValue = preservesValue1.booleanAnd(preservesValue2)
)
or
exists(ParameterPosition ppos, ContentSet cs |
c.clearsContent(ppos, cs) and
input = SummaryComponentStack::push(SummaryComponent::withoutContent(cs), output) and
output = SummaryComponentStack::argument(ppos) and
preservesValue = true
)
}
private class MkClearStack extends RequiredSummaryComponentStack {
override predicate required(SummaryComponent head, SummaryComponentStack tail) {
exists(SummarizedCallable sc, ParameterPosition ppos, ContentSet cs |
sc.clearsContent(ppos, cs) and
head = SummaryComponent::withoutContent(cs) and
tail = SummaryComponentStack::argument(ppos)
)
}
}
/**
@@ -945,8 +919,7 @@ module Private {
AccessPath inSpec, AccessPath outSpec, string kind
) {
summaryElement(this, inSpec, outSpec, kind, true) and
not summaryElement(this, _, _, _, false) and
not this.clearsContent(_, _)
not summaryElement(this, _, _, _, false)
}
private predicate relevantSummaryElement(AccessPath inSpec, AccessPath outSpec, string kind) {

View File

@@ -0,0 +1,9 @@
/** Provides modules for importing negative summaries. */
/**
* A module importing the frameworks that provide external flow data,
* ensuring that they are visible to the taint tracking / data flow library.
*/
private module Frameworks {
private import semmle.code.java.frameworks.GeneratedNegative
}

View File

@@ -251,7 +251,7 @@ private predicate qualifierToArgumentStep(Expr tracked, Expr sink) {
/** Access to a method that passes taint from the qualifier. */
private predicate qualifierToMethodStep(Expr tracked, MethodAccess sink) {
(taintPreservingQualifierToMethod(sink.getMethod()) or unsafeEscape(sink)) and
taintPreservingQualifierToMethod(sink.getMethod()) and
tracked = sink.getQualifier()
}
@@ -282,28 +282,6 @@ private predicate taintPreservingQualifierToMethod(Method m) {
)
}
private class StringReplaceMethod extends TaintPreservingCallable {
StringReplaceMethod() {
this.getDeclaringType() instanceof TypeString and
(
this.hasName("replace") or
this.hasName("replaceAll") or
this.hasName("replaceFirst")
)
}
override predicate returnsTaintFrom(int arg) { arg = 1 }
}
private predicate unsafeEscape(MethodAccess ma) {
// Removing `<script>` tags using a string-replace method is
// unsafe if such a tag is embedded inside another one (e.g. `<scr<script>ipt>`).
exists(StringReplaceMethod m | ma.getMethod() = m |
ma.getArgument(0).(StringLiteral).getValue() = "(<script>)" and
ma.getArgument(1).(StringLiteral).getValue() = ""
)
}
/** Access to a method that passes taint from an argument. */
private predicate argToMethodStep(Expr tracked, MethodAccess sink) {
exists(Method m, int i |

View File

@@ -172,7 +172,12 @@ abstract class Configuration extends DataFlow::Configuration {
}
override predicate allowImplicitRead(DataFlow::Node node, DataFlow::ContentSet c) {
(this.isSink(node) or this.isAdditionalTaintStep(node, _)) and
(
this.isSink(node) or
this.isSink(node, _) or
this.isAdditionalTaintStep(node, _) or
this.isAdditionalTaintStep(node, _, _, _)
) and
defaultImplicitTaintRead(node, c)
}

View File

@@ -172,7 +172,12 @@ abstract class Configuration extends DataFlow::Configuration {
}
override predicate allowImplicitRead(DataFlow::Node node, DataFlow::ContentSet c) {
(this.isSink(node) or this.isAdditionalTaintStep(node, _)) and
(
this.isSink(node) or
this.isSink(node, _) or
this.isAdditionalTaintStep(node, _) or
this.isAdditionalTaintStep(node, _, _, _)
) and
defaultImplicitTaintRead(node, c)
}

View File

@@ -172,7 +172,12 @@ abstract class Configuration extends DataFlow::Configuration {
}
override predicate allowImplicitRead(DataFlow::Node node, DataFlow::ContentSet c) {
(this.isSink(node) or this.isAdditionalTaintStep(node, _)) and
(
this.isSink(node) or
this.isSink(node, _) or
this.isAdditionalTaintStep(node, _) or
this.isAdditionalTaintStep(node, _, _, _)
) and
defaultImplicitTaintRead(node, c)
}

View File

@@ -162,7 +162,7 @@ class LiveClass extends SourceClassOrInterface {
exists(LiveField f | f.getDeclaringType() = this |
// A `serialVersionUID` field is considered to be a live field, but is
// not be enough to be make this class live.
not f instanceof SerialVersionUIDField
not f instanceof SerialVersionUidField
)
or
// If this is a namespace class, it is live if there is at least one live nested class.
@@ -250,7 +250,7 @@ class DeadMethod extends Callable {
// These getters and setters are often generated in an ad-hoc way by the developer, which leads to
// methods that are theoretically dead, but uninteresting. We therefore ignore them, so long as
// they are "simple".
not exists(JPAReadField readField | this.getDeclaringType() = readField.getDeclaringType() |
not exists(JpaReadField readField | this.getDeclaringType() = readField.getDeclaringType() |
this.(GetterMethod).getField() = readField or
this.(SetterMethod).getField() = readField
)

View File

@@ -87,8 +87,8 @@ abstract class WhitelistedLiveField extends Field { }
* A static, final, long field named `serialVersionUID` in a class that extends `Serializable` acts as
* a version number for the serialization framework.
*/
class SerialVersionUIDField extends ReflectivelyReadField {
SerialVersionUIDField() {
class SerialVersionUidField extends ReflectivelyReadField {
SerialVersionUidField() {
this.hasName("serialVersionUID") and
this.isStatic() and
this.isFinal() and
@@ -97,6 +97,9 @@ class SerialVersionUIDField extends ReflectivelyReadField {
}
}
/** DEPRECATED: Alias for SerialVersionUidField */
deprecated class SerialVersionUIDField = SerialVersionUidField;
/**
* A field is read by the JAXB during serialization if it is a JAXB bound field, and if the
* containing class is considered "live".
@@ -154,8 +157,8 @@ class JacksonMixinReflextivelyReadField extends ReflectivelyReadField {
/**
* A field which is read by a JPA compatible Java persistence framework.
*/
class JPAReadField extends ReflectivelyReadField {
JPAReadField() {
class JpaReadField extends ReflectivelyReadField {
JpaReadField() {
exists(PersistentEntity entity |
this = entity.getAField() and
(
@@ -169,3 +172,6 @@ class JPAReadField extends ReflectivelyReadField {
)
}
}
/** DEPRECATED: Alias for JpaReadField */
deprecated class JPAReadField = JpaReadField;

View File

@@ -128,8 +128,9 @@ class JacksonMixinCallableEntryPoint extends EntryPoint {
override Callable getALiveCallable() { result = this }
}
class JAXAnnotationReflectivelyConstructedClass extends ReflectivelyConstructedClass {
JAXAnnotationReflectivelyConstructedClass() {
/** A JAX annotation seen as a reflectively constructed class. */
class JaxAnnotationReflectivelyConstructedClass extends ReflectivelyConstructedClass {
JaxAnnotationReflectivelyConstructedClass() {
this instanceof JaxWsEndpoint or
this instanceof JaxbXmlRegistry or
this instanceof JaxRsResourceClass or
@@ -137,6 +138,10 @@ class JAXAnnotationReflectivelyConstructedClass extends ReflectivelyConstructedC
}
}
/** DEPRECATED: Alias for JaxAnnotationReflectivelyConstructedClass */
deprecated class JAXAnnotationReflectivelyConstructedClass =
JaxAnnotationReflectivelyConstructedClass;
class DeserializedClass extends ReflectivelyConstructedClass {
DeserializedClass() {
exists(CastingExpr cast, ReadObjectMethod readObject |
@@ -342,8 +347,9 @@ class GsonDeserializationEntryPoint extends ReflectivelyConstructedClass {
}
}
class JAXBDeserializationEntryPoint extends ReflectivelyConstructedClass {
JAXBDeserializationEntryPoint() {
/** A JAXB deserialization entry point seen as a reflectively constructed class. */
class JaxbDeserializationEntryPoint extends ReflectivelyConstructedClass {
JaxbDeserializationEntryPoint() {
// A class can be deserialized by JAXB if it's an `XmlRootElement`...
this.getAnAnnotation().getType().hasQualifiedName("javax.xml.bind.annotation", "XmlRootElement")
or
@@ -356,6 +362,9 @@ class JAXBDeserializationEntryPoint extends ReflectivelyConstructedClass {
}
}
/** DEPRECATED: Alias for JaxbDeserializationEntryPoint */
deprecated class JAXBDeserializationEntryPoint = JaxbDeserializationEntryPoint;
/**
* A `javax.annotation` for a method that is called after or before dependency injection on a type.
*

View File

@@ -104,8 +104,8 @@ class SpringAspect extends CallableEntryPoint {
/**
* Spring Shell provides annotations for identifying methods that contribute CLI commands.
*/
class SpringCLI extends CallableEntryPoint {
SpringCLI() {
class SpringCli extends CallableEntryPoint {
SpringCli() {
(
hasAnnotation("org.springframework.shell.core.annotation", "CliCommand") or
hasAnnotation("org.springframework.shell.core.annotation", "CliAvailabilityIndicator")
@@ -116,6 +116,9 @@ class SpringCLI extends CallableEntryPoint {
}
}
/** DEPRECATED: Alias for SpringCli */
deprecated class SpringCLI = SpringCli;
/**
* An entry point which acts as a remote API for a Flex application to access a Spring application.
*/

View File

@@ -58,15 +58,18 @@ class ServletFilterClass extends ReflectivelyConstructedClass {
/**
* An entry point into a GWT application.
*/
class GWTEntryPointConstructedClass extends ReflectivelyConstructedClass {
GWTEntryPointConstructedClass() { this.(GwtEntryPointClass).isLive() }
class GwtEntryPointConstructedClass extends ReflectivelyConstructedClass {
GwtEntryPointConstructedClass() { this.(GwtEntryPointClass).isLive() }
}
/** DEPRECATED: Alias for GwtEntryPointConstructedClass */
deprecated class GWTEntryPointConstructedClass = GwtEntryPointConstructedClass;
/**
* Servlets referred to from a GWT module config file.
*/
class GWTServletClass extends ReflectivelyConstructedClass {
GWTServletClass() {
class GwtServletClass extends ReflectivelyConstructedClass {
GwtServletClass() {
this instanceof ServletClass and
// There must be evidence that GWT is being used, otherwise missing `*.gwt.xml` files could cause
// all `Servlet`s to be live.
@@ -81,6 +84,9 @@ class GWTServletClass extends ReflectivelyConstructedClass {
}
}
/** DEPRECATED: Alias for GwtServletClass */
deprecated class GWTServletClass = GwtServletClass;
/**
* Methods that may be called reflectively by the UiHandler framework.
*/

View File

@@ -15,6 +15,7 @@ private import semmle.code.java.dataflow.internal.DataFlowUtil
private import semmle.code.java.dataflow.internal.DataFlowPrivate
private import semmle.code.java.dataflow.internal.ContainerFlow
private import semmle.code.java.dataflow.InstanceAccess
private import semmle.code.java.dispatch.internal.Unification
/**
* Gets a viable dispatch target for `ma`. This is the input dispatch relation.
@@ -266,67 +267,10 @@ Method viableImpl_out(MethodAccess ma) {
)
}
private module Unification {
pragma[noinline]
private predicate unificationTargetLeft(ParameterizedType t1, GenericType g) {
objectToStringQualType(_, t1) and t1.getGenericType() = g
}
private predicate unificationTargetLeft(ParameterizedType t1) { objectToStringQualType(_, t1) }
pragma[noinline]
private predicate unificationTargetRight(ParameterizedType t2, GenericType g) {
exists(viableMethodImpl(_, _, t2)) and t2.getGenericType() = g
}
private predicate unificationTargets(Type t1, Type t2) {
exists(GenericType g | unificationTargetLeft(t1, g) and unificationTargetRight(t2, g))
or
exists(Array a1, Array a2 |
unificationTargets(a1, a2) and
t1 = a1.getComponentType() and
t2 = a2.getComponentType()
)
or
exists(ParameterizedType pt1, ParameterizedType pt2, int pos |
unificationTargets(pt1, pt2) and
not pt1.getSourceDeclaration() != pt2.getSourceDeclaration() and
t1 = pt1.getTypeArgument(pos) and
t2 = pt2.getTypeArgument(pos)
)
}
pragma[noinline]
private predicate typeArgsOfUnificationTargets(
ParameterizedType t1, ParameterizedType t2, int pos, RefType arg1, RefType arg2
) {
unificationTargets(t1, t2) and
arg1 = t1.getTypeArgument(pos) and
arg2 = t2.getTypeArgument(pos)
}
pragma[nomagic]
predicate failsUnification(Type t1, Type t2) {
unificationTargets(t1, t2) and
(
exists(RefType arg1, RefType arg2 |
typeArgsOfUnificationTargets(t1, t2, _, arg1, arg2) and
failsUnification(arg1, arg2)
)
or
failsUnification(t1.(Array).getComponentType(), t2.(Array).getComponentType())
or
not (
t1 instanceof Array and t2 instanceof Array
or
t1.(PrimitiveType) = t2.(PrimitiveType)
or
t1.(Class).getSourceDeclaration() = t2.(Class).getSourceDeclaration()
or
t1.(Interface).getSourceDeclaration() = t2.(Interface).getSourceDeclaration()
or
t1 instanceof BoundedType and t2 instanceof RefType
or
t1 instanceof RefType and t2 instanceof BoundedType
)
)
}
private predicate unificationTargetRight(ParameterizedType t2) {
exists(viableMethodImpl(_, _, t2))
}
private module Unification = MkUnification<unificationTargetLeft/1, unificationTargetRight/1>;

View File

@@ -9,6 +9,7 @@ private import DispatchFlow as DispatchFlow
private import ObjFlow as ObjFlow
private import semmle.code.java.dataflow.internal.BaseSSA
private import semmle.code.java.controlflow.Guards
private import semmle.code.java.dispatch.internal.Unification
/**
* A conservative analysis that returns a single method - if we can establish
@@ -53,6 +54,16 @@ private module Dispatch {
cached
Method viableImpl(MethodAccess ma) { result = ObjFlow::viableImpl_out(ma) }
/**
* Holds if `m` is a viable implementation of the method called in `ma` for
* which we only have imprecise open-world type-based dispatch resolution, and
* the dispatch type is likely to yield implausible dispatch targets.
*/
cached
predicate lowConfidenceDispatchTarget(MethodAccess ma, Method m) {
m = viableImpl(ma) and lowConfidenceDispatch(ma)
}
/**
* INTERNAL: Use `viableImpl` instead.
*
@@ -61,8 +72,42 @@ private module Dispatch {
cached
Method viableImpl_v3(MethodAccess ma) { result = DispatchFlow::viableImpl_out(ma) }
private predicate qualType(VirtualMethodAccess ma, RefType t, boolean exact) {
exprTypeFlow(ma.getQualifier(), t, exact)
/**
* Holds if the best type bounds for the qualifier of `ma` are likely to
* contain implausible dispatch targets.
*/
private predicate lowConfidenceDispatch(VirtualMethodAccess ma) {
exists(RefType t | hasQualifierType(ma, t, false) |
lowConfidenceDispatchType(t.getSourceDeclaration())
) and
(
not qualType(ma, _, _)
or
exists(RefType t | qualType(ma, t, false) |
lowConfidenceDispatchType(t.getSourceDeclaration())
)
) and
(
not qualUnionType(ma, _, _)
or
exists(RefType t | qualUnionType(ma, t, false) |
lowConfidenceDispatchType(t.getSourceDeclaration())
)
)
}
private predicate lowConfidenceDispatchType(SrcRefType t) {
t instanceof TypeObject
or
t instanceof FunctionalInterface
or
t.hasQualifiedName("java.io", "Serializable")
or
t.hasQualifiedName("java.lang", "Cloneable")
or
t.getPackage().hasName("java.util") and t instanceof Interface
or
t.hasQualifiedName("java.util", "Hashtable")
}
/**
@@ -72,6 +117,35 @@ private module Dispatch {
*/
cached
Method viableImpl_v2(MethodAccess ma) {
result = viableImpl_v2_cand(pragma[only_bind_into](ma)) and
exists(Method def, RefType t, boolean exact |
qualUnionType(pragma[only_bind_into](ma), pragma[only_bind_into](t),
pragma[only_bind_into](exact)) and
def = ma.getMethod().getSourceDeclaration()
|
exact = true and result = exactMethodImpl(def, t.getSourceDeclaration())
or
exact = false and
exists(RefType t2 |
result = viableMethodImpl(def, t.getSourceDeclaration(), t2) and
not Unification_v2::failsUnification(t, t2)
)
)
or
result = viableImpl_v2_cand(ma) and
not qualUnionType(ma, _, _)
}
private predicate qualUnionType(VirtualMethodAccess ma, RefType t, boolean exact) {
exprUnionTypeFlow(ma.getQualifier(), t, exact)
}
private predicate unificationTargetLeft_v2(ParameterizedType t1) { qualUnionType(_, t1, _) }
private module Unification_v2 =
MkUnification<unificationTargetLeft_v2/1, unificationTargetRight/1>;
private Method viableImpl_v2_cand(MethodAccess ma) {
result = viableImpl_v1(ma) and
(
exists(Method def, RefType t, boolean exact |
@@ -83,7 +157,7 @@ private module Dispatch {
exact = false and
exists(RefType t2 |
result = viableMethodImpl(def, t.getSourceDeclaration(), t2) and
not Unification_v2::failsUnification(t, t2)
not Unification_v2_cand::failsUnification(t, t2)
)
)
or
@@ -91,70 +165,15 @@ private module Dispatch {
)
}
private module Unification_v2 {
pragma[noinline]
private predicate unificationTargetLeft(ParameterizedType t1, GenericType g) {
qualType(_, t1, _) and t1.getGenericType() = g
}
pragma[noinline]
private predicate unificationTargetRight(ParameterizedType t2, GenericType g) {
exists(viableMethodImpl(_, _, t2)) and t2.getGenericType() = g
}
private predicate unificationTargets(Type t1, Type t2) {
exists(GenericType g | unificationTargetLeft(t1, g) and unificationTargetRight(t2, g))
or
exists(Array a1, Array a2 |
unificationTargets(a1, a2) and
t1 = a1.getComponentType() and
t2 = a2.getComponentType()
)
or
exists(ParameterizedType pt1, ParameterizedType pt2, int pos |
unificationTargets(pt1, pt2) and
not pt1.getSourceDeclaration() != pt2.getSourceDeclaration() and
t1 = pt1.getTypeArgument(pos) and
t2 = pt2.getTypeArgument(pos)
)
}
pragma[noinline]
private predicate typeArgsOfUnificationTargets(
ParameterizedType t1, ParameterizedType t2, int pos, RefType arg1, RefType arg2
) {
unificationTargets(t1, t2) and
arg1 = t1.getTypeArgument(pos) and
arg2 = t2.getTypeArgument(pos)
}
predicate failsUnification(Type t1, Type t2) {
unificationTargets(t1, t2) and
(
exists(RefType arg1, RefType arg2 |
typeArgsOfUnificationTargets(t1, t2, _, arg1, arg2) and
failsUnification(arg1, arg2)
)
or
failsUnification(t1.(Array).getComponentType(), t2.(Array).getComponentType())
or
not (
t1 instanceof Array and t2 instanceof Array
or
t1.(PrimitiveType) = t2.(PrimitiveType)
or
t1.(Class).getSourceDeclaration() = t2.(Class).getSourceDeclaration()
or
t1.(Interface).getSourceDeclaration() = t2.(Interface).getSourceDeclaration()
or
t1 instanceof BoundedType and t2 instanceof RefType
or
t1 instanceof RefType and t2 instanceof BoundedType
)
)
}
private predicate qualType(VirtualMethodAccess ma, RefType t, boolean exact) {
exprTypeFlow(ma.getQualifier(), t, exact)
}
private predicate unificationTargetLeft_v2_cand(ParameterizedType t1) { qualType(_, t1, _) }
private module Unification_v2_cand =
MkUnification<unificationTargetLeft_v2_cand/1, unificationTargetRight/1>;
/**
* INTERNAL: Use `viableImpl` instead.
*
@@ -203,70 +222,15 @@ private module Dispatch {
else result = source.getMethod().getSourceDeclaration()
}
private module Unification_v1 {
pragma[noinline]
private predicate unificationTargetLeft(ParameterizedType t1, GenericType g) {
hasQualifierType(_, t1, _) and t1.getGenericType() = g
}
private predicate unificationTargetLeft_v1(ParameterizedType t1) { hasQualifierType(_, t1, _) }
pragma[noinline]
private predicate unificationTargetRight(ParameterizedType t2, GenericType g) {
exists(viableMethodImpl(_, _, t2)) and t2.getGenericType() = g
}
private predicate unificationTargets(Type t1, Type t2) {
exists(GenericType g | unificationTargetLeft(t1, g) and unificationTargetRight(t2, g))
or
exists(Array a1, Array a2 |
unificationTargets(a1, a2) and
t1 = a1.getComponentType() and
t2 = a2.getComponentType()
)
or
exists(ParameterizedType pt1, ParameterizedType pt2, int pos |
unificationTargets(pt1, pt2) and
not pt1.getSourceDeclaration() != pt2.getSourceDeclaration() and
t1 = pt1.getTypeArgument(pos) and
t2 = pt2.getTypeArgument(pos)
)
}
pragma[noinline]
private predicate typeArgsOfUnificationTargets(
ParameterizedType t1, ParameterizedType t2, int pos, RefType arg1, RefType arg2
) {
unificationTargets(t1, t2) and
arg1 = t1.getTypeArgument(pos) and
arg2 = t2.getTypeArgument(pos)
}
predicate failsUnification(Type t1, Type t2) {
unificationTargets(t1, t2) and
(
exists(RefType arg1, RefType arg2 |
typeArgsOfUnificationTargets(t1, t2, _, arg1, arg2) and
failsUnification(arg1, arg2)
)
or
failsUnification(t1.(Array).getComponentType(), t2.(Array).getComponentType())
or
not (
t1 instanceof Array and t2 instanceof Array
or
t1.(PrimitiveType) = t2.(PrimitiveType)
or
t1.(Class).getSourceDeclaration() = t2.(Class).getSourceDeclaration()
or
t1.(Interface).getSourceDeclaration() = t2.(Interface).getSourceDeclaration()
or
t1 instanceof BoundedType and t2 instanceof RefType
or
t1 instanceof RefType and t2 instanceof BoundedType
)
)
}
private predicate unificationTargetRight(ParameterizedType t2) {
exists(viableMethodImpl(_, _, t2))
}
private module Unification_v1 =
MkUnification<unificationTargetLeft_v1/1, unificationTargetRight/1>;
private RefType getPreciseType(Expr e) {
result = e.(FunctionalExpr).getConstructedType()
or
@@ -274,9 +238,8 @@ private module Dispatch {
}
private predicate hasQualifierType(VirtualMethodAccess ma, RefType t, boolean exact) {
exists(Expr src | src = variableTrack(ma.getQualifier()) |
// If we have a qualifier, then we track it through variable assignments
// and take the type of the assigned value.
exists(Expr src | src = ma.getQualifier() |
// If we have a qualifier, then we take its type.
exists(RefType srctype | srctype = getPreciseType(src) |
exists(BoundedType bd | bd = srctype |
t = bd.getAnUltimateUpperBoundType()
@@ -324,43 +287,20 @@ private module Dispatch {
exists(Method m | t.hasMethod(m, _, _) and impl = m.getSourceDeclaration())
}
private predicate isAbstractWithSubclass(SrcRefType t) {
t.isAbstract() and exists(Class c | c.getASourceSupertype() = t)
}
private predicate hasViableSubtype(RefType t, SrcRefType sub) {
sub.extendsOrImplements*(t) and
not sub instanceof Interface and
not sub.isAbstract()
not isAbstractWithSubclass(sub)
}
}
import Dispatch
private Expr variableTrackStep(Expr use) {
exists(Variable v |
pragma[only_bind_out](use) = v.getAnAccess() and
use.getType() instanceof RefType and
not result instanceof NullLiteral and
not v.(LocalVariableDecl).getDeclExpr().hasImplicitInit()
|
not v instanceof Parameter and
result = v.getAnAssignedValue()
or
exists(Parameter p | p = v and p.getCallable().isPrivate() |
result = p.getAnAssignedValue() or
result = p.getAnArgument()
)
)
}
private Expr variableTrackPath(Expr use) {
result = variableTrackStep*(use) and
not exists(variableTrackStep(result))
}
/**
* Gets an expression by tracking `use` backwards through variable assignments.
* DEPRECATED: Use `TypeFlow` instead.
*/
pragma[inline]
Expr variableTrack(Expr use) {
result = variableTrackPath(use)
or
not exists(variableTrackPath(use)) and result = use
}
deprecated Expr variableTrack(Expr use) { result = use }

View File

@@ -0,0 +1,136 @@
/**
* Provides a module to check whether two `ParameterizedType`s are unifiable.
*/
import java
/** Holds if `t` is a relevant type to consider for unification. */
signature predicate unificationTarget(ParameterizedType t);
/**
* Given two sets of parameterised types to consider for unification, returns
* the set of pairs that are not unifiable.
*/
module MkUnification<unificationTarget/1 targetLeft, unificationTarget/1 targetRight> {
pragma[noinline]
private predicate unificationTargetLeft(ParameterizedType t1, GenericType g) {
targetLeft(t1) and t1.getGenericType() = g
}
pragma[noinline]
private predicate unificationTargetRight(ParameterizedType t2, GenericType g) {
targetRight(t2) and t2.getGenericType() = g
}
private predicate unificationTargets(Type t1, Type t2) {
exists(GenericType g | unificationTargetLeft(t1, g) and unificationTargetRight(t2, g))
or
exists(Array a1, Array a2 |
unificationTargets(a1, a2) and
t1 = a1.getComponentType() and
t2 = a2.getComponentType()
)
or
exists(ParameterizedType pt1, ParameterizedType pt2, int pos |
unificationTargets(pt1, pt2) and
not pt1.getSourceDeclaration() != pt2.getSourceDeclaration() and
t1 = pt1.getTypeArgument(pos) and
t2 = pt2.getTypeArgument(pos)
)
}
pragma[noinline]
private predicate typeArgsOfUnificationTargets(
ParameterizedType t1, ParameterizedType t2, int pos, RefType arg1, RefType arg2
) {
unificationTargets(t1, t2) and
arg1 = t1.getTypeArgument(pos) and
arg2 = t2.getTypeArgument(pos)
}
private RefType getUpperBound(RefType t) {
if t instanceof BoundedType
then result = t.(BoundedType).getAnUltimateUpperBoundType()
else result = t
}
/**
* Holds if `t1` and `t2` are not unifiable.
*
* Restricted to only consider pairs of types such that `targetLeft(t1)`,
* `targetRight(t2)`, and that both are parameterised instances of the same
* generic type.
*/
pragma[nomagic]
predicate failsUnification(Type t1, Type t2) {
unificationTargets(t1, t2) and
(
exists(RefType arg1, RefType arg2 |
typeArgsOfUnificationTargets(t1, t2, _, arg1, arg2) and
failsUnification(arg1, arg2)
)
or
failsUnification(t1.(Array).getComponentType(), t2.(Array).getComponentType())
or
// Can't unify an `extends` bound against a concrete type that doesn't
// descend from that upper bound:
exists(RefType upperbound, RefType other |
t1.(BoundedType).getAnUltimateUpperBoundType().getSourceDeclaration() = upperbound and
t2.(RefType).getSourceDeclaration() = other and
not t2 instanceof BoundedType
or
t2.(BoundedType).getAnUltimateUpperBoundType().getSourceDeclaration() = upperbound and
t1.(RefType).getSourceDeclaration() = other and
not t1 instanceof BoundedType
|
not other.getASourceSupertype*() = upperbound
)
or
// Can't unify two `extends` bounds that don't intersect:
exists(RefType upperbound1, RefType upperbound2 |
t1.(BoundedType).getAnUltimateUpperBoundType() = upperbound1 and
t2.(BoundedType).getAnUltimateUpperBoundType() = upperbound2 and
notHaveIntersection(upperbound1, upperbound2)
)
or
// Can't unify `? super X` against `Y` or `_ extends Y` where `Y` isn't an
// ancestor of `X`:
exists(RefType lowerbound, RefType upperbound |
t1.(Wildcard).getLowerBoundType().(RefType).getSourceDeclaration() = lowerbound and
getUpperBound(t2).getSourceDeclaration() = upperbound
or
t2.(Wildcard).getLowerBoundType().(RefType).getSourceDeclaration() = lowerbound and
getUpperBound(t1).getSourceDeclaration() = upperbound
|
not lowerbound instanceof BoundedType and
not lowerbound.getASourceSupertype*() = upperbound
)
or
// Can't unify `? super T`, where `T` is a type variable `T extends S`,
// with a type that doesn't intersect with `S`:
exists(BoundedType lowerbound, RefType upperbound |
t1.(Wildcard).getLowerBoundType() = lowerbound and
getUpperBound(t2) = upperbound
or
t2.(Wildcard).getLowerBoundType() = lowerbound and
getUpperBound(t1) = upperbound
|
notHaveIntersection(lowerbound.getUpperBoundType(), upperbound)
)
or
not (
t1 instanceof Array and t2 instanceof Array
or
t1.(PrimitiveType) = t2.(PrimitiveType)
or
t1.(Class).getSourceDeclaration() = t2.(Class).getSourceDeclaration()
or
t1.(Interface).getSourceDeclaration() = t2.(Interface).getSourceDeclaration()
or
t1 instanceof BoundedType and t2 instanceof RefType
or
t1 instanceof RefType and t2 instanceof BoundedType
)
)
}
}

View File

@@ -13,7 +13,7 @@ import semmle.code.java.frameworks.camel.CamelJavaAnnotations
class CamelToUri extends string {
CamelToUri() {
exists(SpringCamelXmlToElement toXmlElement | this = toXmlElement.getUri()) or
exists(CamelJavaDSLToDecl toJavaDSL | this = toJavaDSL.getUri())
exists(CamelJavaDslToDecl toJavaDsl | this = toJavaDsl.getUri())
}
}
@@ -77,13 +77,13 @@ class CamelTargetClass extends Class {
this = xmlMethod.getBeanType()
)
or
exists(CamelJavaDSLMethodDecl methodDecl | this = methodDecl.getABean())
exists(CamelJavaDslMethodDecl methodDecl | this = methodDecl.getABean())
or
// Any beans referred to in Java DSL bean or beanRef elements are considered as possible
// targets. Whether the route builder is ever constructed or called is not considered.
exists(CamelJavaDSLBeanDecl beanDecl | this = beanDecl.getABeanClass())
exists(CamelJavaDslBeanDecl beanDecl | this = beanDecl.getABeanClass())
or
exists(CamelJavaDSLBeanRefDecl beanRefDecl | this = beanRefDecl.getABeanClass())
exists(CamelJavaDslBeanRefDecl beanRefDecl | this = beanRefDecl.getABeanClass())
}
/**

View File

@@ -0,0 +1,8 @@
/** Provides a module for importing negative models. */
/**
* A module importing all generated negative Models as Data models.
*/
private module GeneratedFrameworks {
private import apache.NegativeIOGenerated
}

View File

@@ -2,20 +2,26 @@
import semmle.code.java.Type
library class JAXBElement extends Class {
JAXBElement() {
library class JaxbElement extends Class {
JaxbElement() {
this.getAnAncestor().getQualifiedName() = "javax.xml.bind.JAXBElement" or
this.getAnAnnotation().getType().getName() = "XmlRootElement"
}
}
library class JAXBMarshalMethod extends Method {
JAXBMarshalMethod() {
/** DEPRECATED: Alias for JaxbElement */
deprecated class JAXBElement = JaxbElement;
library class JaxbMarshalMethod extends Method {
JaxbMarshalMethod() {
this.getDeclaringType().getQualifiedName() = "javax.xml.bind.Marshaller" and
this.getName() = "marshal"
}
}
/** DEPRECATED: Alias for JaxbMarshalMethod */
deprecated class JAXBMarshalMethod = JaxbMarshalMethod;
class JaxbAnnotationType extends AnnotationType {
JaxbAnnotationType() { this.getPackage().getName() = "javax.xml.bind.annotation" }
}
@@ -54,7 +60,7 @@ class JaxbType extends Class {
this.getAnAnnotation() = a and
a.getType().(JaxbAnnotationType).hasName("XmlAccessorType")
|
result.getAnAccess() = a.getValue("value")
result = a.getEnumConstantValue("value")
)
}

View File

@@ -64,5 +64,5 @@ class RunWithAnnotation extends Annotation {
/**
* Gets the runner that will be used.
*/
Type getRunner() { result = this.getValue("value").(TypeLiteral).getReferencedType() }
Type getRunner() { result = this.getTypeValue("value") }
}

View File

@@ -296,11 +296,7 @@ class JaxRSProducesAnnotation extends JaxRSAnnotation {
/**
* Gets a declared content type that can be produced by this resource.
*/
Expr getADeclaredContentTypeExpr() {
result = this.getAValue() and not result instanceof ArrayInit
or
result = this.getAValue().(ArrayInit).getAnInit()
}
Expr getADeclaredContentTypeExpr() { result = this.getAnArrayValue("value") }
}
/** An `@Consumes` annotation that describes content types can be consumed by this resource. */

View File

@@ -1,11 +0,0 @@
/** Definitions of taint steps in the KotlinStdLib framework */
import java
private import semmle.code.java.dataflow.ExternalFlow
private class KotlinStdLibSummaryCsv extends SummaryModelCsv {
override predicate row(string row) {
row =
"kotlin.jvm.internal;ArrayIteratorKt;false;iterator;(Object[]);;Argument[0].ArrayElement;ReturnValue.Element;value;manual"
}
}

View File

@@ -85,9 +85,7 @@ class IbatisSqlOperationAnnotation extends Annotation {
/**
* Gets this annotation's SQL statement string.
*/
string getSqlValue() {
result = this.getAValue("value").(CompileTimeConstantExpr).getStringValue()
}
string getSqlValue() { result = this.getAStringArrayValue("value") }
}
/**

View File

@@ -20,10 +20,17 @@ private class StringSummaryCsv extends SummaryModelCsv {
"java.lang;String;false;formatted;(Object[]);;Argument[0].ArrayElement;ReturnValue;taint;manual",
"java.lang;String;false;getChars;;;Argument[-1];Argument[2];taint;manual",
"java.lang;String;false;getBytes;;;Argument[-1];ReturnValue;taint;manual",
"java.lang;String;false;getBytes;;;Argument[-1];Argument[2];taint;manual",
"java.lang;String;false;indent;;;Argument[-1];ReturnValue;taint;manual",
"java.lang;String;false;intern;;;Argument[-1];ReturnValue;taint;manual",
"java.lang;String;false;join;;;Argument[0..1];ReturnValue;taint;manual",
"java.lang;String;false;repeat;(int);;Argument[-1];ReturnValue;taint;manual",
"java.lang;String;false;replace;;;Argument[-1];ReturnValue;taint;manual",
"java.lang;String;false;replace;;;Argument[1];ReturnValue;taint;manual",
"java.lang;String;false;replaceAll;;;Argument[-1];ReturnValue;taint;manual",
"java.lang;String;false;replaceAll;;;Argument[1];ReturnValue;taint;manual",
"java.lang;String;false;replaceFirst;;;Argument[-1];ReturnValue;taint;manual",
"java.lang;String;false;replaceFirst;;;Argument[1];ReturnValue;taint;manual",
"java.lang;String;false;split;;;Argument[-1];ReturnValue;taint;manual",
"java.lang;String;false;String;;;Argument[0];Argument[-1];taint;manual",
"java.lang;String;false;strip;;;Argument[-1];ReturnValue;taint;manual",
@@ -55,6 +62,7 @@ private class StringSummaryCsv extends SummaryModelCsv {
"java.lang;StringBuffer;true;StringBuffer;(CharSequence);;Argument[0];Argument[-1];taint;manual",
"java.lang;StringBuffer;true;StringBuffer;(String);;Argument[0];Argument[-1];taint;manual",
"java.lang;StringBuilder;true;StringBuilder;;;Argument[0];Argument[-1];taint;manual",
"java.lang;CharSequence;true;charAt;;;Argument[-1];ReturnValue;taint;manual",
"java.lang;CharSequence;true;subSequence;;;Argument[-1];ReturnValue;taint;manual",
"java.lang;CharSequence;true;toString;;;Argument[-1];ReturnValue;taint;manual"
]

View File

@@ -0,0 +1,16 @@
/**
* Provides classes and predicates for working with the Thymeleaf template engine.
*/
import java
private import semmle.code.java.dataflow.ExternalFlow
private class ThymeleafSummaryModels extends SummaryModelCsv {
override predicate row(string row) {
row =
[
"org.thymeleaf;TemplateSpec;false;TemplateSpec;;;Argument[0];Argument[-1];taint;manual",
"org.thymeleaf;TemplateSpec;false;getTemplate;;;Argument[-1];ReturnValue;taint;manual",
]
}
}

View File

@@ -58,13 +58,16 @@ class MethodUnboundIdFilterCreate extends Method {
}
/** A method with the name `createANDFilter` declared in `com.unboundid.ldap.sdk.Filter`. */
class MethodUnboundIdFilterCreateANDFilter extends Method {
MethodUnboundIdFilterCreateANDFilter() {
class MethodUnboundIdFilterCreateAndFilter extends Method {
MethodUnboundIdFilterCreateAndFilter() {
this.getDeclaringType() instanceof TypeUnboundIdLdapFilter and
this.hasName("createANDFilter")
}
}
/** DEPRECATED: Alias for MethodUnboundIdFilterCreateAndFilter */
deprecated class MethodUnboundIdFilterCreateANDFilter = MethodUnboundIdFilterCreateAndFilter;
/** A method with the name `createORFilter` declared in `com.unboundid.ldap.sdk.Filter`. */
class MethodUnboundIdFilterCreateORFilter extends Method {
MethodUnboundIdFilterCreateORFilter() {
@@ -73,9 +76,12 @@ class MethodUnboundIdFilterCreateORFilter extends Method {
}
}
/** DEPRECATED: Alias for MethodUnboundIdFilterCreateNOTFilter */
deprecated class MethodUnboundIdFilterCreateNOTFilter = MethodUnboundIdFilterCreateNotFilter;
/** A method with the name `createNOTFilter` declared in `com.unboundid.ldap.sdk.Filter`. */
class MethodUnboundIdFilterCreateNOTFilter extends Method {
MethodUnboundIdFilterCreateNOTFilter() {
class MethodUnboundIdFilterCreateNotFilter extends Method {
MethodUnboundIdFilterCreateNotFilter() {
this.getDeclaringType() instanceof TypeUnboundIdLdapFilter and
this.hasName("createNOTFilter")
}

View File

@@ -53,7 +53,64 @@ private class SummaryModels extends SummaryModelCsv {
"android.content;ContentValues;false;put;;;Argument[0];Argument[-1].MapKey;value;manual",
"android.content;ContentValues;false;put;;;Argument[1];Argument[-1].MapValue;value;manual",
"android.content;ContentValues;false;putAll;;;Argument[0].MapKey;Argument[-1].MapKey;value;manual",
"android.content;ContentValues;false;putAll;;;Argument[0].MapValue;Argument[-1].MapValue;value;manual"
"android.content;ContentValues;false;putAll;;;Argument[0].MapValue;Argument[-1].MapValue;value;manual",
"android.content;ContentResolver;true;acquireContentProviderClient;;;Argument[0];ReturnValue;taint;manual",
"android.content;ContentResolver;true;acquireUnstableContentProviderClient;;;Argument[0];ReturnValue;taint;manual",
"android.content;ContentResolver;true;acquireUnstableContentProviderClient;;;Argument[0];ReturnValue;taint;manual",
"android.content;ContentResolver;true;applyBatch;;;Argument[1];ReturnValue;taint;manual",
"android.content;ContentResolver;true;call;;;Argument[0];ReturnValue;taint;manual",
"android.content;ContentResolver;true;canonicalize;;;Argument[0];ReturnValue;taint;manual",
"android.content;ContentResolver;true;getStreamTypes;;;Argument[0];ReturnValue;taint;manual",
"android.content;ContentResolver;true;getType;;;Argument[0];ReturnValue;taint;manual",
"android.content;ContentResolver;true;insert;;;Argument[0];ReturnValue;taint;manual",
"android.content;ContentResolver;true;query;;;Argument[0];ReturnValue;taint;manual",
"android.content;ContentResolver;true;uncanonicalize;;;Argument[0];ReturnValue;taint;manual",
"android.content;ContentResolver;true;wrap;;;Argument[0];ReturnValue;taint;manual",
// ContentProviderClient is tainted at its creation, not by its arguments
"android.content;ContentProviderClient;true;applyBatch;;;Argument[-1];ReturnValue;taint;manual",
"android.content;ContentProviderClient;true;call;;;Argument[-1];ReturnValue;taint;manual",
"android.content;ContentProviderClient;true;canonicalize;;;Argument[-1];ReturnValue;taint;manual",
"android.content;ContentProviderClient;true;getLocalContentProvider;;;Argument[-1];ReturnValue;taint;manual",
"android.content;ContentProviderClient;true;getStreamTypes;;;Argument[-1];ReturnValue;taint;manual",
"android.content;ContentProviderClient;true;insert;;;Argument[-1];ReturnValue;taint;manual",
"android.content;ContentProviderClient;true;query;;;Argument[-1];ReturnValue;taint;manual",
"android.content;ContentProviderClient;true;uncanonicalize;;;Argument[-1];ReturnValue;taint;manual",
"android.content;ContentProviderOperation;false;apply;;;Argument[-1];ReturnValue;taint;manual",
"android.content;ContentProviderOperation;false;apply;;;Argument[0];ReturnValue;taint;manual",
"android.content;ContentProviderOperation;false;getUri;;;Argument[-1];ReturnValue;taint;manual",
"android.content;ContentProviderOperation;false;newAssertQuery;;;Argument[0];ReturnValue;taint;manual",
"android.content;ContentProviderOperation;false;newCall;;;Argument[0];ReturnValue;taint;manual",
"android.content;ContentProviderOperation;false;newDelete;;;Argument[0];ReturnValue;taint;manual",
"android.content;ContentProviderOperation;false;newInsert;;;Argument[0];ReturnValue;taint;manual",
"android.content;ContentProviderOperation;false;newUpdate;;;Argument[0];ReturnValue;taint;manual",
"android.content;ContentProviderOperation;false;resolveExtrasBackReferences;;;Argument[0];ReturnValue;taint;manual",
"android.content;ContentProviderOperation;false;resolveSelectionArgsBackReferences;;;Argument[0];ReturnValue;taint;manual",
"android.content;ContentProviderOperation;false;resolveValueBackReferences;;;Argument[0];ReturnValue;taint;manual",
"android.content;ContentProviderOperation$Builder;false;build;;;Argument[-1];ReturnValue;taint;manual",
"android.content;ContentProviderOperation$Builder;false;withExceptionAllowed;;;Argument[-1];ReturnValue;value;manual",
"android.content;ContentProviderOperation$Builder;false;withExpectedCount;;;Argument[-1];ReturnValue;value;manual",
"android.content;ContentProviderOperation$Builder;false;withExtra;;;Argument[-1];ReturnValue;value;manual",
"android.content;ContentProviderOperation$Builder;false;withExtraBackReference;;;Argument[-1];ReturnValue;value;manual",
"android.content;ContentProviderOperation$Builder;false;withExtras;;;Argument[-1];ReturnValue;value;manual",
"android.content;ContentProviderOperation$Builder;false;withSelection;;;Argument[-1];ReturnValue;value;manual",
"android.content;ContentProviderOperation$Builder;false;withSelectionBackReference;;;Argument[-1];ReturnValue;value;manual",
"android.content;ContentProviderOperation$Builder;false;withValue;;;Argument[-1];ReturnValue;value;manual",
"android.content;ContentProviderOperation$Builder;false;withValueBackReference;;;Argument[-1];ReturnValue;value;manual",
"android.content;ContentProviderOperation$Builder;false;withValues;;;Argument[-1];ReturnValue;value;manual",
"android.content;ContentProviderOperation$Builder;false;withYieldAllowed;;;Argument[-1];ReturnValue;value;manual",
"android.content;ContentProviderResult;false;ContentProviderResult;(Uri);;Argument[0];Argument[-1].Field[android.content.ContentProviderResult.uri];value;manual",
"android.content;ContentProviderResult;false;ContentProviderResult;(Bundle);;Argument[0];Argument[-1].Field[android.content.ContentProviderResult.extras];value;manual",
"android.content;ContentProviderResult;false;ContentProviderResult;(Throwable);;Argument[0];Argument[-1].Field[android.content.ContentProviderResult.exception];value;manual",
"android.content;ContentProviderResult;false;ContentProviderResult;(Parcel);;Argument[0];Argument[-1];taint;manual",
"android.database;Cursor;true;copyStringToBuffer;;;Argument[-1];Argument[1];taint;manual",
"android.database;Cursor;true;getBlob;;;Argument[-1];ReturnValue;taint;manual",
"android.database;Cursor;true;getColumnName;;;Argument[-1];ReturnValue;taint;manual",
"android.database;Cursor;true;getColumnNames;;;Argument[-1];ReturnValue;taint;manual",
"android.database;Cursor;true;getExtras;;;Argument[-1];ReturnValue;taint;manual",
"android.database;Cursor;true;getNotificationUri;;;Argument[-1];ReturnValue;taint;manual",
"android.database;Cursor;true;getNotificationUris;;;Argument[-1];ReturnValue;taint;manual",
"android.database;Cursor;true;getString;;;Argument[-1];ReturnValue;taint;manual",
"android.database;Cursor;true;respond;;;Argument[-1];ReturnValue;taint;manual"
]
}
}

View File

@@ -19,6 +19,17 @@ private class NotificationBuildersSummaryModels extends SummaryModelCsv {
"android.app;Notification$Action$Builder;true;build;;;Argument[-1];ReturnValue;taint;manual",
"android.app;Notification$Action$Builder;true;build;;;Argument[-1].SyntheticField[android.content.Intent.extras];ReturnValue.SyntheticField[android.content.Intent.extras];value;manual",
"android.app;Notification$Action$Builder;true;getExtras;;;Argument[-1].SyntheticField[android.content.Intent.extras];ReturnValue;value;manual",
"androidx.core.app;NotificationCompat$Action;true;Action;(int,CharSequence,PendingIntent);;Argument[2];Argument[-1];taint;manual",
"androidx.core.app;NotificationCompat$Action;true;Action;(IconCompat,CharSequence,PendingIntent);;Argument[2];Argument[-1];taint;manual",
"androidx.core.app;NotificationCompat$Action;true;getExtras;;;Argument[-1].SyntheticField[android.content.Intent.extras];ReturnValue;value;manual",
"androidx.core.app;NotificationCompat$Action$Builder;true;Builder;(int,CharSequence,PendingIntent);;Argument[2];Argument[-1];taint;manual",
"androidx.core.app;NotificationCompat$Action$Builder;true;Builder;(IconCompat,CharSequence,PendingIntent);;Argument[2];Argument[-1];taint;manual",
"androidx.core.app;NotificationCompat$Action$Builder;true;Builder;(Action);;Argument[0];Argument[-1];taint;manual",
"androidx.core.app;NotificationCompat$Action$Builder;true;addExtras;;;Argument[0].MapKey;Argument[-1].SyntheticField[android.content.Intent.extras].MapKey;value;manual",
"androidx.core.app;NotificationCompat$Action$Builder;true;addExtras;;;Argument[0].MapValue;Argument[-1].SyntheticField[android.content.Intent.extras].MapValue;value;manual",
"androidx.core.app;NotificationCompat$Action$Builder;true;build;;;Argument[-1];ReturnValue;taint;manual",
"androidx.core.app;NotificationCompat$Action$Builder;true;build;;;Argument[-1].SyntheticField[android.content.Intent.extras];ReturnValue.SyntheticField[android.content.Intent.extras];value;manual",
"androidx.core.app;NotificationCompat$Action$Builder;true;getExtras;;;Argument[-1].SyntheticField[android.content.Intent.extras];ReturnValue;value;manual",
"android.app;Notification$Builder;true;addAction;(int,CharSequence,PendingIntent);;Argument[2];Argument[-1];taint;manual",
"android.app;Notification$Builder;true;addAction;(Action);;Argument[0];Argument[-1];taint;manual",
"android.app;Notification$Builder;true;addExtras;;;Argument[0].MapKey;Argument[-1].SyntheticField[android.content.Intent.extras].MapKey;value;manual",
@@ -32,18 +43,30 @@ private class NotificationBuildersSummaryModels extends SummaryModelCsv {
"android.app;Notification$Builder;true;setExtras;;;Argument[0];Argument[-1].SyntheticField[android.content.Intent.extras];value;manual",
"android.app;Notification$Builder;true;setDeleteIntent;;;Argument[0];Argument[-1];taint;manual",
"android.app;Notification$Builder;true;setPublicVersion;;;Argument[0];Argument[-1];taint;manual",
"androidx.core.app;NotificationCompat$Builder;true;addAction;(int,CharSequence,PendingIntent);;Argument[2];Argument[-1];taint;manual",
"androidx.core.app;NotificationCompat$Builder;true;addAction;(Action);;Argument[0];Argument[-1];taint;manual",
"androidx.core.app;NotificationCompat$Builder;true;addExtras;;;Argument[0].MapKey;Argument[-1].SyntheticField[android.content.Intent.extras].MapKey;value;manual",
"androidx.core.app;NotificationCompat$Builder;true;addExtras;;;Argument[0].MapValue;Argument[-1].SyntheticField[android.content.Intent.extras].MapValue;value;manual",
"androidx.core.app;NotificationCompat$Builder;true;build;;;Argument[-1];ReturnValue;taint;manual",
"androidx.core.app;NotificationCompat$Builder;true;build;;;Argument[-1].SyntheticField[android.content.Intent.extras];ReturnValue.Field[android.app.Notification.extras];value;manual",
"androidx.core.app;NotificationCompat$Builder;true;setContentIntent;;;Argument[0];Argument[-1];taint;manual",
"androidx.core.app;NotificationCompat$Builder;true;getExtras;;;Argument[-1].SyntheticField[android.content.Intent.extras];ReturnValue;value;manual",
"androidx.core.app;NotificationCompat$Builder;true;setExtras;;;Argument[0];Argument[-1].SyntheticField[android.content.Intent.extras];value;manual",
"androidx.core.app;NotificationCompat$Builder;true;setDeleteIntent;;;Argument[0];Argument[-1];taint;manual",
"androidx.core.app;NotificationCompat$Builder;true;setPublicVersion;;;Argument[0];Argument[-1];taint;manual",
"android.app;Notification$Style;true;build;;;Argument[-1];ReturnValue;taint;manual",
"android.app;Notification$BigPictureStyle;true;BigPictureStyle;(Builder);;Argument[0];Argument[-1];taint;manual",
"android.app;Notification$BigTextStyle;true;BigTextStyle;(Builder);;Argument[0];Argument[-1];taint;manual",
"android.app;Notification$InboxStyle;true;InboxStyle;(Builder);;Argument[0];Argument[-1];taint;manual",
"android.app;Notification$MediaStyle;true;MediaStyle;(Builder);;Argument[0];Argument[-1];taint;manual",
// Fluent models
"android.app;Notification$Action$Builder;true;" +
["android.app;Notification", "androidx.core.app;NotificationCompat"] +
"$Action$Builder;true;" +
[
"addExtras", "addRemoteInput", "extend", "setAllowGeneratedReplies",
"setAuthenticationRequired", "setContextual", "setSemanticAction"
] + ";;;Argument[-1];ReturnValue;value;manual",
"android.app;Notification$Builder;true;" +
["android.app;Notification", "androidx.core.app;NotificationCompat"] + "$Builder;true;" +
[
"addAction", "addExtras", "addPerson", "extend", "setActions", "setAutoCancel",
"setBadgeIconType", "setBubbleMetadata", "setCategory", "setChannelId",
@@ -58,15 +81,16 @@ private class NotificationBuildersSummaryModels extends SummaryModelCsv {
"setSubText", "setTicker", "setTimeoutAfter", "setUsesChronometer", "setVibrate",
"setVisibility", "setWhen"
] + ";;;Argument[-1];ReturnValue;value;manual",
"android.app;Notification$BigPictureStyle;true;" +
["android.app;Notification", "androidx.core.app;NotificationCompat"] +
"$BigPictureStyle;true;" +
[
"bigLargeIcon", "bigPicture", "setBigContentTitle", "setContentDescription",
"setSummaryText", "showBigPictureWhenCollapsed"
] + ";;;Argument[-1];ReturnValue;value;manual",
"android.app;Notification$BigTextStyle;true;" +
["bigText", "setBigContentTitle", "setSummaryText"] +
["android.app;Notification", "androidx.core.app;NotificationCompat"] + "$BigTextStyle;true;"
+ ["bigText", "setBigContentTitle", "setSummaryText"] +
";;;Argument[-1];ReturnValue;value;manual",
"android.app;Notification$InboxStyle;true;" +
["android.app;Notification", "androidx.core.app;NotificationCompat"] + "$InboxStyle;true;" +
["addLine", "setBigContentTitle", "setSummaryText"] +
";;;Argument[-1];ReturnValue;value;manual",
"android.app;Notification$MediaStyle;true;" +

View File

@@ -13,7 +13,9 @@ private class IOGeneratedSinksCsv extends SinkModelCsv {
"org.apache.commons.io.file;PathFilter;true;accept;(Path,BasicFileAttributes);;Argument[0];create-file;generated",
"org.apache.commons.io.file;PathUtils;false;copyFile;(URL,Path,CopyOption[]);;Argument[0];open-url;generated",
"org.apache.commons.io.file;PathUtils;false;copyFile;(URL,Path,CopyOption[]);;Argument[1];create-file;generated",
"org.apache.commons.io.file;PathUtils;false;copyFileToDirectory;(Path,Path,CopyOption[]);;Argument[1];create-file;generated",
"org.apache.commons.io.file;PathUtils;false;copyFileToDirectory;(URL,Path,CopyOption[]);;Argument[0];open-url;generated",
"org.apache.commons.io.file;PathUtils;false;copyFileToDirectory;(URL,Path,CopyOption[]);;Argument[1];create-file;generated",
"org.apache.commons.io.file;PathUtils;false;newOutputStream;(Path,boolean);;Argument[0];create-file;generated",
"org.apache.commons.io.file;PathUtils;false;writeString;(Path,CharSequence,Charset,OpenOption[]);;Argument[0];create-file;generated",
"org.apache.commons.io.filefilter;FileFilterUtils;true;filter;(IOFileFilter,File[]);;Argument[1];create-file;generated",
@@ -631,14 +633,10 @@ private class IOGeneratedSummaryCsv extends SummaryModelCsv {
"org.apache.commons.io;IOUtils;true;readLines;(InputStream,Charset);;Argument[0];ReturnValue;taint;generated",
"org.apache.commons.io;IOUtils;true;readLines;(InputStream,String);;Argument[0];ReturnValue;taint;generated",
"org.apache.commons.io;IOUtils;true;readLines;(Reader);;Argument[0];ReturnValue;taint;generated",
"org.apache.commons.io;IOUtils;true;toBufferedInputStream;(InputStream);;Argument[0];ReturnValue;taint;generated",
"org.apache.commons.io;IOUtils;true;toBufferedInputStream;(InputStream,int);;Argument[0];ReturnValue;taint;generated",
"org.apache.commons.io;IOUtils;true;toBufferedReader;(Reader);;Argument[0];ReturnValue;taint;generated",
"org.apache.commons.io;IOUtils;true;toBufferedReader;(Reader,int);;Argument[0];ReturnValue;taint;generated",
"org.apache.commons.io;IOUtils;true;toByteArray;(InputStream,int);;Argument[0];ReturnValue;taint;generated",
"org.apache.commons.io;IOUtils;true;toByteArray;(InputStream,long);;Argument[0];ReturnValue;taint;generated",
"org.apache.commons.io;IOUtils;true;toByteArray;(Reader);;Argument[0];ReturnValue;taint;generated",
"org.apache.commons.io;IOUtils;true;toByteArray;(Reader,String);;Argument[0];ReturnValue;taint;generated",
"org.apache.commons.io;IOUtils;true;toByteArray;(String);;Argument[0];ReturnValue;taint;generated",
"org.apache.commons.io;IOUtils;true;toCharArray;(InputStream);;Argument[0];ReturnValue;taint;generated",
"org.apache.commons.io;IOUtils;true;toCharArray;(InputStream,Charset);;Argument[0];ReturnValue;taint;generated",
@@ -669,7 +667,6 @@ private class IOGeneratedSummaryCsv extends SummaryModelCsv {
"org.apache.commons.io;IOUtils;true;writeLines;(Collection,String,OutputStream);;Argument[1];Argument[2];taint;generated",
"org.apache.commons.io;IOUtils;true;writeLines;(Collection,String,OutputStream,Charset);;Argument[1];Argument[2];taint;generated",
"org.apache.commons.io;IOUtils;true;writeLines;(Collection,String,OutputStream,String);;Argument[1];Argument[2];taint;generated",
"org.apache.commons.io;IOUtils;true;writeLines;(Collection,String,Writer);;Argument[0].Element;Argument[2];taint;generated",
"org.apache.commons.io;IOUtils;true;writeLines;(Collection,String,Writer);;Argument[1];Argument[2];taint;generated",
"org.apache.commons.io;IOUtils;true;writer;(Appendable);;Argument[0];ReturnValue;taint;generated",
"org.apache.commons.io;LineIterator;true;LineIterator;(Reader);;Argument[0];Argument[-1];taint;generated",

View File

@@ -0,0 +1,769 @@
/**
* THIS FILE IS AN AUTO-GENERATED MODELS AS DATA FILE. DO NOT EDIT.
* Definitions of negative summaries in the IOGenerated framework.
*/
import java
private import semmle.code.java.dataflow.ExternalFlow
private class IOGeneratedNegativesummaryCsv extends NegativeSummaryModelCsv {
override predicate row(string row) {
row =
[
"org.apache.commons.io.charset;CharsetDecoders;CharsetDecoders;();generated",
"org.apache.commons.io.charset;CharsetEncoders;CharsetEncoders;();generated",
"org.apache.commons.io.comparator;DefaultFileComparator;DefaultFileComparator;();generated",
"org.apache.commons.io.comparator;DirectoryFileComparator;DirectoryFileComparator;();generated",
"org.apache.commons.io.comparator;ExtensionFileComparator;ExtensionFileComparator;();generated",
"org.apache.commons.io.comparator;ExtensionFileComparator;ExtensionFileComparator;(IOCase);generated",
"org.apache.commons.io.comparator;ExtensionFileComparator;toString;();generated",
"org.apache.commons.io.comparator;LastModifiedFileComparator;LastModifiedFileComparator;();generated",
"org.apache.commons.io.comparator;NameFileComparator;NameFileComparator;();generated",
"org.apache.commons.io.comparator;NameFileComparator;NameFileComparator;(IOCase);generated",
"org.apache.commons.io.comparator;NameFileComparator;toString;();generated",
"org.apache.commons.io.comparator;PathFileComparator;PathFileComparator;();generated",
"org.apache.commons.io.comparator;PathFileComparator;PathFileComparator;(IOCase);generated",
"org.apache.commons.io.comparator;PathFileComparator;toString;();generated",
"org.apache.commons.io.comparator;SizeFileComparator;SizeFileComparator;();generated",
"org.apache.commons.io.comparator;SizeFileComparator;SizeFileComparator;(boolean);generated",
"org.apache.commons.io.comparator;SizeFileComparator;toString;();generated",
"org.apache.commons.io.file.attribute;FileTimes;minusMillis;(FileTime,long);generated",
"org.apache.commons.io.file.attribute;FileTimes;minusNanos;(FileTime,long);generated",
"org.apache.commons.io.file.attribute;FileTimes;minusSeconds;(FileTime,long);generated",
"org.apache.commons.io.file.attribute;FileTimes;now;();generated",
"org.apache.commons.io.file.attribute;FileTimes;ntfsTimeToDate;(long);generated",
"org.apache.commons.io.file.attribute;FileTimes;ntfsTimeToFileTime;(long);generated",
"org.apache.commons.io.file.attribute;FileTimes;plusMillis;(FileTime,long);generated",
"org.apache.commons.io.file.attribute;FileTimes;plusNanos;(FileTime,long);generated",
"org.apache.commons.io.file.attribute;FileTimes;plusSeconds;(FileTime,long);generated",
"org.apache.commons.io.file.attribute;FileTimes;setLastModifiedTime;(Path);generated",
"org.apache.commons.io.file.attribute;FileTimes;toDate;(FileTime);generated",
"org.apache.commons.io.file.attribute;FileTimes;toFileTime;(Date);generated",
"org.apache.commons.io.file.attribute;FileTimes;toNtfsTime;(Date);generated",
"org.apache.commons.io.file.attribute;FileTimes;toNtfsTime;(FileTime);generated",
"org.apache.commons.io.file.spi;FileSystemProviders;getFileSystemProvider;(Path);generated",
"org.apache.commons.io.file.spi;FileSystemProviders;installed;();generated",
"org.apache.commons.io.file;AccumulatorPathVisitor;AccumulatorPathVisitor;();generated",
"org.apache.commons.io.file;AccumulatorPathVisitor;relativizeDirectories;(Path,boolean,Comparator);generated",
"org.apache.commons.io.file;AccumulatorPathVisitor;relativizeFiles;(Path,boolean,Comparator);generated",
"org.apache.commons.io.file;AccumulatorPathVisitor;withBigIntegerCounters;();generated",
"org.apache.commons.io.file;AccumulatorPathVisitor;withLongCounters;();generated",
"org.apache.commons.io.file;CleaningPathVisitor;withBigIntegerCounters;();generated",
"org.apache.commons.io.file;CleaningPathVisitor;withLongCounters;();generated",
"org.apache.commons.io.file;Counters$Counter;add;(long);generated",
"org.apache.commons.io.file;Counters$Counter;get;();generated",
"org.apache.commons.io.file;Counters$Counter;getBigInteger;();generated",
"org.apache.commons.io.file;Counters$Counter;getLong;();generated",
"org.apache.commons.io.file;Counters$Counter;increment;();generated",
"org.apache.commons.io.file;Counters$Counter;reset;();generated",
"org.apache.commons.io.file;Counters$PathCounters;getByteCounter;();generated",
"org.apache.commons.io.file;Counters$PathCounters;getDirectoryCounter;();generated",
"org.apache.commons.io.file;Counters$PathCounters;getFileCounter;();generated",
"org.apache.commons.io.file;Counters$PathCounters;reset;();generated",
"org.apache.commons.io.file;Counters;Counters;();generated",
"org.apache.commons.io.file;Counters;bigIntegerCounter;();generated",
"org.apache.commons.io.file;Counters;bigIntegerPathCounters;();generated",
"org.apache.commons.io.file;Counters;longCounter;();generated",
"org.apache.commons.io.file;Counters;longPathCounters;();generated",
"org.apache.commons.io.file;Counters;noopCounter;();generated",
"org.apache.commons.io.file;Counters;noopPathCounters;();generated",
"org.apache.commons.io.file;CountingPathVisitor;toString;();generated",
"org.apache.commons.io.file;CountingPathVisitor;withBigIntegerCounters;();generated",
"org.apache.commons.io.file;CountingPathVisitor;withLongCounters;();generated",
"org.apache.commons.io.file;DeletingPathVisitor;withBigIntegerCounters;();generated",
"org.apache.commons.io.file;DeletingPathVisitor;withLongCounters;();generated",
"org.apache.commons.io.file;NoopPathVisitor;NoopPathVisitor;();generated",
"org.apache.commons.io.file;PathFilter;accept;(Path,BasicFileAttributes);generated",
"org.apache.commons.io.file;PathUtils;cleanDirectory;(Path);generated",
"org.apache.commons.io.file;PathUtils;cleanDirectory;(Path,DeleteOption[]);generated",
"org.apache.commons.io.file;PathUtils;copyDirectory;(Path,Path,CopyOption[]);generated",
"org.apache.commons.io.file;PathUtils;copyFileToDirectory;(Path,Path,CopyOption[]);generated",
"org.apache.commons.io.file;PathUtils;countDirectory;(Path);generated",
"org.apache.commons.io.file;PathUtils;countDirectoryAsBigInteger;(Path);generated",
"org.apache.commons.io.file;PathUtils;createParentDirectories;(Path,FileAttribute[]);generated",
"org.apache.commons.io.file;PathUtils;createParentDirectories;(Path,LinkOption,FileAttribute[]);generated",
"org.apache.commons.io.file;PathUtils;current;();generated",
"org.apache.commons.io.file;PathUtils;delete;(Path);generated",
"org.apache.commons.io.file;PathUtils;delete;(Path,DeleteOption[]);generated",
"org.apache.commons.io.file;PathUtils;delete;(Path,LinkOption[],DeleteOption[]);generated",
"org.apache.commons.io.file;PathUtils;deleteDirectory;(Path);generated",
"org.apache.commons.io.file;PathUtils;deleteDirectory;(Path,DeleteOption[]);generated",
"org.apache.commons.io.file;PathUtils;deleteDirectory;(Path,LinkOption[],DeleteOption[]);generated",
"org.apache.commons.io.file;PathUtils;deleteFile;(Path);generated",
"org.apache.commons.io.file;PathUtils;deleteFile;(Path,DeleteOption[]);generated",
"org.apache.commons.io.file;PathUtils;deleteFile;(Path,LinkOption[],DeleteOption[]);generated",
"org.apache.commons.io.file;PathUtils;directoryAndFileContentEquals;(Path,Path);generated",
"org.apache.commons.io.file;PathUtils;directoryAndFileContentEquals;(Path,Path,LinkOption[],OpenOption[],FileVisitOption[]);generated",
"org.apache.commons.io.file;PathUtils;directoryContentEquals;(Path,Path);generated",
"org.apache.commons.io.file;PathUtils;directoryContentEquals;(Path,Path,int,LinkOption[],FileVisitOption[]);generated",
"org.apache.commons.io.file;PathUtils;fileContentEquals;(Path,Path);generated",
"org.apache.commons.io.file;PathUtils;fileContentEquals;(Path,Path,LinkOption[],OpenOption[]);generated",
"org.apache.commons.io.file;PathUtils;filter;(PathFilter,Path[]);generated",
"org.apache.commons.io.file;PathUtils;getAclEntryList;(Path);generated",
"org.apache.commons.io.file;PathUtils;getAclFileAttributeView;(Path,LinkOption[]);generated",
"org.apache.commons.io.file;PathUtils;getDosFileAttributeView;(Path,LinkOption[]);generated",
"org.apache.commons.io.file;PathUtils;getPosixFileAttributeView;(Path,LinkOption[]);generated",
"org.apache.commons.io.file;PathUtils;getTempDirectory;();generated",
"org.apache.commons.io.file;PathUtils;isDirectory;(Path,LinkOption[]);generated",
"org.apache.commons.io.file;PathUtils;isEmpty;(Path);generated",
"org.apache.commons.io.file;PathUtils;isEmptyDirectory;(Path);generated",
"org.apache.commons.io.file;PathUtils;isEmptyFile;(Path);generated",
"org.apache.commons.io.file;PathUtils;isNewer;(Path,ChronoZonedDateTime,LinkOption[]);generated",
"org.apache.commons.io.file;PathUtils;isNewer;(Path,FileTime,LinkOption[]);generated",
"org.apache.commons.io.file;PathUtils;isNewer;(Path,Instant,LinkOption[]);generated",
"org.apache.commons.io.file;PathUtils;isNewer;(Path,Path);generated",
"org.apache.commons.io.file;PathUtils;isNewer;(Path,long,LinkOption[]);generated",
"org.apache.commons.io.file;PathUtils;isOlder;(Path,FileTime,LinkOption[]);generated",
"org.apache.commons.io.file;PathUtils;isOlder;(Path,Instant,LinkOption[]);generated",
"org.apache.commons.io.file;PathUtils;isOlder;(Path,Path);generated",
"org.apache.commons.io.file;PathUtils;isOlder;(Path,long,LinkOption[]);generated",
"org.apache.commons.io.file;PathUtils;isPosix;(Path,LinkOption[]);generated",
"org.apache.commons.io.file;PathUtils;isRegularFile;(Path,LinkOption[]);generated",
"org.apache.commons.io.file;PathUtils;newDirectoryStream;(Path,PathFilter);generated",
"org.apache.commons.io.file;PathUtils;newOutputStream;(Path,boolean);generated",
"org.apache.commons.io.file;PathUtils;noFollowLinkOptionArray;();generated",
"org.apache.commons.io.file;PathUtils;readAttributes;(Path,Class,LinkOption[]);generated",
"org.apache.commons.io.file;PathUtils;readBasicFileAttributes;(Path);generated",
"org.apache.commons.io.file;PathUtils;readBasicFileAttributes;(Path,LinkOption[]);generated",
"org.apache.commons.io.file;PathUtils;readBasicFileAttributesUnchecked;(Path);generated",
"org.apache.commons.io.file;PathUtils;readDosFileAttributes;(Path,LinkOption[]);generated",
"org.apache.commons.io.file;PathUtils;readOsFileAttributes;(Path,LinkOption[]);generated",
"org.apache.commons.io.file;PathUtils;readPosixFileAttributes;(Path,LinkOption[]);generated",
"org.apache.commons.io.file;PathUtils;readString;(Path,Charset);generated",
"org.apache.commons.io.file;PathUtils;setLastModifiedTime;(Path,Path);generated",
"org.apache.commons.io.file;PathUtils;sizeOf;(Path);generated",
"org.apache.commons.io.file;PathUtils;sizeOfAsBigInteger;(Path);generated",
"org.apache.commons.io.file;PathUtils;sizeOfDirectory;(Path);generated",
"org.apache.commons.io.file;PathUtils;sizeOfDirectoryAsBigInteger;(Path);generated",
"org.apache.commons.io.file;PathUtils;waitFor;(Path,Duration,LinkOption[]);generated",
"org.apache.commons.io.file;PathUtils;walk;(Path,PathFilter,int,boolean,FileVisitOption[]);generated",
"org.apache.commons.io.file;StandardDeleteOption;overrideReadOnly;(DeleteOption[]);generated",
"org.apache.commons.io.filefilter;AbstractFileFilter;AbstractFileFilter;();generated",
"org.apache.commons.io.filefilter;AbstractFileFilter;toString;();generated",
"org.apache.commons.io.filefilter;AgeFileFilter;AgeFileFilter;(Date);generated",
"org.apache.commons.io.filefilter;AgeFileFilter;AgeFileFilter;(Date,boolean);generated",
"org.apache.commons.io.filefilter;AgeFileFilter;AgeFileFilter;(File);generated",
"org.apache.commons.io.filefilter;AgeFileFilter;AgeFileFilter;(File,boolean);generated",
"org.apache.commons.io.filefilter;AgeFileFilter;AgeFileFilter;(long);generated",
"org.apache.commons.io.filefilter;AgeFileFilter;AgeFileFilter;(long,boolean);generated",
"org.apache.commons.io.filefilter;AndFileFilter;AndFileFilter;();generated",
"org.apache.commons.io.filefilter;ConditionalFileFilter;addFileFilter;(IOFileFilter);generated",
"org.apache.commons.io.filefilter;ConditionalFileFilter;getFileFilters;();generated",
"org.apache.commons.io.filefilter;ConditionalFileFilter;removeFileFilter;(IOFileFilter);generated",
"org.apache.commons.io.filefilter;ConditionalFileFilter;setFileFilters;(List);generated",
"org.apache.commons.io.filefilter;FalseFileFilter;toString;();generated",
"org.apache.commons.io.filefilter;FileFilterUtils;FileFilterUtils;();generated",
"org.apache.commons.io.filefilter;FileFilterUtils;ageFileFilter;(Date);generated",
"org.apache.commons.io.filefilter;FileFilterUtils;ageFileFilter;(Date,boolean);generated",
"org.apache.commons.io.filefilter;FileFilterUtils;ageFileFilter;(File);generated",
"org.apache.commons.io.filefilter;FileFilterUtils;ageFileFilter;(File,boolean);generated",
"org.apache.commons.io.filefilter;FileFilterUtils;ageFileFilter;(long);generated",
"org.apache.commons.io.filefilter;FileFilterUtils;ageFileFilter;(long,boolean);generated",
"org.apache.commons.io.filefilter;FileFilterUtils;directoryFileFilter;();generated",
"org.apache.commons.io.filefilter;FileFilterUtils;falseFileFilter;();generated",
"org.apache.commons.io.filefilter;FileFilterUtils;fileFileFilter;();generated",
"org.apache.commons.io.filefilter;FileFilterUtils;filter;(IOFileFilter,File[]);generated",
"org.apache.commons.io.filefilter;FileFilterUtils;filter;(IOFileFilter,Iterable);generated",
"org.apache.commons.io.filefilter;FileFilterUtils;filterList;(IOFileFilter,File[]);generated",
"org.apache.commons.io.filefilter;FileFilterUtils;filterList;(IOFileFilter,Iterable);generated",
"org.apache.commons.io.filefilter;FileFilterUtils;filterSet;(IOFileFilter,File[]);generated",
"org.apache.commons.io.filefilter;FileFilterUtils;filterSet;(IOFileFilter,Iterable);generated",
"org.apache.commons.io.filefilter;FileFilterUtils;sizeFileFilter;(long);generated",
"org.apache.commons.io.filefilter;FileFilterUtils;sizeFileFilter;(long,boolean);generated",
"org.apache.commons.io.filefilter;FileFilterUtils;sizeRangeFileFilter;(long,long);generated",
"org.apache.commons.io.filefilter;FileFilterUtils;trueFileFilter;();generated",
"org.apache.commons.io.filefilter;IOFileFilter;and;(IOFileFilter);generated",
"org.apache.commons.io.filefilter;IOFileFilter;negate;();generated",
"org.apache.commons.io.filefilter;IOFileFilter;or;(IOFileFilter);generated",
"org.apache.commons.io.filefilter;OrFileFilter;OrFileFilter;();generated",
"org.apache.commons.io.filefilter;RegexFileFilter;RegexFileFilter;(String);generated",
"org.apache.commons.io.filefilter;RegexFileFilter;RegexFileFilter;(String,IOCase);generated",
"org.apache.commons.io.filefilter;RegexFileFilter;RegexFileFilter;(String,int);generated",
"org.apache.commons.io.filefilter;SizeFileFilter;SizeFileFilter;(long);generated",
"org.apache.commons.io.filefilter;SizeFileFilter;SizeFileFilter;(long,boolean);generated",
"org.apache.commons.io.filefilter;SizeFileFilter;toString;();generated",
"org.apache.commons.io.filefilter;SymbolicLinkFileFilter;SymbolicLinkFileFilter;(FileVisitResult,FileVisitResult);generated",
"org.apache.commons.io.filefilter;TrueFileFilter;toString;();generated",
"org.apache.commons.io.function;IOBiConsumer;accept;(Object,Object);generated",
"org.apache.commons.io.function;IOBiConsumer;andThen;(IOBiConsumer);generated",
"org.apache.commons.io.function;IOBiFunction;andThen;(Function);generated",
"org.apache.commons.io.function;IOBiFunction;andThen;(IOFunction);generated",
"org.apache.commons.io.function;IOBiFunction;apply;(Object,Object);generated",
"org.apache.commons.io.function;IOConsumer;accept;(Object);generated",
"org.apache.commons.io.function;IOConsumer;andThen;(IOConsumer);generated",
"org.apache.commons.io.function;IOConsumer;forEach;(Object[],IOConsumer);generated",
"org.apache.commons.io.function;IOConsumer;forEachIndexed;(Stream,IOConsumer);generated",
"org.apache.commons.io.function;IOConsumer;noop;();generated",
"org.apache.commons.io.function;IOFunction;andThen;(Consumer);generated",
"org.apache.commons.io.function;IOFunction;andThen;(Function);generated",
"org.apache.commons.io.function;IOFunction;andThen;(IOConsumer);generated",
"org.apache.commons.io.function;IOFunction;andThen;(IOFunction);generated",
"org.apache.commons.io.function;IOFunction;apply;(Object);generated",
"org.apache.commons.io.function;IOFunction;compose;(Function);generated",
"org.apache.commons.io.function;IOFunction;compose;(IOFunction);generated",
"org.apache.commons.io.function;IOFunction;compose;(IOSupplier);generated",
"org.apache.commons.io.function;IOFunction;compose;(Supplier);generated",
"org.apache.commons.io.function;IOFunction;identity;();generated",
"org.apache.commons.io.function;IORunnable;run;();generated",
"org.apache.commons.io.function;IOSupplier;get;();generated",
"org.apache.commons.io.function;IOTriFunction;andThen;(Function);generated",
"org.apache.commons.io.function;IOTriFunction;andThen;(IOFunction);generated",
"org.apache.commons.io.function;IOTriFunction;apply;(Object,Object,Object);generated",
"org.apache.commons.io.input.buffer;CircularByteBuffer;CircularByteBuffer;();generated",
"org.apache.commons.io.input.buffer;CircularByteBuffer;CircularByteBuffer;(int);generated",
"org.apache.commons.io.input.buffer;CircularByteBuffer;add;(byte);generated",
"org.apache.commons.io.input.buffer;CircularByteBuffer;add;(byte[],int,int);generated",
"org.apache.commons.io.input.buffer;CircularByteBuffer;clear;();generated",
"org.apache.commons.io.input.buffer;CircularByteBuffer;getCurrentNumberOfBytes;();generated",
"org.apache.commons.io.input.buffer;CircularByteBuffer;getSpace;();generated",
"org.apache.commons.io.input.buffer;CircularByteBuffer;hasBytes;();generated",
"org.apache.commons.io.input.buffer;CircularByteBuffer;hasSpace;();generated",
"org.apache.commons.io.input.buffer;CircularByteBuffer;hasSpace;(int);generated",
"org.apache.commons.io.input.buffer;CircularByteBuffer;peek;(byte[],int,int);generated",
"org.apache.commons.io.input.buffer;CircularByteBuffer;read;();generated",
"org.apache.commons.io.input.buffer;CircularByteBuffer;read;(byte[],int,int);generated",
"org.apache.commons.io.input.buffer;PeekableInputStream;peek;(byte[]);generated",
"org.apache.commons.io.input.buffer;PeekableInputStream;peek;(byte[],int,int);generated",
"org.apache.commons.io.input;AutoCloseInputStream;AutoCloseInputStream;(InputStream);generated",
"org.apache.commons.io.input;BOMInputStream;BOMInputStream;(InputStream);generated",
"org.apache.commons.io.input;BOMInputStream;BOMInputStream;(InputStream,boolean);generated",
"org.apache.commons.io.input;BOMInputStream;hasBOM;();generated",
"org.apache.commons.io.input;BOMInputStream;hasBOM;(ByteOrderMark);generated",
"org.apache.commons.io.input;BoundedInputStream;isPropagateClose;();generated",
"org.apache.commons.io.input;BoundedInputStream;setPropagateClose;(boolean);generated",
"org.apache.commons.io.input;BoundedInputStream;toString;();generated",
"org.apache.commons.io.input;BrokenInputStream;BrokenInputStream;();generated",
"org.apache.commons.io.input;BrokenInputStream;BrokenInputStream;(IOException);generated",
"org.apache.commons.io.input;BrokenReader;BrokenReader;();generated",
"org.apache.commons.io.input;BrokenReader;BrokenReader;(IOException);generated",
"org.apache.commons.io.input;BufferedFileChannelInputStream;BufferedFileChannelInputStream;(File);generated",
"org.apache.commons.io.input;BufferedFileChannelInputStream;BufferedFileChannelInputStream;(File,int);generated",
"org.apache.commons.io.input;BufferedFileChannelInputStream;BufferedFileChannelInputStream;(Path);generated",
"org.apache.commons.io.input;BufferedFileChannelInputStream;BufferedFileChannelInputStream;(Path,int);generated",
"org.apache.commons.io.input;CharSequenceInputStream;CharSequenceInputStream;(CharSequence,Charset);generated",
"org.apache.commons.io.input;CharSequenceInputStream;CharSequenceInputStream;(CharSequence,Charset,int);generated",
"org.apache.commons.io.input;CharSequenceInputStream;CharSequenceInputStream;(CharSequence,String);generated",
"org.apache.commons.io.input;CharSequenceInputStream;CharSequenceInputStream;(CharSequence,String,int);generated",
"org.apache.commons.io.input;CharacterFilterReader;CharacterFilterReader;(Reader,int);generated",
"org.apache.commons.io.input;CharacterSetFilterReader;CharacterSetFilterReader;(Reader,Integer[]);generated",
"org.apache.commons.io.input;CharacterSetFilterReader;CharacterSetFilterReader;(Reader,Set);generated",
"org.apache.commons.io.input;CloseShieldInputStream;CloseShieldInputStream;(InputStream);generated",
"org.apache.commons.io.input;CloseShieldReader;CloseShieldReader;(Reader);generated",
"org.apache.commons.io.input;CloseShieldReader;wrap;(Reader);generated",
"org.apache.commons.io.input;ClosedInputStream;ClosedInputStream;();generated",
"org.apache.commons.io.input;ClosedReader;ClosedReader;();generated",
"org.apache.commons.io.input;CountingInputStream;CountingInputStream;(InputStream);generated",
"org.apache.commons.io.input;CountingInputStream;getByteCount;();generated",
"org.apache.commons.io.input;CountingInputStream;getCount;();generated",
"org.apache.commons.io.input;CountingInputStream;resetByteCount;();generated",
"org.apache.commons.io.input;CountingInputStream;resetCount;();generated",
"org.apache.commons.io.input;DemuxInputStream;DemuxInputStream;();generated",
"org.apache.commons.io.input;DemuxInputStream;bindStream;(InputStream);generated",
"org.apache.commons.io.input;MarkShieldInputStream;MarkShieldInputStream;(InputStream);generated",
"org.apache.commons.io.input;MemoryMappedFileInputStream;MemoryMappedFileInputStream;(Path);generated",
"org.apache.commons.io.input;MemoryMappedFileInputStream;MemoryMappedFileInputStream;(Path,int);generated",
"org.apache.commons.io.input;MessageDigestCalculatingInputStream;MessageDigestCalculatingInputStream;(InputStream);generated",
"org.apache.commons.io.input;MessageDigestCalculatingInputStream;MessageDigestCalculatingInputStream;(InputStream,String);generated",
"org.apache.commons.io.input;NullInputStream;NullInputStream;();generated",
"org.apache.commons.io.input;NullInputStream;NullInputStream;(long);generated",
"org.apache.commons.io.input;NullInputStream;NullInputStream;(long,boolean,boolean);generated",
"org.apache.commons.io.input;NullInputStream;getPosition;();generated",
"org.apache.commons.io.input;NullInputStream;getSize;();generated",
"org.apache.commons.io.input;NullReader;NullReader;();generated",
"org.apache.commons.io.input;NullReader;NullReader;(long);generated",
"org.apache.commons.io.input;NullReader;NullReader;(long,boolean,boolean);generated",
"org.apache.commons.io.input;NullReader;getPosition;();generated",
"org.apache.commons.io.input;NullReader;getSize;();generated",
"org.apache.commons.io.input;ObservableInputStream$Observer;Observer;();generated",
"org.apache.commons.io.input;ObservableInputStream$Observer;closed;();generated",
"org.apache.commons.io.input;ObservableInputStream$Observer;data;(byte[],int,int);generated",
"org.apache.commons.io.input;ObservableInputStream$Observer;data;(int);generated",
"org.apache.commons.io.input;ObservableInputStream$Observer;error;(IOException);generated",
"org.apache.commons.io.input;ObservableInputStream$Observer;finished;();generated",
"org.apache.commons.io.input;ObservableInputStream;ObservableInputStream;(InputStream);generated",
"org.apache.commons.io.input;ObservableInputStream;consume;();generated",
"org.apache.commons.io.input;ObservableInputStream;remove;(Observer);generated",
"org.apache.commons.io.input;ObservableInputStream;removeAllObservers;();generated",
"org.apache.commons.io.input;ProxyInputStream;ProxyInputStream;(InputStream);generated",
"org.apache.commons.io.input;ProxyReader;ProxyReader;(Reader);generated",
"org.apache.commons.io.input;QueueInputStream;QueueInputStream;();generated",
"org.apache.commons.io.input;QueueInputStream;QueueInputStream;(BlockingQueue);generated",
"org.apache.commons.io.input;QueueInputStream;newQueueOutputStream;();generated",
"org.apache.commons.io.input;RandomAccessFileInputStream;availableLong;();generated",
"org.apache.commons.io.input;RandomAccessFileInputStream;isCloseOnClose;();generated",
"org.apache.commons.io.input;ReversedLinesFileReader;ReversedLinesFileReader;(File);generated",
"org.apache.commons.io.input;ReversedLinesFileReader;ReversedLinesFileReader;(File,Charset);generated",
"org.apache.commons.io.input;ReversedLinesFileReader;ReversedLinesFileReader;(File,int,Charset);generated",
"org.apache.commons.io.input;ReversedLinesFileReader;ReversedLinesFileReader;(File,int,String);generated",
"org.apache.commons.io.input;ReversedLinesFileReader;ReversedLinesFileReader;(Path,Charset);generated",
"org.apache.commons.io.input;ReversedLinesFileReader;ReversedLinesFileReader;(Path,int,Charset);generated",
"org.apache.commons.io.input;ReversedLinesFileReader;ReversedLinesFileReader;(Path,int,String);generated",
"org.apache.commons.io.input;SwappedDataInputStream;SwappedDataInputStream;(InputStream);generated",
"org.apache.commons.io.input;TaggedInputStream;TaggedInputStream;(InputStream);generated",
"org.apache.commons.io.input;TaggedInputStream;isCauseOf;(Throwable);generated",
"org.apache.commons.io.input;TaggedInputStream;throwIfCauseOf;(Throwable);generated",
"org.apache.commons.io.input;TaggedReader;TaggedReader;(Reader);generated",
"org.apache.commons.io.input;TaggedReader;isCauseOf;(Throwable);generated",
"org.apache.commons.io.input;TaggedReader;throwIfCauseOf;(Throwable);generated",
"org.apache.commons.io.input;Tailer$RandomAccessResourceBridge;getPointer;();generated",
"org.apache.commons.io.input;Tailer$RandomAccessResourceBridge;read;(byte[]);generated",
"org.apache.commons.io.input;Tailer$RandomAccessResourceBridge;seek;(long);generated",
"org.apache.commons.io.input;Tailer$Tailable;getRandomAccess;(String);generated",
"org.apache.commons.io.input;Tailer$Tailable;isNewer;(FileTime);generated",
"org.apache.commons.io.input;Tailer$Tailable;lastModifiedFileTime;();generated",
"org.apache.commons.io.input;Tailer$Tailable;size;();generated",
"org.apache.commons.io.input;Tailer;getDelay;();generated",
"org.apache.commons.io.input;Tailer;stop;();generated",
"org.apache.commons.io.input;TailerListener;fileNotFound;();generated",
"org.apache.commons.io.input;TailerListener;fileRotated;();generated",
"org.apache.commons.io.input;TailerListener;handle;(Exception);generated",
"org.apache.commons.io.input;TailerListener;handle;(String);generated",
"org.apache.commons.io.input;TailerListener;init;(Tailer);generated",
"org.apache.commons.io.input;TailerListenerAdapter;TailerListenerAdapter;();generated",
"org.apache.commons.io.input;TailerListenerAdapter;endOfFileReached;();generated",
"org.apache.commons.io.input;TimestampedObserver;TimestampedObserver;();generated",
"org.apache.commons.io.input;TimestampedObserver;getOpenToCloseDuration;();generated",
"org.apache.commons.io.input;TimestampedObserver;getOpenToNowDuration;();generated",
"org.apache.commons.io.input;UncheckedFilterInputStream;UncheckedFilterInputStream;(InputStream);generated",
"org.apache.commons.io.input;UncheckedFilterReader;UncheckedFilterReader;(Reader);generated",
"org.apache.commons.io.input;UncheckedFilterReader;on;(Reader);generated",
"org.apache.commons.io.input;XmlStreamReader;XmlStreamReader;(File);generated",
"org.apache.commons.io.input;XmlStreamReader;XmlStreamReader;(Path);generated",
"org.apache.commons.io.input;XmlStreamReader;XmlStreamReader;(URL);generated",
"org.apache.commons.io.monitor;FileAlterationListener;onDirectoryChange;(File);generated",
"org.apache.commons.io.monitor;FileAlterationListener;onDirectoryCreate;(File);generated",
"org.apache.commons.io.monitor;FileAlterationListener;onDirectoryDelete;(File);generated",
"org.apache.commons.io.monitor;FileAlterationListener;onFileChange;(File);generated",
"org.apache.commons.io.monitor;FileAlterationListener;onFileCreate;(File);generated",
"org.apache.commons.io.monitor;FileAlterationListener;onFileDelete;(File);generated",
"org.apache.commons.io.monitor;FileAlterationListener;onStart;(FileAlterationObserver);generated",
"org.apache.commons.io.monitor;FileAlterationListener;onStop;(FileAlterationObserver);generated",
"org.apache.commons.io.monitor;FileAlterationListenerAdaptor;FileAlterationListenerAdaptor;();generated",
"org.apache.commons.io.monitor;FileAlterationMonitor;FileAlterationMonitor;();generated",
"org.apache.commons.io.monitor;FileAlterationMonitor;FileAlterationMonitor;(long);generated",
"org.apache.commons.io.monitor;FileAlterationMonitor;getInterval;();generated",
"org.apache.commons.io.monitor;FileAlterationMonitor;removeObserver;(FileAlterationObserver);generated",
"org.apache.commons.io.monitor;FileAlterationMonitor;start;();generated",
"org.apache.commons.io.monitor;FileAlterationMonitor;stop;();generated",
"org.apache.commons.io.monitor;FileAlterationMonitor;stop;(long);generated",
"org.apache.commons.io.monitor;FileAlterationObserver;checkAndNotify;();generated",
"org.apache.commons.io.monitor;FileAlterationObserver;destroy;();generated",
"org.apache.commons.io.monitor;FileAlterationObserver;initialize;();generated",
"org.apache.commons.io.monitor;FileAlterationObserver;removeListener;(FileAlterationListener);generated",
"org.apache.commons.io.monitor;FileEntry;getLastModified;();generated",
"org.apache.commons.io.monitor;FileEntry;getLength;();generated",
"org.apache.commons.io.monitor;FileEntry;getLevel;();generated",
"org.apache.commons.io.monitor;FileEntry;isDirectory;();generated",
"org.apache.commons.io.monitor;FileEntry;isExists;();generated",
"org.apache.commons.io.monitor;FileEntry;refresh;(File);generated",
"org.apache.commons.io.monitor;FileEntry;setDirectory;(boolean);generated",
"org.apache.commons.io.monitor;FileEntry;setExists;(boolean);generated",
"org.apache.commons.io.monitor;FileEntry;setLastModified;(long);generated",
"org.apache.commons.io.monitor;FileEntry;setLength;(long);generated",
"org.apache.commons.io.output;AbstractByteArrayOutputStream;AbstractByteArrayOutputStream;();generated",
"org.apache.commons.io.output;AbstractByteArrayOutputStream;reset;();generated",
"org.apache.commons.io.output;AbstractByteArrayOutputStream;size;();generated",
"org.apache.commons.io.output;AbstractByteArrayOutputStream;toByteArray;();generated",
"org.apache.commons.io.output;AbstractByteArrayOutputStream;toInputStream;();generated",
"org.apache.commons.io.output;AbstractByteArrayOutputStream;write;(InputStream);generated",
"org.apache.commons.io.output;AbstractByteArrayOutputStream;writeTo;(OutputStream);generated",
"org.apache.commons.io.output;BrokenOutputStream;BrokenOutputStream;();generated",
"org.apache.commons.io.output;BrokenOutputStream;BrokenOutputStream;(IOException);generated",
"org.apache.commons.io.output;BrokenWriter;BrokenWriter;();generated",
"org.apache.commons.io.output;BrokenWriter;BrokenWriter;(IOException);generated",
"org.apache.commons.io.output;ByteArrayOutputStream;ByteArrayOutputStream;();generated",
"org.apache.commons.io.output;ByteArrayOutputStream;ByteArrayOutputStream;(int);generated",
"org.apache.commons.io.output;ByteArrayOutputStream;toBufferedInputStream;(InputStream);generated",
"org.apache.commons.io.output;ByteArrayOutputStream;toBufferedInputStream;(InputStream,int);generated",
"org.apache.commons.io.output;ChunkedWriter;ChunkedWriter;(Writer);generated",
"org.apache.commons.io.output;ChunkedWriter;ChunkedWriter;(Writer,int);generated",
"org.apache.commons.io.output;CloseShieldWriter;CloseShieldWriter;(Writer);generated",
"org.apache.commons.io.output;CloseShieldWriter;wrap;(Writer);generated",
"org.apache.commons.io.output;ClosedOutputStream;ClosedOutputStream;();generated",
"org.apache.commons.io.output;ClosedWriter;ClosedWriter;();generated",
"org.apache.commons.io.output;CountingOutputStream;getByteCount;();generated",
"org.apache.commons.io.output;CountingOutputStream;getCount;();generated",
"org.apache.commons.io.output;CountingOutputStream;resetByteCount;();generated",
"org.apache.commons.io.output;CountingOutputStream;resetCount;();generated",
"org.apache.commons.io.output;DeferredFileOutputStream;isInMemory;();generated",
"org.apache.commons.io.output;DeferredFileOutputStream;toInputStream;();generated",
"org.apache.commons.io.output;DemuxOutputStream;DemuxOutputStream;();generated",
"org.apache.commons.io.output;DemuxOutputStream;bindStream;(OutputStream);generated",
"org.apache.commons.io.output;FileWriterWithEncoding;FileWriterWithEncoding;(File,Charset);generated",
"org.apache.commons.io.output;FileWriterWithEncoding;FileWriterWithEncoding;(File,Charset,boolean);generated",
"org.apache.commons.io.output;FileWriterWithEncoding;FileWriterWithEncoding;(File,CharsetEncoder);generated",
"org.apache.commons.io.output;FileWriterWithEncoding;FileWriterWithEncoding;(File,CharsetEncoder,boolean);generated",
"org.apache.commons.io.output;FileWriterWithEncoding;FileWriterWithEncoding;(File,String);generated",
"org.apache.commons.io.output;FileWriterWithEncoding;FileWriterWithEncoding;(File,String,boolean);generated",
"org.apache.commons.io.output;FileWriterWithEncoding;FileWriterWithEncoding;(String,Charset);generated",
"org.apache.commons.io.output;FileWriterWithEncoding;FileWriterWithEncoding;(String,Charset,boolean);generated",
"org.apache.commons.io.output;FileWriterWithEncoding;FileWriterWithEncoding;(String,CharsetEncoder);generated",
"org.apache.commons.io.output;FileWriterWithEncoding;FileWriterWithEncoding;(String,CharsetEncoder,boolean);generated",
"org.apache.commons.io.output;FileWriterWithEncoding;FileWriterWithEncoding;(String,String);generated",
"org.apache.commons.io.output;FileWriterWithEncoding;FileWriterWithEncoding;(String,String,boolean);generated",
"org.apache.commons.io.output;LockableFileWriter;LockableFileWriter;(File);generated",
"org.apache.commons.io.output;LockableFileWriter;LockableFileWriter;(File,Charset);generated",
"org.apache.commons.io.output;LockableFileWriter;LockableFileWriter;(File,String);generated",
"org.apache.commons.io.output;LockableFileWriter;LockableFileWriter;(File,boolean);generated",
"org.apache.commons.io.output;LockableFileWriter;LockableFileWriter;(String);generated",
"org.apache.commons.io.output;LockableFileWriter;LockableFileWriter;(String,boolean);generated",
"org.apache.commons.io.output;NullOutputStream;NullOutputStream;();generated",
"org.apache.commons.io.output;NullPrintStream;NullPrintStream;();generated",
"org.apache.commons.io.output;NullWriter;NullWriter;();generated",
"org.apache.commons.io.output;ProxyWriter;ProxyWriter;(Writer);generated",
"org.apache.commons.io.output;QueueOutputStream;QueueOutputStream;();generated",
"org.apache.commons.io.output;QueueOutputStream;QueueOutputStream;(BlockingQueue);generated",
"org.apache.commons.io.output;QueueOutputStream;newQueueInputStream;();generated",
"org.apache.commons.io.output;StringBuilderWriter;StringBuilderWriter;();generated",
"org.apache.commons.io.output;StringBuilderWriter;StringBuilderWriter;(int);generated",
"org.apache.commons.io.output;TaggedOutputStream;isCauseOf;(Exception);generated",
"org.apache.commons.io.output;TaggedOutputStream;throwIfCauseOf;(Exception);generated",
"org.apache.commons.io.output;TaggedWriter;TaggedWriter;(Writer);generated",
"org.apache.commons.io.output;TaggedWriter;isCauseOf;(Exception);generated",
"org.apache.commons.io.output;TaggedWriter;throwIfCauseOf;(Exception);generated",
"org.apache.commons.io.output;ThresholdingOutputStream;ThresholdingOutputStream;(int);generated",
"org.apache.commons.io.output;ThresholdingOutputStream;getByteCount;();generated",
"org.apache.commons.io.output;ThresholdingOutputStream;getThreshold;();generated",
"org.apache.commons.io.output;ThresholdingOutputStream;isThresholdExceeded;();generated",
"org.apache.commons.io.output;UncheckedFilterWriter;on;(Writer);generated",
"org.apache.commons.io.output;UnsynchronizedByteArrayOutputStream;UnsynchronizedByteArrayOutputStream;();generated",
"org.apache.commons.io.output;UnsynchronizedByteArrayOutputStream;UnsynchronizedByteArrayOutputStream;(int);generated",
"org.apache.commons.io.output;UnsynchronizedByteArrayOutputStream;toBufferedInputStream;(InputStream);generated",
"org.apache.commons.io.output;UnsynchronizedByteArrayOutputStream;toBufferedInputStream;(InputStream,int);generated",
"org.apache.commons.io.output;XmlStreamWriter;XmlStreamWriter;(File);generated",
"org.apache.commons.io.serialization;ClassNameMatcher;matches;(String);generated",
"org.apache.commons.io;ByteOrderMark;get;(int);generated",
"org.apache.commons.io;ByteOrderMark;getBytes;();generated",
"org.apache.commons.io;ByteOrderMark;length;();generated",
"org.apache.commons.io;ByteOrderParser;parseByteOrder;(String);generated",
"org.apache.commons.io;Charsets;Charsets;();generated",
"org.apache.commons.io;Charsets;requiredCharsets;();generated",
"org.apache.commons.io;Charsets;toCharset;(Charset);generated",
"org.apache.commons.io;Charsets;toCharset;(String);generated",
"org.apache.commons.io;CopyUtils;CopyUtils;();generated",
"org.apache.commons.io;CopyUtils;copy;(Reader,OutputStream);generated",
"org.apache.commons.io;CopyUtils;copy;(Reader,OutputStream,String);generated",
"org.apache.commons.io;CopyUtils;copy;(String,OutputStream);generated",
"org.apache.commons.io;CopyUtils;copy;(String,OutputStream,String);generated",
"org.apache.commons.io;DirectoryWalker$CancelException;getDepth;();generated",
"org.apache.commons.io;EndianUtils;EndianUtils;();generated",
"org.apache.commons.io;EndianUtils;readSwappedDouble;(InputStream);generated",
"org.apache.commons.io;EndianUtils;readSwappedDouble;(byte[],int);generated",
"org.apache.commons.io;EndianUtils;readSwappedFloat;(InputStream);generated",
"org.apache.commons.io;EndianUtils;readSwappedFloat;(byte[],int);generated",
"org.apache.commons.io;EndianUtils;readSwappedInteger;(InputStream);generated",
"org.apache.commons.io;EndianUtils;readSwappedInteger;(byte[],int);generated",
"org.apache.commons.io;EndianUtils;readSwappedLong;(InputStream);generated",
"org.apache.commons.io;EndianUtils;readSwappedLong;(byte[],int);generated",
"org.apache.commons.io;EndianUtils;readSwappedShort;(InputStream);generated",
"org.apache.commons.io;EndianUtils;readSwappedShort;(byte[],int);generated",
"org.apache.commons.io;EndianUtils;readSwappedUnsignedInteger;(InputStream);generated",
"org.apache.commons.io;EndianUtils;readSwappedUnsignedInteger;(byte[],int);generated",
"org.apache.commons.io;EndianUtils;readSwappedUnsignedShort;(InputStream);generated",
"org.apache.commons.io;EndianUtils;readSwappedUnsignedShort;(byte[],int);generated",
"org.apache.commons.io;EndianUtils;swapDouble;(double);generated",
"org.apache.commons.io;EndianUtils;swapFloat;(float);generated",
"org.apache.commons.io;EndianUtils;swapInteger;(int);generated",
"org.apache.commons.io;EndianUtils;swapLong;(long);generated",
"org.apache.commons.io;EndianUtils;swapShort;(short);generated",
"org.apache.commons.io;EndianUtils;writeSwappedDouble;(OutputStream,double);generated",
"org.apache.commons.io;EndianUtils;writeSwappedDouble;(byte[],int,double);generated",
"org.apache.commons.io;EndianUtils;writeSwappedFloat;(OutputStream,float);generated",
"org.apache.commons.io;EndianUtils;writeSwappedFloat;(byte[],int,float);generated",
"org.apache.commons.io;EndianUtils;writeSwappedInteger;(OutputStream,int);generated",
"org.apache.commons.io;EndianUtils;writeSwappedInteger;(byte[],int,int);generated",
"org.apache.commons.io;EndianUtils;writeSwappedLong;(OutputStream,long);generated",
"org.apache.commons.io;EndianUtils;writeSwappedLong;(byte[],int,long);generated",
"org.apache.commons.io;EndianUtils;writeSwappedShort;(OutputStream,short);generated",
"org.apache.commons.io;EndianUtils;writeSwappedShort;(byte[],int,short);generated",
"org.apache.commons.io;FileCleaner;FileCleaner;();generated",
"org.apache.commons.io;FileCleaner;exitWhenFinished;();generated",
"org.apache.commons.io;FileCleaner;getInstance;();generated",
"org.apache.commons.io;FileCleaner;getTrackCount;();generated",
"org.apache.commons.io;FileCleaner;track;(File,Object);generated",
"org.apache.commons.io;FileCleaner;track;(File,Object,FileDeleteStrategy);generated",
"org.apache.commons.io;FileCleaner;track;(String,Object);generated",
"org.apache.commons.io;FileCleaner;track;(String,Object,FileDeleteStrategy);generated",
"org.apache.commons.io;FileCleaningTracker;FileCleaningTracker;();generated",
"org.apache.commons.io;FileCleaningTracker;exitWhenFinished;();generated",
"org.apache.commons.io;FileCleaningTracker;getTrackCount;();generated",
"org.apache.commons.io;FileCleaningTracker;track;(File,Object);generated",
"org.apache.commons.io;FileCleaningTracker;track;(File,Object,FileDeleteStrategy);generated",
"org.apache.commons.io;FileCleaningTracker;track;(String,Object);generated",
"org.apache.commons.io;FileCleaningTracker;track;(String,Object,FileDeleteStrategy);generated",
"org.apache.commons.io;FileDeleteStrategy;delete;(File);generated",
"org.apache.commons.io;FileDeleteStrategy;deleteQuietly;(File);generated",
"org.apache.commons.io;FileExistsException;FileExistsException;();generated",
"org.apache.commons.io;FileExistsException;FileExistsException;(File);generated",
"org.apache.commons.io;FileExistsException;FileExistsException;(String);generated",
"org.apache.commons.io;FileSystem;getCurrent;();generated",
"org.apache.commons.io;FileSystem;getIllegalFileNameChars;();generated",
"org.apache.commons.io;FileSystem;getMaxFileNameLength;();generated",
"org.apache.commons.io;FileSystem;getMaxPathLength;();generated",
"org.apache.commons.io;FileSystem;getNameSeparator;();generated",
"org.apache.commons.io;FileSystem;getReservedFileNames;();generated",
"org.apache.commons.io;FileSystem;isCasePreserving;();generated",
"org.apache.commons.io;FileSystem;isCaseSensitive;();generated",
"org.apache.commons.io;FileSystem;isLegalFileName;(CharSequence);generated",
"org.apache.commons.io;FileSystem;isReservedFileName;(CharSequence);generated",
"org.apache.commons.io;FileSystem;normalizeSeparators;(String);generated",
"org.apache.commons.io;FileSystem;supportsDriveLetter;();generated",
"org.apache.commons.io;FileSystemUtils;FileSystemUtils;();generated",
"org.apache.commons.io;FileSystemUtils;freeSpace;(String);generated",
"org.apache.commons.io;FileSystemUtils;freeSpaceKb;();generated",
"org.apache.commons.io;FileSystemUtils;freeSpaceKb;(String);generated",
"org.apache.commons.io;FileSystemUtils;freeSpaceKb;(String,long);generated",
"org.apache.commons.io;FileSystemUtils;freeSpaceKb;(long);generated",
"org.apache.commons.io;FileUtils;FileUtils;();generated",
"org.apache.commons.io;FileUtils;byteCountToDisplaySize;(BigInteger);generated",
"org.apache.commons.io;FileUtils;byteCountToDisplaySize;(Number);generated",
"org.apache.commons.io;FileUtils;byteCountToDisplaySize;(long);generated",
"org.apache.commons.io;FileUtils;checksumCRC32;(File);generated",
"org.apache.commons.io;FileUtils;cleanDirectory;(File);generated",
"org.apache.commons.io;FileUtils;contentEquals;(File,File);generated",
"org.apache.commons.io;FileUtils;contentEqualsIgnoreEOL;(File,File,String);generated",
"org.apache.commons.io;FileUtils;copyDirectory;(File,File);generated",
"org.apache.commons.io;FileUtils;copyDirectory;(File,File,FileFilter);generated",
"org.apache.commons.io;FileUtils;copyDirectory;(File,File,FileFilter,boolean);generated",
"org.apache.commons.io;FileUtils;copyDirectory;(File,File,FileFilter,boolean,CopyOption[]);generated",
"org.apache.commons.io;FileUtils;copyDirectory;(File,File,boolean);generated",
"org.apache.commons.io;FileUtils;copyDirectoryToDirectory;(File,File);generated",
"org.apache.commons.io;FileUtils;copyFile;(File,File);generated",
"org.apache.commons.io;FileUtils;copyFile;(File,File,CopyOption[]);generated",
"org.apache.commons.io;FileUtils;copyFile;(File,File,boolean);generated",
"org.apache.commons.io;FileUtils;copyFile;(File,File,boolean,CopyOption[]);generated",
"org.apache.commons.io;FileUtils;copyFile;(File,OutputStream);generated",
"org.apache.commons.io;FileUtils;copyFileToDirectory;(File,File);generated",
"org.apache.commons.io;FileUtils;copyFileToDirectory;(File,File,boolean);generated",
"org.apache.commons.io;FileUtils;copyInputStreamToFile;(InputStream,File);generated",
"org.apache.commons.io;FileUtils;copyToDirectory;(File,File);generated",
"org.apache.commons.io;FileUtils;copyToDirectory;(Iterable,File);generated",
"org.apache.commons.io;FileUtils;copyToFile;(InputStream,File);generated",
"org.apache.commons.io;FileUtils;copyURLToFile;(URL,File);generated",
"org.apache.commons.io;FileUtils;copyURLToFile;(URL,File,int,int);generated",
"org.apache.commons.io;FileUtils;createParentDirectories;(File);generated",
"org.apache.commons.io;FileUtils;current;();generated",
"org.apache.commons.io;FileUtils;deleteDirectory;(File);generated",
"org.apache.commons.io;FileUtils;deleteQuietly;(File);generated",
"org.apache.commons.io;FileUtils;directoryContains;(File,File);generated",
"org.apache.commons.io;FileUtils;forceDelete;(File);generated",
"org.apache.commons.io;FileUtils;forceDeleteOnExit;(File);generated",
"org.apache.commons.io;FileUtils;forceMkdir;(File);generated",
"org.apache.commons.io;FileUtils;forceMkdirParent;(File);generated",
"org.apache.commons.io;FileUtils;getTempDirectory;();generated",
"org.apache.commons.io;FileUtils;getTempDirectoryPath;();generated",
"org.apache.commons.io;FileUtils;getUserDirectory;();generated",
"org.apache.commons.io;FileUtils;getUserDirectoryPath;();generated",
"org.apache.commons.io;FileUtils;isDirectory;(File,LinkOption[]);generated",
"org.apache.commons.io;FileUtils;isEmptyDirectory;(File);generated",
"org.apache.commons.io;FileUtils;isFileNewer;(File,ChronoLocalDate);generated",
"org.apache.commons.io;FileUtils;isFileNewer;(File,ChronoLocalDate,LocalTime);generated",
"org.apache.commons.io;FileUtils;isFileNewer;(File,ChronoLocalDateTime);generated",
"org.apache.commons.io;FileUtils;isFileNewer;(File,ChronoLocalDateTime,ZoneId);generated",
"org.apache.commons.io;FileUtils;isFileNewer;(File,ChronoZonedDateTime);generated",
"org.apache.commons.io;FileUtils;isFileNewer;(File,Date);generated",
"org.apache.commons.io;FileUtils;isFileNewer;(File,File);generated",
"org.apache.commons.io;FileUtils;isFileNewer;(File,FileTime);generated",
"org.apache.commons.io;FileUtils;isFileNewer;(File,Instant);generated",
"org.apache.commons.io;FileUtils;isFileNewer;(File,long);generated",
"org.apache.commons.io;FileUtils;isFileOlder;(File,ChronoLocalDate);generated",
"org.apache.commons.io;FileUtils;isFileOlder;(File,ChronoLocalDate,LocalTime);generated",
"org.apache.commons.io;FileUtils;isFileOlder;(File,ChronoLocalDateTime);generated",
"org.apache.commons.io;FileUtils;isFileOlder;(File,ChronoLocalDateTime,ZoneId);generated",
"org.apache.commons.io;FileUtils;isFileOlder;(File,ChronoZonedDateTime);generated",
"org.apache.commons.io;FileUtils;isFileOlder;(File,Date);generated",
"org.apache.commons.io;FileUtils;isFileOlder;(File,File);generated",
"org.apache.commons.io;FileUtils;isFileOlder;(File,FileTime);generated",
"org.apache.commons.io;FileUtils;isFileOlder;(File,Instant);generated",
"org.apache.commons.io;FileUtils;isFileOlder;(File,long);generated",
"org.apache.commons.io;FileUtils;isRegularFile;(File,LinkOption[]);generated",
"org.apache.commons.io;FileUtils;isSymlink;(File);generated",
"org.apache.commons.io;FileUtils;iterateFiles;(File,IOFileFilter,IOFileFilter);generated",
"org.apache.commons.io;FileUtils;iterateFiles;(File,String[],boolean);generated",
"org.apache.commons.io;FileUtils;iterateFilesAndDirs;(File,IOFileFilter,IOFileFilter);generated",
"org.apache.commons.io;FileUtils;lastModified;(File);generated",
"org.apache.commons.io;FileUtils;lastModifiedFileTime;(File);generated",
"org.apache.commons.io;FileUtils;lastModifiedUnchecked;(File);generated",
"org.apache.commons.io;FileUtils;lineIterator;(File);generated",
"org.apache.commons.io;FileUtils;lineIterator;(File,String);generated",
"org.apache.commons.io;FileUtils;listFiles;(File,IOFileFilter,IOFileFilter);generated",
"org.apache.commons.io;FileUtils;listFiles;(File,String[],boolean);generated",
"org.apache.commons.io;FileUtils;listFilesAndDirs;(File,IOFileFilter,IOFileFilter);generated",
"org.apache.commons.io;FileUtils;moveDirectory;(File,File);generated",
"org.apache.commons.io;FileUtils;moveDirectoryToDirectory;(File,File,boolean);generated",
"org.apache.commons.io;FileUtils;moveFile;(File,File);generated",
"org.apache.commons.io;FileUtils;moveFile;(File,File,CopyOption[]);generated",
"org.apache.commons.io;FileUtils;moveFileToDirectory;(File,File,boolean);generated",
"org.apache.commons.io;FileUtils;moveToDirectory;(File,File,boolean);generated",
"org.apache.commons.io;FileUtils;newOutputStream;(File,boolean);generated",
"org.apache.commons.io;FileUtils;openInputStream;(File);generated",
"org.apache.commons.io;FileUtils;openOutputStream;(File);generated",
"org.apache.commons.io;FileUtils;openOutputStream;(File,boolean);generated",
"org.apache.commons.io;FileUtils;readFileToByteArray;(File);generated",
"org.apache.commons.io;FileUtils;readFileToString;(File);generated",
"org.apache.commons.io;FileUtils;readFileToString;(File,Charset);generated",
"org.apache.commons.io;FileUtils;readFileToString;(File,String);generated",
"org.apache.commons.io;FileUtils;readLines;(File);generated",
"org.apache.commons.io;FileUtils;readLines;(File,Charset);generated",
"org.apache.commons.io;FileUtils;readLines;(File,String);generated",
"org.apache.commons.io;FileUtils;sizeOf;(File);generated",
"org.apache.commons.io;FileUtils;sizeOfAsBigInteger;(File);generated",
"org.apache.commons.io;FileUtils;sizeOfDirectory;(File);generated",
"org.apache.commons.io;FileUtils;sizeOfDirectoryAsBigInteger;(File);generated",
"org.apache.commons.io;FileUtils;streamFiles;(File,boolean,String[]);generated",
"org.apache.commons.io;FileUtils;toFile;(URL);generated",
"org.apache.commons.io;FileUtils;toFiles;(URL[]);generated",
"org.apache.commons.io;FileUtils;touch;(File);generated",
"org.apache.commons.io;FileUtils;waitFor;(File,int);generated",
"org.apache.commons.io;FileUtils;write;(File,CharSequence);generated",
"org.apache.commons.io;FileUtils;write;(File,CharSequence,Charset);generated",
"org.apache.commons.io;FileUtils;write;(File,CharSequence,Charset,boolean);generated",
"org.apache.commons.io;FileUtils;write;(File,CharSequence,String);generated",
"org.apache.commons.io;FileUtils;write;(File,CharSequence,String,boolean);generated",
"org.apache.commons.io;FileUtils;write;(File,CharSequence,boolean);generated",
"org.apache.commons.io;FileUtils;writeByteArrayToFile;(File,byte[]);generated",
"org.apache.commons.io;FileUtils;writeByteArrayToFile;(File,byte[],boolean);generated",
"org.apache.commons.io;FileUtils;writeByteArrayToFile;(File,byte[],int,int);generated",
"org.apache.commons.io;FileUtils;writeByteArrayToFile;(File,byte[],int,int,boolean);generated",
"org.apache.commons.io;FileUtils;writeLines;(File,Collection);generated",
"org.apache.commons.io;FileUtils;writeLines;(File,Collection,String);generated",
"org.apache.commons.io;FileUtils;writeLines;(File,Collection,String,boolean);generated",
"org.apache.commons.io;FileUtils;writeLines;(File,Collection,boolean);generated",
"org.apache.commons.io;FileUtils;writeLines;(File,String,Collection);generated",
"org.apache.commons.io;FileUtils;writeLines;(File,String,Collection,String);generated",
"org.apache.commons.io;FileUtils;writeLines;(File,String,Collection,String,boolean);generated",
"org.apache.commons.io;FileUtils;writeLines;(File,String,Collection,boolean);generated",
"org.apache.commons.io;FileUtils;writeStringToFile;(File,String);generated",
"org.apache.commons.io;FileUtils;writeStringToFile;(File,String,Charset);generated",
"org.apache.commons.io;FileUtils;writeStringToFile;(File,String,Charset,boolean);generated",
"org.apache.commons.io;FileUtils;writeStringToFile;(File,String,String);generated",
"org.apache.commons.io;FileUtils;writeStringToFile;(File,String,String,boolean);generated",
"org.apache.commons.io;FileUtils;writeStringToFile;(File,String,boolean);generated",
"org.apache.commons.io;FilenameUtils;FilenameUtils;();generated",
"org.apache.commons.io;FilenameUtils;directoryContains;(String,String);generated",
"org.apache.commons.io;FilenameUtils;equals;(String,String);generated",
"org.apache.commons.io;FilenameUtils;equals;(String,String,boolean,IOCase);generated",
"org.apache.commons.io;FilenameUtils;equalsNormalized;(String,String);generated",
"org.apache.commons.io;FilenameUtils;equalsNormalizedOnSystem;(String,String);generated",
"org.apache.commons.io;FilenameUtils;equalsOnSystem;(String,String);generated",
"org.apache.commons.io;FilenameUtils;getPrefixLength;(String);generated",
"org.apache.commons.io;FilenameUtils;indexOfExtension;(String);generated",
"org.apache.commons.io;FilenameUtils;indexOfLastSeparator;(String);generated",
"org.apache.commons.io;FilenameUtils;isExtension;(String,Collection);generated",
"org.apache.commons.io;FilenameUtils;isExtension;(String,String);generated",
"org.apache.commons.io;FilenameUtils;isExtension;(String,String[]);generated",
"org.apache.commons.io;FilenameUtils;separatorsToSystem;(String);generated",
"org.apache.commons.io;FilenameUtils;separatorsToUnix;(String);generated",
"org.apache.commons.io;FilenameUtils;separatorsToWindows;(String);generated",
"org.apache.commons.io;FilenameUtils;wildcardMatch;(String,String);generated",
"org.apache.commons.io;FilenameUtils;wildcardMatch;(String,String,IOCase);generated",
"org.apache.commons.io;FilenameUtils;wildcardMatchOnSystem;(String,String);generated",
"org.apache.commons.io;HexDump;HexDump;();generated",
"org.apache.commons.io;HexDump;dump;(byte[],long,OutputStream,int);generated",
"org.apache.commons.io;IOCase;checkCompareTo;(String,String);generated",
"org.apache.commons.io;IOCase;checkEndsWith;(String,String);generated",
"org.apache.commons.io;IOCase;checkEquals;(String,String);generated",
"org.apache.commons.io;IOCase;checkIndexOf;(String,int,String);generated",
"org.apache.commons.io;IOCase;checkRegionMatches;(String,int,String);generated",
"org.apache.commons.io;IOCase;checkStartsWith;(String,String);generated",
"org.apache.commons.io;IOCase;forName;(String);generated",
"org.apache.commons.io;IOCase;getName;();generated",
"org.apache.commons.io;IOCase;isCaseSensitive;();generated",
"org.apache.commons.io;IOCase;isCaseSensitive;(IOCase);generated",
"org.apache.commons.io;IOCase;toString;();generated",
"org.apache.commons.io;IOCase;value;(IOCase,IOCase);generated",
"org.apache.commons.io;IOExceptionList;checkEmpty;(List,Object);generated",
"org.apache.commons.io;IOExceptionList;getCause;(int,Class);generated",
"org.apache.commons.io;IOExceptionWithCause;IOExceptionWithCause;(String,Throwable);generated",
"org.apache.commons.io;IOExceptionWithCause;IOExceptionWithCause;(Throwable);generated",
"org.apache.commons.io;IOIndexedException;IOIndexedException;(int,Throwable);generated",
"org.apache.commons.io;IOIndexedException;getIndex;();generated",
"org.apache.commons.io;IOUtils;IOUtils;();generated",
"org.apache.commons.io;IOUtils;byteArray;();generated",
"org.apache.commons.io;IOUtils;byteArray;(int);generated",
"org.apache.commons.io;IOUtils;close;(Closeable);generated",
"org.apache.commons.io;IOUtils;close;(Closeable,IOConsumer);generated",
"org.apache.commons.io;IOUtils;close;(Closeable[]);generated",
"org.apache.commons.io;IOUtils;close;(URLConnection);generated",
"org.apache.commons.io;IOUtils;closeQuietly;(Closeable);generated",
"org.apache.commons.io;IOUtils;closeQuietly;(Closeable,Consumer);generated",
"org.apache.commons.io;IOUtils;closeQuietly;(Closeable[]);generated",
"org.apache.commons.io;IOUtils;closeQuietly;(InputStream);generated",
"org.apache.commons.io;IOUtils;closeQuietly;(OutputStream);generated",
"org.apache.commons.io;IOUtils;closeQuietly;(Reader);generated",
"org.apache.commons.io;IOUtils;closeQuietly;(Selector);generated",
"org.apache.commons.io;IOUtils;closeQuietly;(ServerSocket);generated",
"org.apache.commons.io;IOUtils;closeQuietly;(Socket);generated",
"org.apache.commons.io;IOUtils;closeQuietly;(Writer);generated",
"org.apache.commons.io;IOUtils;consume;(InputStream);generated",
"org.apache.commons.io;IOUtils;contentEquals;(InputStream,InputStream);generated",
"org.apache.commons.io;IOUtils;contentEquals;(Reader,Reader);generated",
"org.apache.commons.io;IOUtils;contentEqualsIgnoreEOL;(Reader,Reader);generated",
"org.apache.commons.io;IOUtils;copy;(ByteArrayOutputStream);generated",
"org.apache.commons.io;IOUtils;copy;(Reader,OutputStream);generated",
"org.apache.commons.io;IOUtils;copy;(Reader,OutputStream,Charset);generated",
"org.apache.commons.io;IOUtils;copy;(Reader,OutputStream,String);generated",
"org.apache.commons.io;IOUtils;copy;(URL,File);generated",
"org.apache.commons.io;IOUtils;copy;(URL,OutputStream);generated",
"org.apache.commons.io;IOUtils;length;(CharSequence);generated",
"org.apache.commons.io;IOUtils;length;(Object[]);generated",
"org.apache.commons.io;IOUtils;length;(byte[]);generated",
"org.apache.commons.io;IOUtils;length;(char[]);generated",
"org.apache.commons.io;IOUtils;resourceToByteArray;(String);generated",
"org.apache.commons.io;IOUtils;resourceToByteArray;(String,ClassLoader);generated",
"org.apache.commons.io;IOUtils;resourceToString;(String,Charset);generated",
"org.apache.commons.io;IOUtils;resourceToString;(String,Charset,ClassLoader);generated",
"org.apache.commons.io;IOUtils;resourceToURL;(String);generated",
"org.apache.commons.io;IOUtils;resourceToURL;(String,ClassLoader);generated",
"org.apache.commons.io;IOUtils;skip;(InputStream,long);generated",
"org.apache.commons.io;IOUtils;skip;(ReadableByteChannel,long);generated",
"org.apache.commons.io;IOUtils;skip;(Reader,long);generated",
"org.apache.commons.io;IOUtils;skipFully;(InputStream,long);generated",
"org.apache.commons.io;IOUtils;skipFully;(ReadableByteChannel,long);generated",
"org.apache.commons.io;IOUtils;skipFully;(Reader,long);generated",
"org.apache.commons.io;IOUtils;toBufferedInputStream;(InputStream);generated",
"org.apache.commons.io;IOUtils;toBufferedInputStream;(InputStream,int);generated",
"org.apache.commons.io;IOUtils;toByteArray;(InputStream);generated",
"org.apache.commons.io;IOUtils;toByteArray;(Reader);generated",
"org.apache.commons.io;IOUtils;toByteArray;(Reader,Charset);generated",
"org.apache.commons.io;IOUtils;toByteArray;(Reader,String);generated",
"org.apache.commons.io;IOUtils;toByteArray;(URI);generated",
"org.apache.commons.io;IOUtils;toByteArray;(URL);generated",
"org.apache.commons.io;IOUtils;toByteArray;(URLConnection);generated",
"org.apache.commons.io;IOUtils;toString;(URI);generated",
"org.apache.commons.io;IOUtils;toString;(URI,Charset);generated",
"org.apache.commons.io;IOUtils;toString;(URI,String);generated",
"org.apache.commons.io;IOUtils;toString;(URL);generated",
"org.apache.commons.io;IOUtils;toString;(URL,Charset);generated",
"org.apache.commons.io;IOUtils;toString;(URL,String);generated",
"org.apache.commons.io;IOUtils;write;(CharSequence,OutputStream);generated",
"org.apache.commons.io;IOUtils;write;(CharSequence,OutputStream,Charset);generated",
"org.apache.commons.io;IOUtils;write;(CharSequence,OutputStream,String);generated",
"org.apache.commons.io;IOUtils;write;(String,OutputStream);generated",
"org.apache.commons.io;IOUtils;write;(String,OutputStream,Charset);generated",
"org.apache.commons.io;IOUtils;write;(String,OutputStream,String);generated",
"org.apache.commons.io;IOUtils;write;(StringBuffer,OutputStream);generated",
"org.apache.commons.io;IOUtils;write;(StringBuffer,OutputStream,String);generated",
"org.apache.commons.io;IOUtils;write;(char[],OutputStream);generated",
"org.apache.commons.io;IOUtils;write;(char[],OutputStream,Charset);generated",
"org.apache.commons.io;IOUtils;write;(char[],OutputStream,String);generated",
"org.apache.commons.io;LineIterator;closeQuietly;(LineIterator);generated",
"org.apache.commons.io;RandomAccessFileMode;create;(File);generated",
"org.apache.commons.io;RandomAccessFileMode;create;(Path);generated",
"org.apache.commons.io;RandomAccessFileMode;create;(String);generated",
"org.apache.commons.io;RandomAccessFileMode;toString;();generated",
"org.apache.commons.io;StandardLineSeparator;getBytes;(Charset);generated",
"org.apache.commons.io;StandardLineSeparator;getString;();generated",
"org.apache.commons.io;TaggedIOException;isTaggedWith;(Throwable,Object);generated",
"org.apache.commons.io;TaggedIOException;throwCauseIfTaggedWith;(Throwable,Object);generated",
"org.apache.commons.io;UncheckedIO;UncheckedIO;();generated",
"org.apache.commons.io;UncheckedIO;accept;(IOConsumer,Object);generated",
"org.apache.commons.io;UncheckedIO;apply;(IOBiFunction,Object,Object);generated",
"org.apache.commons.io;UncheckedIO;get;(IOSupplier);generated",
"org.apache.commons.io;UncheckedIO;run;(IORunnable);generated",
"org.apache.commons.io;UncheckedIOExceptions;UncheckedIOExceptions;();generated",
"org.apache.commons.io;UncheckedIOExceptions;create;(Object);generated",
"org.apache.commons.io;UncheckedIOExceptions;wrap;(IOException,Object);generated"
]
}
}

View File

@@ -35,8 +35,8 @@ library class ProcessorDefinitionElement extends MethodAccess {
*
* This declares a "target" for this route, described by the URI given as the first argument.
*/
class CamelJavaDSLToDecl extends ProcessorDefinitionElement {
CamelJavaDSLToDecl() { getMethod().hasName("to") }
class CamelJavaDslToDecl extends ProcessorDefinitionElement {
CamelJavaDslToDecl() { getMethod().hasName("to") }
/**
* Gets the URI specified by this `to` declaration.
@@ -47,14 +47,17 @@ class CamelJavaDSLToDecl extends ProcessorDefinitionElement {
deprecated string getURI() { result = getUri() }
}
/** DEPRECATED: Alias for CamelJavaDslToDecl */
deprecated class CamelJavaDSLToDecl = CamelJavaDslToDecl;
/**
* A declaration of a "bean" target in the Apache Camel Java DSL.
*
* This declares a bean to call for this route. The bean is defined either by a Class<?> reference,
* or the bean object itself.
*/
class CamelJavaDSLBeanDecl extends ProcessorDefinitionElement {
CamelJavaDSLBeanDecl() { getMethod().hasName("bean") }
class CamelJavaDslBeanDecl extends ProcessorDefinitionElement {
CamelJavaDslBeanDecl() { getMethod().hasName("bean") }
/**
* Gets a bean class that may be registered as a target by this `bean()` declaration.
@@ -71,6 +74,9 @@ class CamelJavaDSLBeanDecl extends ProcessorDefinitionElement {
}
}
/** DEPRECATED: Alias for CamelJavaDslBeanDecl */
deprecated class CamelJavaDSLBeanDecl = CamelJavaDslBeanDecl;
/**
* A declaration of a "beanRef" target in the Apache Camel Java DSL.
*
@@ -78,8 +84,8 @@ class CamelJavaDSLBeanDecl extends ProcessorDefinitionElement {
* the bean reference is dependent on which registries are used by Apache Camel, but we make the
* assumption that it either represetns a qualified name, or a Srping bean identifier.
*/
class CamelJavaDSLBeanRefDecl extends ProcessorDefinitionElement {
CamelJavaDSLBeanRefDecl() { getMethod().hasName("beanRef") }
class CamelJavaDslBeanRefDecl extends ProcessorDefinitionElement {
CamelJavaDslBeanRefDecl() { getMethod().hasName("beanRef") }
/**
* Gets the string describing the bean referred to.
@@ -98,13 +104,16 @@ class CamelJavaDSLBeanRefDecl extends ProcessorDefinitionElement {
}
}
/** DEPRECATED: Alias for CamelJavaDslBeanRefDecl */
deprecated class CamelJavaDSLBeanRefDecl = CamelJavaDslBeanRefDecl;
/**
* A "method" Camel expression in the Apache Camel Java DSL.
*
* An expression that represents a call to a bean, or particular method on a bean.
*/
class CamelJavaDSLMethodDecl extends MethodAccess {
CamelJavaDSLMethodDecl() {
class CamelJavaDslMethodDecl extends MethodAccess {
CamelJavaDslMethodDecl() {
getMethod()
.getDeclaringType()
.getSourceDeclaration()
@@ -129,3 +138,6 @@ class CamelJavaDSLMethodDecl extends MethodAccess {
else result = getArgument(0).getType()
}
}
/** DEPRECATED: Alias for CamelJavaDslMethodDecl */
deprecated class CamelJavaDSLMethodDecl = CamelJavaDslMethodDecl;

View File

@@ -6,4 +6,5 @@ import java
private module GeneratedFrameworks {
private import apache.IOGenerated
private import kotlin.StdLibGenerated
}

View File

@@ -33,12 +33,12 @@ class PersistentEntity extends RefType {
}
/**
* Gets the access type for this entity as defined by a `@javax.persistence.Access` annotation, if any.
* Gets the access type for this entity as defined by a `@javax.persistence.Access` annotation,
* if any, in lower case.
*/
string getAccessTypeFromAnnotation() {
exists(AccessAnnotation accessType | accessType = this.getAnAnnotation() |
result =
accessType.getValue("value").(FieldRead).getField().(EnumConstant).getName().toLowerCase()
result = accessType.getEnumConstantValue("value").getName().toLowerCase()
)
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,14 @@
/** Definitions of taint steps in the KotlinStdLib framework */
import java
private import semmle.code.java.dataflow.ExternalFlow
private class KotlinStdLibSummaryCsv extends SummaryModelCsv {
override predicate row(string row) {
row =
[
"kotlin.jvm.internal;ArrayIteratorKt;false;iterator;(Object[]);;Argument[0].ArrayElement;ReturnValue.Element;value;manual",
"kotlin.collections;ArraysKt;false;withIndex;(Object[]);;Argument[0].ArrayElement;ReturnValue;taint;manual"
]
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -13,6 +13,7 @@ import semmle.code.java.frameworks.spring.SpringContext
import semmle.code.java.frameworks.spring.SpringComponentScan
import semmle.code.java.frameworks.spring.SpringConstructorArg
import semmle.code.java.frameworks.spring.SpringController
import semmle.code.java.frameworks.spring.SpringData
import semmle.code.java.frameworks.spring.SpringDescription
import semmle.code.java.frameworks.spring.SpringEntry
import semmle.code.java.frameworks.spring.SpringFlex

View File

@@ -311,9 +311,7 @@ class SpringQualifierDefinitionAnnotation extends Annotation {
/**
* Gets the value of the qualifier field for this qualifier.
*/
string getQualifierValue() {
result = this.getValue("value").(CompileTimeConstantExpr).getStringValue()
}
string getQualifierValue() { result = this.getStringValue("value") }
}
/**
@@ -325,9 +323,7 @@ class SpringQualifierAnnotation extends Annotation {
/**
* Gets the value of the qualifier field for this qualifier.
*/
string getQualifierValue() {
result = this.getValue("value").(CompileTimeConstantExpr).getStringValue()
}
string getQualifierValue() { result = this.getStringValue("value") }
/**
* Gets the bean definition in an XML file that this qualifier resolves to, if any.
@@ -350,9 +346,7 @@ class SpringResourceAnnotation extends Annotation {
/**
* Gets the specified name value, if any.
*/
string getNameValue() {
result = this.getValue("name").(CompileTimeConstantExpr).getStringValue()
}
string getNameValue() { result = this.getStringValue("name") }
/**
* Gets the bean definition in an XML file that the resource resolves to, if any.

View File

@@ -40,16 +40,10 @@ class SpringComponentScan extends Annotation {
*/
string getBasePackages() {
// "value" and "basePackages" are synonymous, and are simple strings
result = this.getAValue("basePackages").(StringLiteral).getValue()
result = this.getAStringArrayValue(["basePackages", "value"])
or
result = this.getAValue("value").(StringLiteral).getValue()
or
exists(TypeLiteral typeLiteral |
// Base package classes are type literals whose package should be considered a base package.
typeLiteral = this.getAValue("basePackageClasses")
|
result = typeLiteral.getReferencedType().(RefType).getPackage().getName()
)
// Base package classes are type literals whose package should be considered a base package.
result = this.getATypeArrayValue("basePackageClasses").(RefType).getPackage().getName()
}
}
@@ -144,8 +138,7 @@ class SpringComponent extends RefType {
if exists(this.getComponentAnnotation().getValue("value"))
then
// If the name has been specified in the component annotation, use that.
result =
this.getComponentAnnotation().getValue("value").(CompileTimeConstantExpr).getStringValue()
result = this.getComponentAnnotation().getStringValue("value")
else
// Otherwise use the name of the class, with the initial letter lower cased.
exists(string name | name = this.getName() |
@@ -204,7 +197,7 @@ class SpringComponent extends RefType {
.getType()
.hasQualifiedName("org.springframework.context.annotation", "Profile")
|
result = profileAnnotation.getAValue("value").(StringLiteral).getValue()
result = profileAnnotation.getAStringArrayValue("value")
)
}
}

View File

@@ -154,9 +154,7 @@ class SpringRequestMappingMethod extends SpringControllerMethod {
}
/** Gets the "value" @RequestMapping annotation value, if present. */
string getValue() {
result = requestMappingAnnotation.getValue("value").(CompileTimeConstantExpr).getStringValue()
}
string getValue() { result = requestMappingAnnotation.getStringValue("value") }
/** Holds if this is considered an `@ResponseBody` method. */
predicate isResponseBody() {

View File

@@ -0,0 +1,17 @@
/**
* Provides classes and predicates for working with Spring classes and interfaces from
* `org.springframework.data`.
*/
import java
private import semmle.code.java.dataflow.ExternalFlow
/**
* Provides models for the `org.springframework.data` package.
*/
private class FlowSummaries extends SummaryModelCsv {
override predicate row(string row) {
row =
"org.springframework.data.repository;CrudRepository;true;save;;;Argument[0];ReturnValue;value;manual"
}
}

View File

@@ -34,5 +34,5 @@ class StrutsActionsAnnotation extends StrutsAnnotation {
/**
* Gets an Action annotation contained in this Actions annotation.
*/
StrutsActionAnnotation getAnAction() { result = this.getAValue("value") }
StrutsActionAnnotation getAnAction() { result = this.getAnArrayValue("value") }
}

View File

@@ -49,7 +49,7 @@ private class Serializable extends ClassStore {
/** The instantiation of a marshallable class, which can be stored to disk as XML. */
private class Marshallable extends ClassStore {
Marshallable() { this.getConstructor().getDeclaringType() instanceof JAXBElement }
Marshallable() { this.getConstructor().getDeclaringType() instanceof JaxbElement }
/** Gets a store, for example `marshaller.marshal(instance)`. */
override Expr getAStore() {
@@ -69,7 +69,7 @@ private Expr getInstanceInput(DataFlow::Node instance, RefType t) {
fa.getField().getDeclaringType() = t
|
t.getASourceSupertype*() instanceof TypeSerializable or
t instanceof JAXBElement
t instanceof JaxbElement
)
}
@@ -98,7 +98,7 @@ private predicate serializableStore(DataFlow::Node instance, Expr store) {
private predicate marshallableStore(DataFlow::Node instance, Expr store) {
exists(MethodAccess m |
store = m and
m.getMethod() instanceof JAXBMarshalMethod and
m.getMethod() instanceof JaxbMarshalMethod and
instance.asExpr() = m.getArgument(0)
)
}

View File

@@ -24,7 +24,7 @@ private class DefaultSafeExternalApiMethod extends SafeExternalApiMethod {
or
this.getDeclaringType().hasQualifiedName("org.apache.commons.lang3", "Validate")
or
this.getQualifiedName() = "Objects.equals"
this.hasQualifiedName("java.util", "Objects", "equals")
or
this.getDeclaringType() instanceof TypeString and this.getName() = "equals"
or
@@ -92,10 +92,7 @@ class ExternalApiDataNode extends DataFlow::Node {
int getIndex() { result = i }
/** Gets the description of the method being called. */
string getMethodDescription() {
result =
this.getMethod().getDeclaringType().getPackage() + "." + this.getMethod().getQualifiedName()
}
string getMethodDescription() { result = this.getMethod().getQualifiedName() }
}
/** DEPRECATED: Alias for ExternalApiDataNode */

View File

@@ -102,11 +102,25 @@ private class PendingIntentSentSinkModels extends SinkModelCsv {
"android.app;NotificationManager;true;notify;(String,int,Notification);;Argument[2];pending-intent-sent;manual",
"android.app;NotificationManager;true;notifyAsPackage;(String,String,int,Notification);;Argument[3];pending-intent-sent;manual",
"android.app;NotificationManager;true;notifyAsUser;(String,int,Notification,UserHandle);;Argument[2];pending-intent-sent;manual",
"androidx.core.app;NotificationManagerCompat;true;notify;(int,Notification);;Argument[1];pending-intent-sent;manual",
"androidx.core.app;NotificationManagerCompat;true;notify;(String,int,Notification);;Argument[2];pending-intent-sent;manual",
"android.app;PendingIntent;false;send;(Context,int,Intent,OnFinished,Handler,String,Bundle);;Argument[2];pending-intent-sent;manual",
"android.app;PendingIntent;false;send;(Context,int,Intent,OnFinished,Handler,String);;Argument[2];pending-intent-sent;manual",
"android.app;PendingIntent;false;send;(Context,int,Intent,OnFinished,Handler);;Argument[2];pending-intent-sent;manual",
"android.app;PendingIntent;false;send;(Context,int,Intent);;Argument[2];pending-intent-sent;manual",
"android.app;Activity;true;setResult;(int,Intent);;Argument[1];pending-intent-sent;manual"
"android.app;Activity;true;setResult;(int,Intent);;Argument[1];pending-intent-sent;manual",
"android.app;AlarmManager;true;set;(int,long,PendingIntent);;Argument[2];pending-intent-sent;manual",
"android.app;AlarmManager;true;setAlarmClock;;;Argument[1];pending-intent-sent;manual",
"android.app;AlarmManager;true;setAndAllowWhileIdle;;;Argument[2];pending-intent-sent;manual",
"android.app;AlarmManager;true;setExact;(int,long,PendingIntent);;Argument[2];pending-intent-sent;manual",
"android.app;AlarmManager;true;setExactAndAllowWhileIdle;;;Argument[2];pending-intent-sent;manual",
"android.app;AlarmManager;true;setInexactRepeating;;;Argument[3];pending-intent-sent;manual",
"android.app;AlarmManager;true;setRepeating;;;Argument[3];pending-intent-sent;manual",
"android.app;AlarmManager;true;setWindow;(int,long,long,PendingIntent);;Argument[3];pending-intent-sent;manual",
"androidx.core.app;AlarmManagerCompat;true;setAlarmClock;;;Argument[2..3];pending-intent-sent;manual",
"androidx.core.app;AlarmManagerCompat;true;setAndAllowWhileIdle;;;Argument[3];pending-intent-sent;manual",
"androidx.core.app;AlarmManagerCompat;true;setExact;;;Argument[3];pending-intent-sent;manual",
"androidx.core.app;AlarmManagerCompat;true;setExactAndAllowWhileIdle;;;Argument[3];pending-intent-sent;manual",
]
}
}

View File

@@ -176,7 +176,7 @@ private predicate nameAddStep(DataFlow::ExprNode n1, DataFlow::ExprNode n2) {
* by calling `new JMXServiceURL(tainted)`.
*/
private predicate jmxServiceUrlStep(DataFlow::ExprNode n1, DataFlow::ExprNode n2) {
exists(ConstructorCall cc | cc.getConstructedType() instanceof TypeJMXServiceURL |
exists(ConstructorCall cc | cc.getConstructedType() instanceof TypeJmxServiceUrl |
n1.asExpr() = cc.getAnArgument() and
n2.asExpr() = cc
)
@@ -189,7 +189,7 @@ private predicate jmxServiceUrlStep(DataFlow::ExprNode n1, DataFlow::ExprNode n2
private predicate jmxConnectorStep(DataFlow::ExprNode n1, DataFlow::ExprNode n2) {
exists(MethodAccess ma, Method m | n1.asExpr() = ma.getArgument(0) and n2.asExpr() = ma |
ma.getMethod() = m and
m.getDeclaringType() instanceof TypeJMXConnectorFactory and
m.getDeclaringType() instanceof TypeJmxConnectorFactory and
m.hasName("newJMXConnector")
)
}
@@ -199,7 +199,7 @@ private predicate jmxConnectorStep(DataFlow::ExprNode n1, DataFlow::ExprNode n2)
* `RMIConnector` by calling `new RMIConnector(tainted)`.
*/
private predicate rmiConnectorStep(DataFlow::ExprNode n1, DataFlow::ExprNode n2) {
exists(ConstructorCall cc | cc.getConstructedType() instanceof TypeRMIConnector |
exists(ConstructorCall cc | cc.getConstructedType() instanceof TypeRmiConnector |
n1.asExpr() = cc.getAnArgument() and
n2.asExpr() = cc
)

View File

@@ -140,8 +140,8 @@ private predicate filterStep(DataFlow::ExprNode n1, DataFlow::ExprNode n2) {
ma.getMethod() = m
|
m instanceof MethodUnboundIdFilterCreate or
m instanceof MethodUnboundIdFilterCreateANDFilter or
m instanceof MethodUnboundIdFilterCreateNOTFilter or
m instanceof MethodUnboundIdFilterCreateAndFilter or
m instanceof MethodUnboundIdFilterCreateNotFilter or
m instanceof MethodUnboundIdFilterCreateORFilter or
m instanceof MethodUnboundIdFilterSimplifyFilter
)

View File

@@ -96,7 +96,10 @@ class OverlyWideRange extends RegExpCharacterRange {
toCodePoint("A") <= high
or
// a non-alphanumeric char as part of the range boundaries
exists(int bound | bound = [low, high] | not isAlphanumeric(bound.toUnicode()))
exists(int bound | bound = [low, high] | not isAlphanumeric(bound.toUnicode())) and
// while still being ascii
low < 128 and
high < 128
) and
// allowlist for known ranges
not this = allowedWideRanges()
@@ -173,7 +176,7 @@ module RangePrinter {
}
/** Gets the number of parts we should print for a given `range`. */
private int parts(OverlyWideRange range) { result = 1 + strictcount(cutoff(range, _)) }
private int parts(OverlyWideRange range) { result = 1 + count(cutoff(range, _)) }
/** Holds if the given part of a range should span from `low` to `high`. */
private predicate part(OverlyWideRange range, int part, string low, string high) {

View File

@@ -0,0 +1,108 @@
/** Definitions related to the server-side template injection (SST) query. */
import java
private import semmle.code.java.dataflow.FlowSources
private import semmle.code.java.dataflow.ExternalFlow
private import semmle.code.java.dataflow.TaintTracking
/**
* A source for server-side template injection (SST) vulnerabilities.
*/
abstract class TemplateInjectionSource extends DataFlow::Node {
/** Holds if this source has the specified `state`. */
predicate hasState(DataFlow::FlowState state) { state instanceof DataFlow::FlowStateEmpty }
}
/**
* A sink for server-side template injection (SST) vulnerabilities.
*/
abstract class TemplateInjectionSink extends DataFlow::Node {
/** Holds if this sink has the specified `state`. */
predicate hasState(DataFlow::FlowState state) { state instanceof DataFlow::FlowStateEmpty }
}
/**
* A unit class for adding additional taint steps.
*
* Extend this class to add additional taint steps that should apply to flows related to
* server-side template injection (SST) vulnerabilities.
*/
class TemplateInjectionAdditionalTaintStep extends Unit {
/**
* Holds if the step from `node1` to `node2` should be considered a taint
* step for flows related to server-side template injection (SST) vulnerabilities.
*/
predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { none() }
/**
* Holds if the step from `node1` to `node2` should be considered a taint
* step for flows related toserver-side template injection (SST) vulnerabilities.
* This step is only applicable in `state1` and updates the flow state to `state2`.
*/
predicate isAdditionalTaintStep(
DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2,
DataFlow::FlowState state2
) {
none()
}
}
/**
* A sanitizer for server-side template injection (SST) vulnerabilities.
*/
abstract class TemplateInjectionSanitizer extends DataFlow::Node { }
/**
* A sanitizer for server-side template injection (SST) vulnerabilities.
* This sanitizer is only applicable when `TemplateInjectionSanitizerWithState::hasState`
* holds for the flow state.
*/
abstract class TemplateInjectionSanitizerWithState extends DataFlow::Node {
/** Holds if this sanitizer has the specified `state`. */
abstract predicate hasState(DataFlow::FlowState state);
}
private class DefaultTemplateInjectionSource extends TemplateInjectionSource instanceof RemoteFlowSource {
}
private class DefaultTemplateInjectionSink extends TemplateInjectionSink {
DefaultTemplateInjectionSink() { sinkNode(this, "ssti") }
}
private class DefaultTemplateInjectionSanitizer extends TemplateInjectionSanitizer {
DefaultTemplateInjectionSanitizer() {
this.getType() instanceof PrimitiveType or
this.getType() instanceof BoxedType or
this.getType() instanceof NumericType
}
}
private class TemplateInjectionSinkModels extends SinkModelCsv {
override predicate row(string row) {
row =
[
"freemarker.template;Template;true;Template;(String,Reader);;Argument[1];ssti;manual",
"freemarker.template;Template;true;Template;(String,Reader,Configuration);;Argument[1];ssti;manual",
"freemarker.template;Template;true;Template;(String,Reader,Configuration,String);;Argument[1];ssti;manual",
"freemarker.template;Template;true;Template;(String,String,Reader,Configuration);;Argument[2];ssti;manual",
"freemarker.template;Template;true;Template;(String,String,Reader,Configuration,String);;Argument[2];ssti;manual",
"freemarker.template;Template;true;Template;(String,String,Reader,Configuration,ParserConfiguration,String);;Argument[2];ssti;manual",
"freemarker.template;Template;true;Template;(String,String,Configuration);;Argument[1];ssti;manual",
"freemarker.cache;StringTemplateLoader;true;putTemplate;;;Argument[1];ssti;manual",
"com.mitchellbosecke.pebble;PebbleEngine;true;getTemplate;;;Argument[0];ssti;manual",
"com.mitchellbosecke.pebble;PebbleEngine;true;getLiteralTemplate;;;Argument[0];ssti;manual",
"com.hubspot.jinjava;Jinjava;true;renderForResult;;;Argument[0];ssti;manual",
"com.hubspot.jinjava;Jinjava;true;render;;;Argument[0];ssti;manual",
"org.thymeleaf;ITemplateEngine;true;process;;;Argument[0];ssti;manual",
"org.thymeleaf;ITemplateEngine;true;processThrottled;;;Argument[0];ssti;manual",
"org.apache.velocity.app;Velocity;true;evaluate;;;Argument[3];ssti;manual",
"org.apache.velocity.app;Velocity;true;mergeTemplate;;;Argument[2];ssti;manual",
"org.apache.velocity.app;VelocityEngine;true;evaluate;;;Argument[3];ssti;manual",
"org.apache.velocity.app;VelocityEngine;true;mergeTemplate;;;Argument[2];ssti;manual",
"org.apache.velocity.runtime.resource.util;StringResourceRepository;true;putStringResource;;;Argument[1];ssti;manual",
"org.apache.velocity.runtime;RuntimeServices;true;evaluate;;;Argument[3];ssti;manual",
"org.apache.velocity.runtime;RuntimeServices;true;parse;;;Argument[0];ssti;manual",
"org.apache.velocity.runtime;RuntimeSingleton;true;parse;;;Argument[0];ssti;manual"
]
}
}

View File

@@ -0,0 +1,38 @@
/** Provides a taint tracking configuration for server-side template injection (SST) vulnerabilities */
import java
import semmle.code.java.dataflow.TaintTracking
import semmle.code.java.dataflow.FlowSources
import semmle.code.java.security.TemplateInjection
/** A taint tracking configuration to reason about server-side template injection (SST) vulnerabilities */
class TemplateInjectionFlowConfig extends TaintTracking::Configuration {
TemplateInjectionFlowConfig() { this = "TemplateInjectionFlowConfig" }
override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) {
source.(TemplateInjectionSource).hasState(state)
}
override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) {
sink.(TemplateInjectionSink).hasState(state)
}
override predicate isSanitizer(DataFlow::Node sanitizer) {
sanitizer instanceof TemplateInjectionSanitizer
}
override predicate isSanitizer(DataFlow::Node sanitizer, DataFlow::FlowState state) {
sanitizer.(TemplateInjectionSanitizerWithState).hasState(state)
}
override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) {
any(TemplateInjectionAdditionalTaintStep a).isAdditionalTaintStep(node1, node2)
}
override predicate isAdditionalTaintStep(
DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2,
DataFlow::FlowState state2
) {
any(TemplateInjectionAdditionalTaintStep a).isAdditionalTaintStep(node1, state1, node2, state2)
}
}

View File

@@ -115,6 +115,7 @@ private newtype TStatePair =
private int rankState(State state) {
state =
rank[result](State s, Location l |
stateInsideBacktracking(s) and
l = s.getRepr().getLocation()
|
s order by l.getStartLine(), l.getStartColumn(), s.toString()

View File

@@ -93,8 +93,6 @@ class RegExpRoot extends RegExpTerm {
* Holds if this root term is relevant to the ReDoS analysis.
*/
predicate isRelevant() {
// there is at least one repetition
getRoot(any(InfiniteRepetitionQuantifier q)) = this and
// is actually used as a RegExp
this.isUsedAsRegExp() and
// not excluded for library specific reasons
@@ -877,6 +875,107 @@ predicate isStartState(State state) {
*/
signature predicate isCandidateSig(State state, string pump);
/**
* Holds if `state` is a candidate for ReDoS.
*/
signature predicate isCandidateSig(State state);
/**
* Predicates for constructing a prefix string that leads to a given state.
*/
module PrefixConstruction<isCandidateSig/1 isCandidate> {
/**
* Holds if `state` is the textually last start state for the regular expression.
*/
private predicate lastStartState(RelevantState state) {
exists(RegExpRoot root |
state =
max(RelevantState s, Location l |
isStartState(s) and
getRoot(s.getRepr()) = root and
l = s.getRepr().getLocation()
|
s
order by
l.getStartLine(), l.getStartColumn(), s.getRepr().toString(), l.getEndColumn(),
l.getEndLine()
)
)
}
/**
* Holds if there exists any transition (Epsilon() or other) from `a` to `b`.
*/
private predicate existsTransition(State a, State b) { delta(a, _, b) }
/**
* Gets the minimum number of transitions it takes to reach `state` from the `start` state.
*/
int prefixLength(State start, State state) =
shortestDistances(lastStartState/1, existsTransition/2)(start, state, result)
/**
* Gets the minimum number of transitions it takes to reach `state` from the start state.
*/
private int lengthFromStart(State state) { result = prefixLength(_, state) }
/**
* Gets a string for which the regular expression will reach `state`.
*
* Has at most one result for any given `state`.
* This predicate will not always have a result even if there is a ReDoS issue in
* the regular expression.
*/
string prefix(State state) {
lastStartState(state) and
result = ""
or
// the search stops past the last redos candidate state.
lengthFromStart(state) <= max(lengthFromStart(any(State s | isCandidate(s)))) and
exists(State prev |
// select a unique predecessor (by an arbitrary measure)
prev =
min(State s, Location loc |
lengthFromStart(s) = lengthFromStart(state) - 1 and
loc = s.getRepr().getLocation() and
delta(s, _, state)
|
s
order by
loc.getStartLine(), loc.getStartColumn(), loc.getEndLine(), loc.getEndColumn(),
s.getRepr().toString()
)
|
// greedy search for the shortest prefix
result = prefix(prev) and delta(prev, Epsilon(), state)
or
not delta(prev, Epsilon(), state) and
result = prefix(prev) + getCanonicalEdgeChar(prev, state)
)
}
/**
* Gets a canonical char for which there exists a transition from `prev` to `next` in the NFA.
*/
private string getCanonicalEdgeChar(State prev, State next) {
result =
min(string c | delta(prev, any(InputSymbol symbol | c = intersect(Any(), symbol)), next))
}
/** A state within a regular expression that contains a candidate state. */
class RelevantState instanceof State {
RelevantState() {
exists(State s | isCandidate(s) | getRoot(s.getRepr()) = getRoot(this.getRepr()))
}
/** Gets a string representation for this state in a regular expression. */
string toString() { result = State.super.toString() }
/** Gets the term represented by this state. */
RegExpTerm getRepr() { result = State.super.getRepr() }
}
}
/**
* A module for pruning candidate ReDoS states.
* The candidates are specified by the `isCandidate` signature predicate.
@@ -910,95 +1009,11 @@ module ReDoSPruning<isCandidateSig/2 isCandidate> {
/** Gets a state that can reach the `accept-any` state using only epsilon steps. */
private State acceptsAnySuffix() { epsilonSucc*(result) = AcceptAnySuffix(_) }
/**
* Predicates for constructing a prefix string that leads to a given state.
*/
private module PrefixConstruction {
/**
* Holds if `state` is the textually last start state for the regular expression.
*/
private predicate lastStartState(State state) {
exists(RegExpRoot root |
state =
max(State s, Location l |
s = stateInPumpableRegexp() and
isStartState(s) and
getRoot(s.getRepr()) = root and
l = s.getRepr().getLocation()
|
s
order by
l.getStartLine(), l.getStartColumn(), s.getRepr().toString(), l.getEndColumn(),
l.getEndLine()
)
)
}
predicate isCandidateState(State s) { isReDoSCandidate(s, _) }
/**
* Holds if there exists any transition (Epsilon() or other) from `a` to `b`.
*/
private predicate existsTransition(State a, State b) { delta(a, _, b) }
import PrefixConstruction<isCandidateState/1> as Prefix
/**
* Gets the minimum number of transitions it takes to reach `state` from the `start` state.
*/
int prefixLength(State start, State state) =
shortestDistances(lastStartState/1, existsTransition/2)(start, state, result)
/**
* Gets the minimum number of transitions it takes to reach `state` from the start state.
*/
private int lengthFromStart(State state) { result = prefixLength(_, state) }
/**
* Gets a string for which the regular expression will reach `state`.
*
* Has at most one result for any given `state`.
* This predicate will not always have a result even if there is a ReDoS issue in
* the regular expression.
*/
string prefix(State state) {
lastStartState(state) and
result = ""
or
// the search stops past the last redos candidate state.
lengthFromStart(state) <= max(lengthFromStart(any(State s | isReDoSCandidate(s, _)))) and
exists(State prev |
// select a unique predecessor (by an arbitrary measure)
prev =
min(State s, Location loc |
lengthFromStart(s) = lengthFromStart(state) - 1 and
loc = s.getRepr().getLocation() and
delta(s, _, state)
|
s
order by
loc.getStartLine(), loc.getStartColumn(), loc.getEndLine(), loc.getEndColumn(),
s.getRepr().toString()
)
|
// greedy search for the shortest prefix
result = prefix(prev) and delta(prev, Epsilon(), state)
or
not delta(prev, Epsilon(), state) and
result = prefix(prev) + getCanonicalEdgeChar(prev, state)
)
}
/**
* Gets a canonical char for which there exists a transition from `prev` to `next` in the NFA.
*/
private string getCanonicalEdgeChar(State prev, State next) {
result =
min(string c | delta(prev, any(InputSymbol symbol | c = intersect(Any(), symbol)), next))
}
/** Gets a state within a regular expression that has a pumpable state. */
pragma[noinline]
State stateInPumpableRegexp() {
exists(State s | isReDoSCandidate(s, _) | getRoot(s.getRepr()) = getRoot(result.getRepr()))
}
}
class RelevantState = Prefix::RelevantState;
/**
* Predicates for testing the presence of a rejecting suffix.
@@ -1018,8 +1033,6 @@ module ReDoSPruning<isCandidateSig/2 isCandidate> {
* using epsilon transitions. But any attempt at repeating `w` will end in a state that accepts all suffixes.
*/
private module SuffixConstruction {
import PrefixConstruction
/**
* Holds if all states reachable from `fork` by repeating `w`
* are likely rejectable by appending some suffix.
@@ -1035,32 +1048,26 @@ module ReDoSPruning<isCandidateSig/2 isCandidate> {
* This predicate might find impossible suffixes when searching for suffixes of length > 1, which can cause FPs.
*/
pragma[noinline]
private predicate isLikelyRejectable(State s) {
s = stateInPumpableRegexp() and
(
// exists a reject edge with some char.
hasRejectEdge(s)
or
hasEdgeToLikelyRejectable(s)
or
// stopping here is rejection
isRejectState(s)
)
private predicate isLikelyRejectable(RelevantState s) {
// exists a reject edge with some char.
hasRejectEdge(s)
or
hasEdgeToLikelyRejectable(s)
or
// stopping here is rejection
isRejectState(s)
}
/**
* Holds if `s` is not an accept state, and there is no epsilon transition to an accept state.
*/
predicate isRejectState(State s) {
s = stateInPumpableRegexp() and not epsilonSucc*(s) = Accept(_)
}
predicate isRejectState(RelevantState s) { not epsilonSucc*(s) = Accept(_) }
/**
* Holds if there is likely a non-empty suffix leading to rejection starting in `s`.
*/
pragma[noopt]
predicate hasEdgeToLikelyRejectable(State s) {
s = stateInPumpableRegexp() and
predicate hasEdgeToLikelyRejectable(RelevantState s) {
// all edges (at least one) with some char leads to another state that is rejectable.
// the `next` states might not share a common suffix, which can cause FPs.
exists(string char | char = hasEdgeToLikelyRejectableHelper(s) |
@@ -1075,8 +1082,7 @@ module ReDoSPruning<isCandidateSig/2 isCandidate> {
* and `s` has not been found to be rejectable by `hasRejectEdge` or `isRejectState`.
*/
pragma[noinline]
private string hasEdgeToLikelyRejectableHelper(State s) {
s = stateInPumpableRegexp() and
private string hasEdgeToLikelyRejectableHelper(RelevantState s) {
not hasRejectEdge(s) and
not isRejectState(s) and
deltaClosedChar(s, result, _)
@@ -1087,9 +1093,7 @@ module ReDoSPruning<isCandidateSig/2 isCandidate> {
* along epsilon edges, such that there is a transition from
* `prev` to `next` that the character symbol `char`.
*/
predicate deltaClosedChar(State prev, string char, State next) {
prev = stateInPumpableRegexp() and
next = stateInPumpableRegexp() and
predicate deltaClosedChar(RelevantState prev, string char, RelevantState next) {
deltaClosed(prev, getAnInputSymbolMatchingRelevant(char), next)
}
@@ -1099,18 +1103,28 @@ module ReDoSPruning<isCandidateSig/2 isCandidate> {
result = getAnInputSymbolMatching(char)
}
pragma[noinline]
RegExpRoot relevantRoot() {
exists(RegExpTerm term, State s |
s.getRepr() = term and isCandidateState(s) and result = term.getRootTerm()
)
}
/**
* Gets a char used for finding possible suffixes inside `root`.
*/
pragma[noinline]
private string relevant(RegExpRoot root) {
exists(ascii(result)) and exists(root)
or
exists(InputSymbol s | belongsTo(s, root) | result = intersect(s, _))
or
// The characters from `hasSimpleRejectEdge`. Only `\n` is really needed (as `\n` is not in the `ascii` relation).
// The three chars must be kept in sync with `hasSimpleRejectEdge`.
result = ["|", "\n", "Z"] and exists(root)
root = relevantRoot() and
(
exists(ascii(result)) and exists(root)
or
exists(InputSymbol s | belongsTo(s, root) | result = intersect(s, _))
or
// The characters from `hasSimpleRejectEdge`. Only `\n` is really needed (as `\n` is not in the `ascii` relation).
// The three chars must be kept in sync with `hasSimpleRejectEdge`.
result = ["|", "\n", "Z"] and exists(root)
)
}
/**
@@ -1208,12 +1222,12 @@ module ReDoSPruning<isCandidateSig/2 isCandidate> {
predicate hasReDoSResult(RegExpTerm t, string pump, State s, string prefixMsg) {
isReDoSAttackable(t, pump, s) and
(
prefixMsg = "starting with '" + escape(PrefixConstruction::prefix(s)) + "' and " and
not PrefixConstruction::prefix(s) = ""
prefixMsg = "starting with '" + escape(Prefix::prefix(s)) + "' and " and
not Prefix::prefix(s) = ""
or
PrefixConstruction::prefix(s) = "" and prefixMsg = ""
Prefix::prefix(s) = "" and prefixMsg = ""
or
not exists(PrefixConstruction::prefix(s)) and prefixMsg = ""
not exists(Prefix::prefix(s)) and prefixMsg = ""
)
}

View File

@@ -72,6 +72,56 @@ class AndroidApplicationXmlElement extends XmlElement {
* Holds if this application element has explicitly set a value for its `android:permission` attribute.
*/
predicate requiresPermissions() { this.getAnAttribute().(AndroidPermissionXmlAttribute).isFull() }
/**
* Holds if this application element does not disable the `android:allowBackup` attribute.
*
* https://developer.android.com/guide/topics/data/autobackup
*/
predicate allowsBackup() {
not this.getFile().(AndroidManifestXmlFile).isInBuildDirectory() and
(
// explicitly sets android:allowBackup="true"
this.allowsBackupExplicitly()
or
// Manifest providing the main intent for an application, and does not explicitly
// disallow the allowBackup attribute
this.providesMainIntent() and
// Check that android:allowBackup="false" is not present
not exists(AndroidXmlAttribute attr |
this.getAnAttribute() = attr and
attr.getName() = "allowBackup" and
attr.getValue() = "false"
)
)
}
/**
* Holds if this application element sets the `android:allowBackup` attribute to `true`.
*
* https://developer.android.com/guide/topics/data/autobackup
*/
private predicate allowsBackupExplicitly() {
exists(AndroidXmlAttribute attr |
this.getAnAttribute() = attr and
attr.getName() = "allowBackup" and
attr.getValue() = "true"
)
}
/**
* Holds if the application element contains a child element which provides the
* `android.intent.action.MAIN` intent.
*/
private predicate providesMainIntent() {
exists(AndroidActivityXmlElement activity |
activity = this.getAChild() and
exists(AndroidIntentFilterXmlElement intentFilter |
intentFilter = activity.getAChild() and
intentFilter.getAnActionElement().getActionName() = "android.intent.action.MAIN"
)
)
}
}
/**