diff --git a/java/ql/src/Advisory/Declarations/MissingOverrideAnnotation.ql b/java/ql/src/Advisory/Declarations/MissingOverrideAnnotation.ql index f2df9e25315..3e09f729739 100644 --- a/java/ql/src/Advisory/Declarations/MissingOverrideAnnotation.ql +++ b/java/ql/src/Advisory/Declarations/MissingOverrideAnnotation.ql @@ -8,16 +8,13 @@ * @id java/missing-override-annotation * @tags maintainability */ + import java class OverridingMethod extends Method { - OverridingMethod() { - exists(Method m | this.overrides(m)) - } + OverridingMethod() { exists(Method m | this.overrides(m)) } - predicate isOverrideAnnotated() { - this.getAnAnnotation() instanceof OverrideAnnotation - } + predicate isOverrideAnnotated() { this.getAnAnnotation() instanceof OverrideAnnotation } } from OverridingMethod m, Method overridden @@ -26,5 +23,5 @@ where m.overrides(overridden) and not m.isOverrideAnnotated() and not exists(FunctionalExpr mref | mref.asMethod() = m) -select m, "This method overrides $@; it is advisable to add an Override annotation.", - overridden, overridden.getDeclaringType() + "." + overridden.getName() +select m, "This method overrides $@; it is advisable to add an Override annotation.", overridden, + overridden.getDeclaringType() + "." + overridden.getName() diff --git a/java/ql/src/Advisory/Declarations/NonFinalImmutableField.ql b/java/ql/src/Advisory/Declarations/NonFinalImmutableField.ql index b5179abd1ed..d025466ae5a 100644 --- a/java/ql/src/Advisory/Declarations/NonFinalImmutableField.ql +++ b/java/ql/src/Advisory/Declarations/NonFinalImmutableField.ql @@ -9,6 +9,7 @@ * @id java/non-final-immutable-field * @tags reliability */ + import java class Initialization extends Callable { @@ -41,7 +42,8 @@ class ImmutableField extends Field { forall(FieldAccess fw, AnyAssignment ae | fw.getField().getSourceDeclaration() = this and fw = ae.getDest() - | ae.getEnclosingCallable().getDeclaringType() = this.getDeclaringType() and + | + ae.getEnclosingCallable().getDeclaringType() = this.getDeclaringType() and ae.getEnclosingCallable() instanceof Initialization ) } @@ -49,4 +51,5 @@ class ImmutableField extends Field { from ImmutableField f where not f.isFinal() -select f, "This immutable field is not declared final but is only assigned to during initialization." +select f, + "This immutable field is not declared final but is only assigned to during initialization." diff --git a/java/ql/src/Advisory/Declarations/NonPrivateField.ql b/java/ql/src/Advisory/Declarations/NonPrivateField.ql index 4526f9fc89c..60e49003586 100644 --- a/java/ql/src/Advisory/Declarations/NonPrivateField.ql +++ b/java/ql/src/Advisory/Declarations/NonPrivateField.ql @@ -8,6 +8,7 @@ * @id java/non-private-field * @tags maintainability */ + import java import semmle.code.java.JDKAnnotations diff --git a/java/ql/src/Advisory/Deprecated Code/AvoidDeprecatedCallableAccess.ql b/java/ql/src/Advisory/Deprecated Code/AvoidDeprecatedCallableAccess.ql index 6b122338ad1..354b82fe165 100644 --- a/java/ql/src/Advisory/Deprecated Code/AvoidDeprecatedCallableAccess.ql +++ b/java/ql/src/Advisory/Deprecated Code/AvoidDeprecatedCallableAccess.ql @@ -10,10 +10,10 @@ * non-attributable * external/cwe/cwe-477 */ + import java -private -predicate isDeprecatedCallable(Callable c) { +private predicate isDeprecatedCallable(Callable c) { c.getAnAnnotation() instanceof DeprecatedAnnotation or exists(c.getDoc().getJavadoc().getATag("@deprecated")) } @@ -24,5 +24,5 @@ where isDeprecatedCallable(c) and // Exclude deprecated calls from within deprecated code. not isDeprecatedCallable(ca.getCaller()) -select ca, "Invoking $@ should be avoided because it has been deprecated.", - c, c.getDeclaringType() + "." + c.getName() +select ca, "Invoking $@ should be avoided because it has been deprecated.", c, + c.getDeclaringType() + "." + c.getName() diff --git a/java/ql/src/Advisory/Documentation/ImpossibleJavadocThrows.ql b/java/ql/src/Advisory/Documentation/ImpossibleJavadocThrows.ql index 029303caaed..7803605ae22 100644 --- a/java/ql/src/Advisory/Documentation/ImpossibleJavadocThrows.ql +++ b/java/ql/src/Advisory/Documentation/ImpossibleJavadocThrows.ql @@ -19,9 +19,10 @@ RefType getTaggedType(ThrowsTag tag) { predicate canThrow(Callable callable, RefType exception) { exists(string uncheckedException | uncheckedException = "RuntimeException" or uncheckedException = "Error" - | + | exception.getASupertype*().hasQualifiedName("java.lang", uncheckedException) - ) or + ) + or callable.getAnException().getType().getASubtype*() = exception } @@ -31,4 +32,5 @@ where docMethod.getDoc().getJavadoc().getAChild*() = throwsTag and not canThrow(docMethod, thrownType) select throwsTag, - "Javadoc for " + docMethod + " claims to throw " + thrownType.getName() + " but this is impossible." + "Javadoc for " + docMethod + " claims to throw " + thrownType.getName() + + " but this is impossible." diff --git a/java/ql/src/Advisory/Documentation/MissingJavadocMethods.ql b/java/ql/src/Advisory/Documentation/MissingJavadocMethods.ql index e952598c2a6..49d90a595d3 100644 --- a/java/ql/src/Advisory/Documentation/MissingJavadocMethods.ql +++ b/java/ql/src/Advisory/Documentation/MissingJavadocMethods.ql @@ -8,9 +8,11 @@ * @id java/undocumented-function * @tags maintainability */ + import java import JavadocCommon from DocuCallable c where not c.hasAcceptableDocText() -select c, "This " + c.toMethodOrConstructorString() + " does not have a non-trivial Javadoc comment." +select c, + "This " + c.toMethodOrConstructorString() + " does not have a non-trivial Javadoc comment." diff --git a/java/ql/src/Advisory/Documentation/MissingJavadocParameters.ql b/java/ql/src/Advisory/Documentation/MissingJavadocParameters.ql index 87712e8d9aa..ec4735e5e21 100644 --- a/java/ql/src/Advisory/Documentation/MissingJavadocParameters.ql +++ b/java/ql/src/Advisory/Documentation/MissingJavadocParameters.ql @@ -8,6 +8,7 @@ * @id java/undocumented-parameter * @tags maintainability */ + import java import JavadocCommon diff --git a/java/ql/src/Advisory/Documentation/MissingJavadocReturnValues.ql b/java/ql/src/Advisory/Documentation/MissingJavadocReturnValues.ql index 683f0c96b50..6668fa6da33 100644 --- a/java/ql/src/Advisory/Documentation/MissingJavadocReturnValues.ql +++ b/java/ql/src/Advisory/Documentation/MissingJavadocReturnValues.ql @@ -8,6 +8,7 @@ * @id java/undocumented-return-value * @tags maintainability */ + import java import JavadocCommon diff --git a/java/ql/src/Advisory/Documentation/MissingJavadocThrows.ql b/java/ql/src/Advisory/Documentation/MissingJavadocThrows.ql index a6aa1602d00..2b6b346062c 100644 --- a/java/ql/src/Advisory/Documentation/MissingJavadocThrows.ql +++ b/java/ql/src/Advisory/Documentation/MissingJavadocThrows.ql @@ -8,6 +8,7 @@ * @id java/undocumented-exception * @tags maintainability */ + import java import JavadocCommon @@ -18,5 +19,6 @@ where e.getType() = t and not c.hasAcceptableThrowsTag(e) ) -select c, "This " + c.toMethodOrConstructorString() + " throws $@ but does not have a corresponding Javadoc tag.", - t, t.getName() +select c, + "This " + c.toMethodOrConstructorString() + + " throws $@ but does not have a corresponding Javadoc tag.", t, t.getName() diff --git a/java/ql/src/Advisory/Documentation/MissingJavadocTypes.ql b/java/ql/src/Advisory/Documentation/MissingJavadocTypes.ql index da922aa0be5..b9c5958623d 100644 --- a/java/ql/src/Advisory/Documentation/MissingJavadocTypes.ql +++ b/java/ql/src/Advisory/Documentation/MissingJavadocTypes.ql @@ -8,6 +8,7 @@ * @id java/undocumented-type * @tags maintainability */ + import java import JavadocCommon diff --git a/java/ql/src/Advisory/Documentation/SpuriousJavadocParam.ql b/java/ql/src/Advisory/Documentation/SpuriousJavadocParam.ql index 0828e4dd85e..8f7506e8647 100644 --- a/java/ql/src/Advisory/Documentation/SpuriousJavadocParam.ql +++ b/java/ql/src/Advisory/Documentation/SpuriousJavadocParam.ql @@ -13,20 +13,17 @@ import java from Callable callable, ParamTag paramTag, string what, string msg where callable.(Documentable).getJavadoc().getAChild() = paramTag and - ( if callable instanceof Constructor - then what = "constructor" - else what = "method" - ) and - if exists(paramTag.getParamName()) then ( + (if callable instanceof Constructor then what = "constructor" else what = "method") and + if exists(paramTag.getParamName()) + then ( // The tag's value is neither matched by a callable parameter name ... not callable.getAParameter().getName() = paramTag.getParamName() and // ... nor by a type parameter name. not exists(TypeVariable tv | tv.getGenericCallable() = callable | "<" + tv.getName() + ">" = paramTag.getParamName() ) and - msg = "@param tag \"" + paramTag.getParamName() - + "\" does not match any actual parameter of " + what + " \"" - + callable.getName() + "()\"." + msg = "@param tag \"" + paramTag.getParamName() + "\" does not match any actual parameter of " + + what + " \"" + callable.getName() + "()\"." ) else // The tag has no value at all. msg = "This @param tag does not have a value." diff --git a/java/ql/src/Advisory/Java Objects/AvoidCloneMethodAccess.ql b/java/ql/src/Advisory/Java Objects/AvoidCloneMethodAccess.ql index 732ebbe8de0..4d1a2875202 100644 --- a/java/ql/src/Advisory/Java Objects/AvoidCloneMethodAccess.ql +++ b/java/ql/src/Advisory/Java Objects/AvoidCloneMethodAccess.ql @@ -8,6 +8,7 @@ * @id java/use-of-clone-method * @tags reliability */ + import java class ObjectCloneMethod extends Method { diff --git a/java/ql/src/Advisory/Java Objects/AvoidCloneOverride.ql b/java/ql/src/Advisory/Java Objects/AvoidCloneOverride.ql index 4914dd8fdc6..1736708b35c 100644 --- a/java/ql/src/Advisory/Java Objects/AvoidCloneOverride.ql +++ b/java/ql/src/Advisory/Java Objects/AvoidCloneOverride.ql @@ -8,6 +8,7 @@ * @id java/override-of-clone-method * @tags reliability */ + import java class ObjectCloneMethod extends Method { diff --git a/java/ql/src/Advisory/Java Objects/AvoidCloneableInterface.ql b/java/ql/src/Advisory/Java Objects/AvoidCloneableInterface.ql index 3c4c1f227d2..02abef17130 100644 --- a/java/ql/src/Advisory/Java Objects/AvoidCloneableInterface.ql +++ b/java/ql/src/Advisory/Java Objects/AvoidCloneableInterface.ql @@ -8,6 +8,7 @@ * @id java/use-of-cloneable-interface * @tags reliability */ + import java from RefType t diff --git a/java/ql/src/Advisory/Java Objects/AvoidFinalizeOverride.ql b/java/ql/src/Advisory/Java Objects/AvoidFinalizeOverride.ql index de5aa3a9873..3b5ddefbb34 100644 --- a/java/ql/src/Advisory/Java Objects/AvoidFinalizeOverride.ql +++ b/java/ql/src/Advisory/Java Objects/AvoidFinalizeOverride.ql @@ -7,6 +7,7 @@ * @id java/override-of-finalize-method * @tags reliability */ + import java class ObjectFinalizeMethod extends Method { diff --git a/java/ql/src/Advisory/Naming/NamingConventionsConstants.ql b/java/ql/src/Advisory/Naming/NamingConventionsConstants.ql index 2d2b54d2d9e..4ee4bfd27cf 100644 --- a/java/ql/src/Advisory/Naming/NamingConventionsConstants.ql +++ b/java/ql/src/Advisory/Naming/NamingConventionsConstants.ql @@ -7,6 +7,7 @@ * @id java/misnamed-constant * @tags maintainability */ + import java import NamingConventionsCommon diff --git a/java/ql/src/Advisory/Naming/NamingConventionsMethods.ql b/java/ql/src/Advisory/Naming/NamingConventionsMethods.ql index 2be29008b65..a4347b783a0 100644 --- a/java/ql/src/Advisory/Naming/NamingConventionsMethods.ql +++ b/java/ql/src/Advisory/Naming/NamingConventionsMethods.ql @@ -7,6 +7,7 @@ * @id java/misnamed-function * @tags maintainability */ + import java from Method m diff --git a/java/ql/src/Advisory/Naming/NamingConventionsPackages.ql b/java/ql/src/Advisory/Naming/NamingConventionsPackages.ql index 7e99f055739..7d135b21fac 100644 --- a/java/ql/src/Advisory/Naming/NamingConventionsPackages.ql +++ b/java/ql/src/Advisory/Naming/NamingConventionsPackages.ql @@ -7,6 +7,7 @@ * @id java/misnamed-package * @tags maintainability */ + import java from RefType t, Package p @@ -14,4 +15,6 @@ where p = t.getPackage() and t.fromSource() and not p.getName().toLowerCase() = p.getName() -select t, "This type belongs to the package " + p.getName() + ", which should not include uppercase letters." +select t, + "This type belongs to the package " + p.getName() + + ", which should not include uppercase letters." diff --git a/java/ql/src/Advisory/Naming/NamingConventionsRefTypes.ql b/java/ql/src/Advisory/Naming/NamingConventionsRefTypes.ql index e52098b8da8..83093433123 100644 --- a/java/ql/src/Advisory/Naming/NamingConventionsRefTypes.ql +++ b/java/ql/src/Advisory/Naming/NamingConventionsRefTypes.ql @@ -7,6 +7,7 @@ * @id java/misnamed-type * @tags maintainability */ + import java from RefType t diff --git a/java/ql/src/Advisory/Naming/NamingConventionsVariables.ql b/java/ql/src/Advisory/Naming/NamingConventionsVariables.ql index 2339c165b53..bafa2ec5b14 100644 --- a/java/ql/src/Advisory/Naming/NamingConventionsVariables.ql +++ b/java/ql/src/Advisory/Naming/NamingConventionsVariables.ql @@ -7,6 +7,7 @@ * @id java/misnamed-variable * @tags maintainability */ + import java import NamingConventionsCommon diff --git a/java/ql/src/Advisory/Statements/OneStatementPerLine.ql b/java/ql/src/Advisory/Statements/OneStatementPerLine.ql index 50e1a927ca3..da8d7e3275a 100644 --- a/java/ql/src/Advisory/Statements/OneStatementPerLine.ql +++ b/java/ql/src/Advisory/Statements/OneStatementPerLine.ql @@ -7,12 +7,14 @@ * @id java/multiple-statements-on-same-line * @tags maintainability */ + import java predicate lineDefinesEnum(File f, int line) { exists(Location l | exists(EnumType e | e.getLocation() = l) or - exists(EnumConstant e | e.getLocation() = l) | + exists(EnumConstant e | e.getLocation() = l) + | f = l.getFile() and line = l.getStartLine() ) } diff --git a/java/ql/src/Advisory/Types/GenericsConstructor.ql b/java/ql/src/Advisory/Types/GenericsConstructor.ql index 613d78b6346..411c2466290 100644 --- a/java/ql/src/Advisory/Types/GenericsConstructor.ql +++ b/java/ql/src/Advisory/Types/GenericsConstructor.ql @@ -8,6 +8,7 @@ * @id java/raw-constructor-invocation * @tags maintainability */ + import java from ClassInstanceExpr cie diff --git a/java/ql/src/Advisory/Types/GenericsReturnType.ql b/java/ql/src/Advisory/Types/GenericsReturnType.ql index 1160dfc21a7..0107f7953a2 100644 --- a/java/ql/src/Advisory/Types/GenericsReturnType.ql +++ b/java/ql/src/Advisory/Types/GenericsReturnType.ql @@ -8,6 +8,7 @@ * @id java/raw-return-type * @tags maintainability */ + import java from Method m diff --git a/java/ql/src/Advisory/Types/GenericsVariable.ql b/java/ql/src/Advisory/Types/GenericsVariable.ql index ad0fa8cbc37..8f5fb3c05c9 100644 --- a/java/ql/src/Advisory/Types/GenericsVariable.ql +++ b/java/ql/src/Advisory/Types/GenericsVariable.ql @@ -8,6 +8,7 @@ * @id java/raw-variable * @tags maintainability */ + import java from Variable v diff --git a/java/ql/src/AlertSuppression.ql b/java/ql/src/AlertSuppression.ql index 142bf78e695..0cc44bc75b0 100644 --- a/java/ql/src/AlertSuppression.ql +++ b/java/ql/src/AlertSuppression.ql @@ -17,73 +17,61 @@ class SuppressionComment extends Javadoc { isEolComment(this) and exists(string text | text = getChild(0).getText() | // match `lgtm[...]` anywhere in the comment - annotation = text.regexpFind("(?i)\\blgtm\\s*\\[[^\\]]*\\]", _, _) - or + annotation = text.regexpFind("(?i)\\blgtm\\s*\\[[^\\]]*\\]", _, _) or // match `lgtm` at the start of the comment and after semicolon annotation = text.regexpFind("(?i)(?<=^|;)\\s*lgtm(?!\\B|\\s*\\[)", _, _).trim() ) } /** - * Gets the text of this suppression comment. - */ - string getText() { - result = getChild(0).getText() - } + * Gets the text of this suppression comment. + */ + string getText() { result = getChild(0).getText() } /** Gets the suppression annotation in this comment. */ - string getAnnotation() { - result = annotation - } + string getAnnotation() { result = annotation } /** - * Holds if this comment applies to the range from column `startcolumn` of line `startline` - * to column `endcolumn` of line `endline` in file `filepath`. - */ + * Holds if this comment applies to the range from column `startcolumn` of line `startline` + * to column `endcolumn` of line `endline` in file `filepath`. + */ predicate covers(string filepath, int startline, int startcolumn, int endline, int endcolumn) { this.getLocation().hasLocationInfo(filepath, startline, _, endline, endcolumn) and startcolumn = 1 } /** Gets the scope of this suppression. */ - SuppressionScope getScope() { - this = result.getSuppressionComment() - } + SuppressionScope getScope() { this = result.getSuppressionComment() } } /** * The scope of an alert suppression comment. */ class SuppressionScope extends @javadoc { - SuppressionScope() { - this instanceof SuppressionComment - } + SuppressionScope() { this instanceof SuppressionComment } /** Gets a suppression comment with this scope. */ - SuppressionComment getSuppressionComment() { - result = this - } + SuppressionComment getSuppressionComment() { result = this } /** - * Holds if this element is at the specified location. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `filepath`. - * For more information, see - * [LGTM locations](https://lgtm.com/help/ql/locations). - */ - predicate hasLocationInfo(string filepath, int startline, int startcolumn, int endline, int endcolumn) { + * Holds if this element is at the specified location. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `filepath`. + * For more information, see + * [LGTM locations](https://lgtm.com/help/ql/locations). + */ + predicate hasLocationInfo( + string filepath, int startline, int startcolumn, int endline, int endcolumn + ) { this.(SuppressionComment).covers(filepath, startline, startcolumn, endline, endcolumn) } /** Gets a textual representation of this element. */ - string toString() { - result = "suppression range" - } + string toString() { result = "suppression range" } } from SuppressionComment c -select - c, // suppression comment - c.getText(), // text of suppression comment (excluding delimiters) +select c, // suppression comment + c.getText(), // text of suppression comment (excluding delimiters) c.getAnnotation(), // text of suppression annotation - c.getScope() // scope of suppression + c.getScope() // scope of suppression diff --git a/java/ql/src/Architecture/Dependencies/MutualDependency.ql b/java/ql/src/Architecture/Dependencies/MutualDependency.ql index e86cc7216b6..c6ef88cd305 100644 --- a/java/ql/src/Architecture/Dependencies/MutualDependency.ql +++ b/java/ql/src/Architecture/Dependencies/MutualDependency.ql @@ -32,5 +32,4 @@ where t2.getAMethod().getName().toLowerCase().matches("%visit%") or t1.getPackage() = t2.getPackage() ) -select t1, "This type and type $@ are mutually dependent.", - t2, t2.getName() +select t1, "This type and type $@ are mutually dependent.", t2, t2.getName() diff --git a/java/ql/src/Architecture/Dependencies/UnusedMavenDependencyBinary.ql b/java/ql/src/Architecture/Dependencies/UnusedMavenDependencyBinary.ql index 021b17f3820..65d6250b340 100644 --- a/java/ql/src/Architecture/Dependencies/UnusedMavenDependencyBinary.ql +++ b/java/ql/src/Architecture/Dependencies/UnusedMavenDependencyBinary.ql @@ -9,47 +9,35 @@ import UnusedMavenDependencies -/* +/** * A whitelist of binary dependencies that should never be highlighted as unusued. */ predicate whitelist(Dependency d) { - /* - * jsr305 contains package annotations. If a project uses those exclusively, we will - * consider it "unused". - */ + // jsr305 contains package annotations. If a project uses those exclusively, we will + // consider it "unused". d.getShortCoordinate() = "com.google.code.findbugs:jsr305" } from PomDependency d, Pom source where -source.getADependency() = d and -/* - * There is not a Pom file for the target of this dependency, so we assume that it was resolved by - * a binary file in the local maven repository. - */ -not exists(Pom target | target = d.getPom()) and -/* - * In order to accurately identify whether this binary dependency is required, we must have identified - * a Maven repository. If we have not found a repository, it's likely that it has a custom path of - * which we are unaware, so do not report any problems. - */ -exists(MavenRepo mr) and -/* - * We either haven't indexed a relevant jar file, which suggests that nothing statically depended upon - * it, or we have indexed the relevant jar file, but no source code in the project defined by the pom - * depends on any code within the detected jar. - */ -not pomDependsOnContainer(source, d.getJar()) and -/* - * If something that depends on us depends on the jar represented by this dependency, and it doesn't - * depend directly on the jar itself, we don't consider it to be "unused". - */ -not exists(Pom pomThatDependsOnSource | - pomThatDependsOnSource.getAnExportedPom+() = source - | - pomDependsOnContainer(pomThatDependsOnSource, d.getJar()) and - not exists(File f | f = pomThatDependsOnSource.getADependency().getJar() and f = d.getJar())) and -// Filter out those dependencies on the whitelist -not whitelist(d) + source.getADependency() = d and + // There is not a Pom file for the target of this dependency, so we assume that it was resolved by + // a binary file in the local maven repository. + not exists(Pom target | target = d.getPom()) and + // In order to accurately identify whether this binary dependency is required, we must have identified + // a Maven repository. If we have not found a repository, it's likely that it has a custom path of + // which we are unaware, so do not report any problems. + exists(MavenRepo mr) and + // We either haven't indexed a relevant jar file, which suggests that nothing statically depended upon + // it, or we have indexed the relevant jar file, but no source code in the project defined by the pom + // depends on any code within the detected jar. + not pomDependsOnContainer(source, d.getJar()) and + // If something that depends on us depends on the jar represented by this dependency, and it doesn't + // depend directly on the jar itself, we don't consider it to be "unused". + not exists(Pom pomThatDependsOnSource | pomThatDependsOnSource.getAnExportedPom+() = source | + pomDependsOnContainer(pomThatDependsOnSource, d.getJar()) and + not exists(File f | f = pomThatDependsOnSource.getADependency().getJar() and f = d.getJar()) + ) and + // Filter out those dependencies on the whitelist + not whitelist(d) select d, "Maven dependency on the binary package " + d.getShortCoordinate() + " is unused." - diff --git a/java/ql/src/Architecture/Dependencies/UnusedMavenDependencySource.ql b/java/ql/src/Architecture/Dependencies/UnusedMavenDependencySource.ql index 55bf10e934c..ac8ec9471a9 100644 --- a/java/ql/src/Architecture/Dependencies/UnusedMavenDependencySource.ql +++ b/java/ql/src/Architecture/Dependencies/UnusedMavenDependencySource.ql @@ -13,22 +13,16 @@ import UnusedMavenDependencies from PomDependency d, Pom source, Pom target where -source.getADependency() = d and -/* - * We have a targetPom file, so this is a "source" dependency, rather than a binary dependency - * from the Maven repository. Note, although .pom files exist in the local maven repository, they - * are usually not indexed because they are outside the source directory. We assume that they have - * not been indexed. - */ -target = d.getPom() and -/* - * If we have a pom for the target of this dependency, then it is unused iff neither it, nor any - * of its transitive dependencies are required. - */ -not exists(Pom exported | - exported = target.getAnExportedPom*() - | - pomDependsOnContainer(source, exported.getAnExportedDependency().getJar()) or - pomDependsOnPom(source, exported) -) + source.getADependency() = d and + // We have a targetPom file, so this is a "source" dependency, rather than a binary dependency + // from the Maven repository. Note, although .pom files exist in the local maven repository, they + // are usually not indexed because they are outside the source directory. We assume that they have + // not been indexed. + target = d.getPom() and + // If we have a pom for the target of this dependency, then it is unused iff neither it, nor any + // of its transitive dependencies are required. + not exists(Pom exported | exported = target.getAnExportedPom*() | + pomDependsOnContainer(source, exported.getAnExportedDependency().getJar()) or + pomDependsOnPom(source, exported) + ) select d, "Maven dependency onto " + d.getShortCoordinate() + " is unused." diff --git a/java/ql/src/Architecture/Refactoring Opportunities/FeatureEnvy.ql b/java/ql/src/Architecture/Refactoring Opportunities/FeatureEnvy.ql index cfcdda20834..7e82206e9f0 100644 --- a/java/ql/src/Architecture/Refactoring Opportunities/FeatureEnvy.ql +++ b/java/ql/src/Architecture/Refactoring Opportunities/FeatureEnvy.ql @@ -10,6 +10,7 @@ * @tags maintainability * modularity */ + import java Member getAUsedMember(Method m) { @@ -21,9 +22,7 @@ int dependencyCount(Method source, RefType target) { result = strictcount(Member m | m = getAUsedMember(source) and m = target.getAMember()) } -predicate methodDependsOn(Method m, RefType target) { - exists(dependencyCount(m, target)) -} +predicate methodDependsOn(Method m, RefType target) { exists(dependencyCount(m, target)) } predicate dependsOn(RefType source, RefType target) { methodDependsOn(source.getACallable(), target) @@ -36,7 +35,7 @@ int selfDependencyCount(Method source) { predicate dependsHighlyOn(Method source, RefType target, int selfCount, int depCount) { depCount = dependencyCount(source, target) and selfCount = selfDependencyCount(source) and - depCount > 2*selfCount and + depCount > 2 * selfCount and depCount > 4 } @@ -69,6 +68,7 @@ where // Don't include types that are used from many different places - we only highlight // relatively local fixes that could reasonably be implemented. count(Method yetAnotherMethod | query(yetAnotherMethod, other, _, _)) < 10 -select m, "Method " + m.getName() + " is too closely tied to $@: " + depCount + - " dependencies to it, but only " + selfCount + " dependencies to its own type.", - other, other.getName() +select m, + "Method " + m.getName() + " is too closely tied to $@: " + depCount + + " dependencies to it, but only " + selfCount + " dependencies to its own type.", other, + other.getName() diff --git a/java/ql/src/Architecture/Refactoring Opportunities/HubClasses.ql b/java/ql/src/Architecture/Refactoring Opportunities/HubClasses.ql index dedb0d82649..d50e1d3b5d9 100644 --- a/java/ql/src/Architecture/Refactoring Opportunities/HubClasses.ql +++ b/java/ql/src/Architecture/Refactoring Opportunities/HubClasses.ql @@ -9,6 +9,7 @@ * @tags maintainability * modularity */ + import java from RefType t, int aff, int eff @@ -16,6 +17,8 @@ where t.fromSource() and aff = t.getMetrics().getAfferentCoupling() and eff = t.getMetrics().getEfferentSourceCoupling() and - aff > 15 and eff > 15 + aff > 15 and + eff > 15 select t as Class, - "Hub class: this class depends on " + eff.toString() + " classes and is used by " + aff.toString() + " classes." + "Hub class: this class depends on " + eff.toString() + " classes and is used by " + aff.toString() + + " classes." diff --git a/java/ql/src/Architecture/Refactoring Opportunities/InappropriateIntimacy.ql b/java/ql/src/Architecture/Refactoring Opportunities/InappropriateIntimacy.ql index d62212f9318..b7d797e7fa9 100644 --- a/java/ql/src/Architecture/Refactoring Opportunities/InappropriateIntimacy.ql +++ b/java/ql/src/Architecture/Refactoring Opportunities/InappropriateIntimacy.ql @@ -9,6 +9,7 @@ * @tags maintainability * modularity */ + import java predicate enclosingRefType(Variable v, RefType type) { @@ -60,5 +61,6 @@ where cb > 20 and ca >= cb and not exists(CompilationUnit cu | cu = a.getCompilationUnit() and cu = b.getCompilationUnit()) -select a, "Type " + a.getName() + " is too closely tied to $@ (" + ca.toString() + - " dependencies one way and " + cb.toString() + " the other).", b, b.getName() +select a, + "Type " + a.getName() + " is too closely tied to $@ (" + ca.toString() + + " dependencies one way and " + cb.toString() + " the other).", b, b.getName() diff --git a/java/ql/src/Compatibility/JDK9/JdkInternalAccess.ql b/java/ql/src/Compatibility/JDK9/JdkInternalAccess.ql index 5fdd1962901..7086a70d0bb 100644 --- a/java/ql/src/Compatibility/JDK9/JdkInternalAccess.ql +++ b/java/ql/src/Compatibility/JDK9/JdkInternalAccess.ql @@ -8,6 +8,7 @@ * @id java/jdk-internal-api-access * @tags maintainability */ + import java import JdkInternals import JdkInternalsReplacement @@ -24,72 +25,83 @@ predicate importedPackage(Import i, Package p) { } predicate typeReplacement(RefType t, string repl) { - exists(string old | jdkInternalReplacement(old, repl) | - t.getQualifiedName() = old - ) + exists(string old | jdkInternalReplacement(old, repl) | t.getQualifiedName() = old) } predicate packageReplacementForType(RefType t, string repl) { exists(string old, string pkgName | jdkInternalReplacement(old, repl) and t.getPackage().getName() = pkgName - | + | pkgName = old or - pkgName.prefix(old.length()+1) = old + "." + pkgName.prefix(old.length() + 1) = old + "." ) } predicate packageReplacement(Package p, string repl) { exists(string old | jdkInternalReplacement(old, repl) | p.getName() = old or - p.getName().prefix(old.length()+1) = old + "." + p.getName().prefix(old.length() + 1) = old + "." ) } predicate replacement(RefType t, string repl) { - typeReplacement(t, repl) or + typeReplacement(t, repl) + or not typeReplacement(t, _) and packageReplacementForType(t, repl) } abstract class JdkInternalAccess extends Element { abstract string getAccessedApi(); + abstract string getReplacement(); } class JdkInternalTypeAccess extends JdkInternalAccess, TypeAccess { - JdkInternalTypeAccess() { - jdkInternalApi(this.getType().(RefType).getPackage().getName()) - } - override string getAccessedApi() { - result = getType().(RefType).getQualifiedName() - } + JdkInternalTypeAccess() { jdkInternalApi(this.getType().(RefType).getPackage().getName()) } + + override string getAccessedApi() { result = getType().(RefType).getQualifiedName() } + override string getReplacement() { exists(RefType t | this.getType() = t | - (replacement(t, result) or not replacement(t, _) and result = "unknown") + ( + replacement(t, result) + or + not replacement(t, _) and result = "unknown" + ) ) } } class JdkInternalImport extends JdkInternalAccess, Import { JdkInternalImport() { - exists(RefType t | importedType(this, t) | - jdkInternalApi(t.getPackage().getName()) - ) or - exists(Package p | importedPackage(this, p) | - jdkInternalApi(p.getName()) - ) + exists(RefType t | importedType(this, t) | jdkInternalApi(t.getPackage().getName())) + or + exists(Package p | importedPackage(this, p) | jdkInternalApi(p.getName())) } + override string getAccessedApi() { - exists(RefType t | result = t.getQualifiedName() | importedType(this, t)) or + exists(RefType t | result = t.getQualifiedName() | importedType(this, t)) + or exists(Package p | result = p.getName() | importedPackage(this, p)) } + override string getReplacement() { exists(RefType t | importedType(this, t) and - (replacement(t, result) or not replacement(t, _) and result = "unknown") - ) or + ( + replacement(t, result) + or + not replacement(t, _) and result = "unknown" + ) + ) + or exists(Package p | importedPackage(this, p) and - (packageReplacement(p, result) or not packageReplacement(p, _) and result = "unknown") + ( + packageReplacement(p, result) + or + not packageReplacement(p, _) and result = "unknown" + ) ) } } @@ -97,8 +109,8 @@ class JdkInternalImport extends JdkInternalAccess, Import { predicate jdkPackage(Package p) { exists(string pkgName | p.getName() = pkgName or - p.getName().prefix(pkgName.length()+1) = pkgName + "." - | + p.getName().prefix(pkgName.length() + 1) = pkgName + "." + | pkgName = "com.sun" or pkgName = "sun" or pkgName = "java" or @@ -115,7 +127,7 @@ predicate jdkPackage(Package p) { from JdkInternalAccess ta, string repl, string msg where repl = ta.getReplacement() and - (if (repl="unknown") then msg = "" else msg = " (" + repl + ")") and + (if (repl = "unknown") then msg = "" else msg = " (" + repl + ")") and not jdkInternalApi(ta.getCompilationUnit().getPackage().getName()) and not jdkPackage(ta.getCompilationUnit().getPackage()) select ta, "Access to unsupported JDK-internal API '" + ta.getAccessedApi() + "'." + msg diff --git a/java/ql/src/Compatibility/JDK9/UnderscoreIdentifier.ql b/java/ql/src/Compatibility/JDK9/UnderscoreIdentifier.ql index 2fef4eaa528..9e92b6b761f 100644 --- a/java/ql/src/Compatibility/JDK9/UnderscoreIdentifier.ql +++ b/java/ql/src/Compatibility/JDK9/UnderscoreIdentifier.ql @@ -8,6 +8,7 @@ * @id java/underscore-identifier * @tags maintainability */ + import java class IdentifierElement extends Element { diff --git a/java/ql/src/Complexity/BlockWithTooManyStatements.ql b/java/ql/src/Complexity/BlockWithTooManyStatements.ql index f2719f586d5..f1bdce1f0ab 100644 --- a/java/ql/src/Complexity/BlockWithTooManyStatements.ql +++ b/java/ql/src/Complexity/BlockWithTooManyStatements.ql @@ -10,6 +10,7 @@ * testability * complexity */ + import java class ComplexStmt extends Stmt { diff --git a/java/ql/src/Complexity/ComplexCondition.ql b/java/ql/src/Complexity/ComplexCondition.ql index 3c46be68f76..e8f7b67f35e 100644 --- a/java/ql/src/Complexity/ComplexCondition.ql +++ b/java/ql/src/Complexity/ComplexCondition.ql @@ -8,6 +8,7 @@ * @tags testability * readability */ + import java predicate nontrivialLogicalOperator(BinaryExpr e) { diff --git a/java/ql/src/DeadCode/DeadClass.ql b/java/ql/src/DeadCode/DeadClass.ql index 038a7fdfca3..8a1b5e0be77 100644 --- a/java/ql/src/DeadCode/DeadClass.ql +++ b/java/ql/src/DeadCode/DeadClass.ql @@ -9,27 +9,28 @@ * useless-code * external/cwe/cwe-561 */ + import semmle.code.java.deadcode.DeadCode from DeadClass c, Element origin, string reason where - if exists(DeadRoot root | root = c.getADeadRoot() | not root = c.getACallable()) then ( - // Report a list of the dead roots. - origin = c.getADeadRoot() and - not origin = c.getACallable() and - // There are uses of this class from outside the class. - reason = " is only used from dead code originating at $@." + if exists(DeadRoot root | root = c.getADeadRoot() | not root = c.getACallable()) + then ( + // Report a list of the dead roots. + origin = c.getADeadRoot() and + not origin = c.getACallable() and + // There are uses of this class from outside the class. + reason = " is only used from dead code originating at $@." ) else ( // There are no dead roots outside this class. origin = c and - if c.isUnusedOutsideClass() then + if c.isUnusedOutsideClass() + then // Never accessed outside this class, so it's entirely unused. reason = " is entirely unused." else - /* - * There are no dead roots outside the class, but the class has a possible liveness cause - * external to the class, so it must be accessed from at least one dead-code cycle. - */ + // There are no dead roots outside the class, but the class has a possible liveness cause + // external to the class, so it must be accessed from at least one dead-code cycle. reason = " is only used from or in a dead-code cycle." ) select c, "The class " + c.getName() + reason, origin, origin.getName() diff --git a/java/ql/src/DeadCode/DeadField.ql b/java/ql/src/DeadCode/DeadField.ql index 992e18cd440..8981926833a 100644 --- a/java/ql/src/DeadCode/DeadField.ql +++ b/java/ql/src/DeadCode/DeadField.ql @@ -16,8 +16,13 @@ import semmle.code.java.deadcode.DeadCode from DeadField f, Element origin, string reason where not f.isInDeadScope() and - if exists(FieldRead read | read = f.getAnAccess()) then ( - if exists(DeadRoot root | root = getADeadRoot(f.getAnAccess().(FieldRead).getEnclosingCallable())) then ( + if exists(FieldRead read | read = f.getAnAccess()) + then ( + if + exists(DeadRoot root | + root = getADeadRoot(f.getAnAccess().(FieldRead).getEnclosingCallable()) + ) + then ( origin = getADeadRoot(f.getAnAccess().(FieldRead).getEnclosingCallable()) and reason = " is only read from dead code originating at $@." ) else ( diff --git a/java/ql/src/DeadCode/DeadMethod.ql b/java/ql/src/DeadCode/DeadMethod.ql index ee27a18cd9a..8b5d0f155ef 100644 --- a/java/ql/src/DeadCode/DeadMethod.ql +++ b/java/ql/src/DeadCode/DeadMethod.ql @@ -9,25 +9,30 @@ * useless-code * external/cwe/cwe-561 */ + import java import semmle.code.java.deadcode.DeadCode from DeadMethod c, Callable origin, string reason where not c.isInDeadScope() and - if exists(DeadRoot deadRoot | deadRoot = getADeadRoot(c) | deadRoot.getSourceDeclaration() != c) then ( + if exists(DeadRoot deadRoot | deadRoot = getADeadRoot(c) | deadRoot.getSourceDeclaration() != c) + then ( // We've found a dead root that is not this callable (or an instantiation thereof). origin = getADeadRoot(c).getSourceDeclaration() and reason = " is only used from dead code originating at $@." ) else ( origin = c and - if exists(Callable cause | cause = possibleLivenessCause(c) and not cause instanceof DeadRoot | - cause.getSourceDeclaration() = c implies possibleLivenessCause(cause).getSourceDeclaration() != c) + if + exists(Callable cause | cause = possibleLivenessCause(c) and not cause instanceof DeadRoot | + cause.getSourceDeclaration() = c + implies + possibleLivenessCause(cause).getSourceDeclaration() != c + ) then // There are no dead roots that are not this callable (or an instantiation thereof), and at least one // liveness cause (ignoring trivial cycles between a parameterized callable and its source declaration). reason = " is only used from, or in, a dead-code cycle." - else - reason = " is entirely unused." + else reason = " is entirely unused." ) select c, "The method " + c.getName() + reason, origin, origin.getName() diff --git a/java/ql/src/DeadCode/FLinesOfDeadCode.ql b/java/ql/src/DeadCode/FLinesOfDeadCode.ql index 4404a6b8d25..c5f209d557e 100644 --- a/java/ql/src/DeadCode/FLinesOfDeadCode.ql +++ b/java/ql/src/DeadCode/FLinesOfDeadCode.ql @@ -9,6 +9,7 @@ * @tags maintainability * external/cwe/cwe-561 */ + import java import semmle.code.java.deadcode.DeadCode @@ -16,35 +17,42 @@ from File f, int n where n = // Lines of code contributed by dead classes. - sum(DeadClass deadClass | deadClass.getFile() = f | - deadClass.getNumberOfLinesOfCode() - - /* - * Remove inner and local classes, as they are reported as separate dead classes. Do not - * remove anonymous classes, because they aren't reported separately. - */ - sum(NestedClass innerClass | innerClass.getEnclosingType() = deadClass and not innerClass.isAnonymous() | - innerClass.getNumberOfLinesOfCode() + sum(DeadClass deadClass | + deadClass.getFile() = f + | + deadClass.getNumberOfLinesOfCode() - + // Remove inner and local classes, as they are reported as separate dead classes. Do not + // remove anonymous classes, because they aren't reported separately. + sum(NestedClass innerClass | + innerClass.getEnclosingType() = deadClass and not innerClass.isAnonymous() + | + innerClass.getNumberOfLinesOfCode() + ) + ) + + // Lines of code contributed by dead methods, not in dead classes. + sum(DeadMethod deadMethod | + deadMethod.getFile() = f and not deadMethod.isInDeadScope() + | + deadMethod.getNumberOfLinesOfCode() - + // Remove local classes defined in the dead method - they are reported separately as a dead + // class. We keep anonymous class counts, because anonymous classes are not reported + // separately. + sum(LocalClass localClass | + localClass.getLocalClassDeclStmt().getEnclosingCallable() = deadMethod + | + localClass.getNumberOfLinesOfCode() + ) + ) + + // Lines of code contributed by dead fields, not in dead classes. + sum(DeadField deadField | + deadField.getFile() = f and not deadField.isInDeadScope() + | + deadField.getNumberOfLinesOfCode() + ) + + // Lines of code contributed by unused enum constants. + sum(UnusedEnumConstant deadEnumConstant | + deadEnumConstant.getFile() = f + | + deadEnumConstant.getNumberOfLinesOfCode() ) - ) + - // Lines of code contributed by dead methods, not in dead classes. - sum(DeadMethod deadMethod | deadMethod.getFile() = f and not deadMethod.isInDeadScope() | - deadMethod.getNumberOfLinesOfCode() - - /* - * Remove local classes defined in the dead method - they are reported separately as a dead - * class. We keep anonymous class counts, because anonymous classes are not reported - * separately. - */ - sum(LocalClass localClass | localClass.getLocalClassDeclStmt().getEnclosingCallable() = deadMethod | - localClass.getNumberOfLinesOfCode() - ) - ) + - // Lines of code contributed by dead fields, not in dead classes. - sum(DeadField deadField | deadField.getFile() = f and not deadField.isInDeadScope() | - deadField.getNumberOfLinesOfCode() - ) + - // Lines of code contributed by unused enum constants. - sum(UnusedEnumConstant deadEnumConstant | deadEnumConstant.getFile() = f | - deadEnumConstant.getNumberOfLinesOfCode() - ) -select f, n -order by n desc +select f, n order by n desc diff --git a/java/ql/src/DeadCode/UselessParameter.ql b/java/ql/src/DeadCode/UselessParameter.ql index b7b4e66c901..71e9d2606fa 100644 --- a/java/ql/src/DeadCode/UselessParameter.ql +++ b/java/ql/src/DeadCode/UselessParameter.ql @@ -9,6 +9,7 @@ * useless-code * external/cwe/cwe-561 */ + import semmle.code.java.deadcode.DeadCode from RootdefCallable c diff --git a/java/ql/src/Frameworks/JavaEE/EJB/EjbContainerInterference.ql b/java/ql/src/Frameworks/JavaEE/EJB/EjbContainerInterference.ql index 71f145f34e4..79dd15510e8 100644 --- a/java/ql/src/Frameworks/JavaEE/EJB/EjbContainerInterference.ql +++ b/java/ql/src/Frameworks/JavaEE/EJB/EjbContainerInterference.ql @@ -13,25 +13,26 @@ * external/cwe/cwe-578 * external/cwe/cwe-382 */ + import java import semmle.code.java.frameworks.javaee.ejb.EJB import semmle.code.java.frameworks.javaee.ejb.EJBRestrictions /* -JSR 220: Enterprise JavaBeansTM,Version 3.0 -EJB Core Contracts and Requirements -Section 21.1.2 Programming Restrictions - -- The enterprise bean must not attempt to create a class loader; obtain the current class loader; -set the context class loader; set security manager; create a new security manager; stop the -JVM; or change the input, output, and error streams. - -These functions are reserved for the EJB container. Allowing the enterprise bean to use these functions -could compromise security and decrease the container's ability to properly manage the runtime envi- -ronment. -*/ + * JSR 220: Enterprise JavaBeansTM,Version 3.0 + * EJB Core Contracts and Requirements + * Section 21.1.2 Programming Restrictions + * + * - The enterprise bean must not attempt to create a class loader; obtain the current class loader; + * set the context class loader; set security manager; create a new security manager; stop the + * JVM; or change the input, output, and error streams. + * + * These functions are reserved for the EJB container. Allowing the enterprise bean to use these functions + * could compromise security and decrease the container's ability to properly manage the runtime envi- + * ronment. + */ from Callable origin, ForbiddenContainerInterferenceCallable target, Call call where ejbCalls(origin, target, call) -select origin, "EJB should not interfere with its container's operation by calling $@.", - call, target.getDeclaringType().getName() + "." + target.getName() +select origin, "EJB should not interfere with its container's operation by calling $@.", call, + target.getDeclaringType().getName() + "." + target.getName() diff --git a/java/ql/src/Frameworks/JavaEE/EJB/EjbFileIO.ql b/java/ql/src/Frameworks/JavaEE/EJB/EjbFileIO.ql index 7b39f3b5c65..51f0105cb07 100644 --- a/java/ql/src/Frameworks/JavaEE/EJB/EjbFileIO.ql +++ b/java/ql/src/Frameworks/JavaEE/EJB/EjbFileIO.ql @@ -10,27 +10,28 @@ * @tags reliability * external/cwe/cwe-576 */ + import java import semmle.code.java.frameworks.javaee.ejb.EJB import semmle.code.java.frameworks.javaee.ejb.EJBRestrictions /* -JSR 220: Enterprise JavaBeansTM,Version 3.0 -EJB Core Contracts and Requirements -Section 21.1.2 Programming Restrictions - -- An enterprise bean must not use the java.io package to attempt to access files and directo- -ries in the file system. - -The file system APIs are not well-suited for business components to access data. Business components -should use a resource manager API, such as JDBC, to store data. - -- The enterprise bean must not attempt to directly read or write a file descriptor. - -Allowing the enterprise bean to read and write file descriptors directly could compromise security. -*/ + * JSR 220: Enterprise JavaBeansTM,Version 3.0 + * EJB Core Contracts and Requirements + * Section 21.1.2 Programming Restrictions + * + * - An enterprise bean must not use the java.io package to attempt to access files and directo- + * ries in the file system. + * + * The file system APIs are not well-suited for business components to access data. Business components + * should use a resource manager API, such as JDBC, to store data. + * + * - The enterprise bean must not attempt to directly read or write a file descriptor. + * + * Allowing the enterprise bean to read and write file descriptors directly could compromise security. + */ from Callable origin, ForbiddenFileCallable target, Call call where ejbCalls(origin, target, call) -select origin, "EJB should not access the file system by calling $@.", - call, target.getDeclaringType().getName() + "." + target.getName() +select origin, "EJB should not access the file system by calling $@.", call, + target.getDeclaringType().getName() + "." + target.getName() diff --git a/java/ql/src/Frameworks/JavaEE/EJB/EjbGraphics.ql b/java/ql/src/Frameworks/JavaEE/EJB/EjbGraphics.ql index cdda4120b48..3d155d415b3 100644 --- a/java/ql/src/Frameworks/JavaEE/EJB/EjbGraphics.ql +++ b/java/ql/src/Frameworks/JavaEE/EJB/EjbGraphics.ql @@ -10,23 +10,24 @@ * @tags reliability * external/cwe/cwe-575 */ + import java import semmle.code.java.frameworks.javaee.ejb.EJB import semmle.code.java.frameworks.javaee.ejb.EJBRestrictions /* -JSR 220: Enterprise JavaBeansTM,Version 3.0 -EJB Core Contracts and Requirements -Section 21.1.2 Programming Restrictions - -- An enterprise bean must not use the AWT functionality to attempt to output information to a -display, or to input information from a keyboard. - -Most servers do not allow direct interaction between an application program and a keyboard/display -attached to the server system. -*/ + * JSR 220: Enterprise JavaBeansTM,Version 3.0 + * EJB Core Contracts and Requirements + * Section 21.1.2 Programming Restrictions + * + * - An enterprise bean must not use the AWT functionality to attempt to output information to a + * display, or to input information from a keyboard. + * + * Most servers do not allow direct interaction between an application program and a keyboard/display + * attached to the server system. + */ from Callable origin, ForbiddenGraphicsCallable target, Call call where ejbCalls(origin, target, call) -select origin, "EJB should not use AWT or other graphics functionality by $@.", - call, target.getDeclaringType().getName() + "." + target.getName() +select origin, "EJB should not use AWT or other graphics functionality by $@.", call, + target.getDeclaringType().getName() + "." + target.getName() diff --git a/java/ql/src/Frameworks/JavaEE/EJB/EjbNative.ql b/java/ql/src/Frameworks/JavaEE/EJB/EjbNative.ql index d8272e1d5d9..16736a1669e 100644 --- a/java/ql/src/Frameworks/JavaEE/EJB/EjbNative.ql +++ b/java/ql/src/Frameworks/JavaEE/EJB/EjbNative.ql @@ -9,22 +9,23 @@ * @tags reliability * external/cwe/cwe-573 */ + import java import semmle.code.java.frameworks.javaee.ejb.EJB import semmle.code.java.frameworks.javaee.ejb.EJBRestrictions /* -JSR 220: Enterprise JavaBeansTM,Version 3.0 -EJB Core Contracts and Requirements -Section 21.1.2 Programming Restrictions - -- The enterprise bean must not attempt to load a native library. - -This function is reserved for the EJB container. Allowing the enterprise bean to load native code would -create a security hole. -*/ + * JSR 220: Enterprise JavaBeansTM,Version 3.0 + * EJB Core Contracts and Requirements + * Section 21.1.2 Programming Restrictions + * + * - The enterprise bean must not attempt to load a native library. + * + * This function is reserved for the EJB container. Allowing the enterprise bean to load native code would + * create a security hole. + */ from Callable origin, ForbiddenNativeCallable target, Call call where ejbCalls(origin, target, call) -select origin, "EJB should not use native code by calling $@.", - call, target.getDeclaringType().getName() + "." + target.getName() +select origin, "EJB should not use native code by calling $@.", call, + target.getDeclaringType().getName() + "." + target.getName() diff --git a/java/ql/src/Frameworks/JavaEE/EJB/EjbReflection.ql b/java/ql/src/Frameworks/JavaEE/EJB/EjbReflection.ql index b22543b9acd..fa28edc7393 100644 --- a/java/ql/src/Frameworks/JavaEE/EJB/EjbReflection.ql +++ b/java/ql/src/Frameworks/JavaEE/EJB/EjbReflection.ql @@ -8,25 +8,26 @@ * @id java/ejb/reflection * @tags external/cwe/cwe-573 */ + import java import semmle.code.java.frameworks.javaee.ejb.EJB import semmle.code.java.frameworks.javaee.ejb.EJBRestrictions /* -JSR 220: Enterprise JavaBeansTM,Version 3.0 -EJB Core Contracts and Requirements -Section 21.1.2 Programming Restrictions - -- The enterprise bean must not attempt to query a class to obtain information about the declared -members that are not otherwise accessible to the enterprise bean because of the security rules -of the Java language. The enterprise bean must not attempt to use the Reflection API to access -information that the security rules of the Java programming language make unavailable. - -Allowing the enterprise bean to access information about other classes and to access the classes in a -manner that is normally disallowed by the Java programming language could compromise security. -*/ + * JSR 220: Enterprise JavaBeansTM,Version 3.0 + * EJB Core Contracts and Requirements + * Section 21.1.2 Programming Restrictions + * + * - The enterprise bean must not attempt to query a class to obtain information about the declared + * members that are not otherwise accessible to the enterprise bean because of the security rules + * of the Java language. The enterprise bean must not attempt to use the Reflection API to access + * information that the security rules of the Java programming language make unavailable. + * + * Allowing the enterprise bean to access information about other classes and to access the classes in a + * manner that is normally disallowed by the Java programming language could compromise security. + */ from Callable origin, ForbiddenReflectionCallable target, Call call where ejbCalls(origin, target, call) -select origin, "EJB should not use reflection by calling $@.", - call, target.getDeclaringType().getName() + "." + target.getName() +select origin, "EJB should not use reflection by calling $@.", call, + target.getDeclaringType().getName() + "." + target.getName() diff --git a/java/ql/src/Frameworks/JavaEE/EJB/EjbSecurityConfiguration.ql b/java/ql/src/Frameworks/JavaEE/EJB/EjbSecurityConfiguration.ql index 17f549d3dce..eb08dcb8060 100644 --- a/java/ql/src/Frameworks/JavaEE/EJB/EjbSecurityConfiguration.ql +++ b/java/ql/src/Frameworks/JavaEE/EJB/EjbSecurityConfiguration.ql @@ -9,28 +9,29 @@ * @id java/ejb/security-configuration-access * @tags external/cwe/cwe-573 */ + import java import semmle.code.java.frameworks.javaee.ejb.EJB import semmle.code.java.frameworks.javaee.ejb.EJBRestrictions /* -JSR 220: Enterprise JavaBeansTM,Version 3.0 -EJB Core Contracts and Requirements -Section 21.1.2 Programming Restrictions - -- The enterprise bean must not attempt to obtain the security policy information for a particular -code source. - -Allowing the enterprise bean to access the security policy information would create a security hole. - -- The enterprise bean must not attempt to access or modify the security configuration objects -(Policy, Security, Provider, Signer, and Identity). - -These functions are reserved for the EJB container. Allowing the enterprise bean to use these functions -could compromise security. -*/ + * JSR 220: Enterprise JavaBeansTM,Version 3.0 + * EJB Core Contracts and Requirements + * Section 21.1.2 Programming Restrictions + * + * - The enterprise bean must not attempt to obtain the security policy information for a particular + * code source. + * + * Allowing the enterprise bean to access the security policy information would create a security hole. + * + * - The enterprise bean must not attempt to access or modify the security configuration objects + * (Policy, Security, Provider, Signer, and Identity). + * + * These functions are reserved for the EJB container. Allowing the enterprise bean to use these functions + * could compromise security. + */ from Callable origin, ForbiddenSecurityConfigurationCallable target, Call call where ejbCalls(origin, target, call) -select origin, "EJB should not access a security configuration by calling $@.", - call, target.getDeclaringType().getName() + "." + target.getName() +select origin, "EJB should not access a security configuration by calling $@.", call, + target.getDeclaringType().getName() + "." + target.getName() diff --git a/java/ql/src/Frameworks/JavaEE/EJB/EjbSerialization.ql b/java/ql/src/Frameworks/JavaEE/EJB/EjbSerialization.ql index 08954d27a04..d6e5c1fc9b1 100644 --- a/java/ql/src/Frameworks/JavaEE/EJB/EjbSerialization.ql +++ b/java/ql/src/Frameworks/JavaEE/EJB/EjbSerialization.ql @@ -8,22 +8,23 @@ * @id java/ejb/substitution-in-serialization * @tags external/cwe/cwe-573 */ + import java import semmle.code.java.frameworks.javaee.ejb.EJB import semmle.code.java.frameworks.javaee.ejb.EJBRestrictions /* -JSR 220: Enterprise JavaBeansTM,Version 3.0 -EJB Core Contracts and Requirements -Section 21.1.2 Programming Restrictions - -- The enterprise bean must not attempt to use the subclass and object substitution features of the -Java Serialization Protocol. - -Allowing the enterprise bean to use these functions could compromise security. -*/ + * JSR 220: Enterprise JavaBeansTM,Version 3.0 + * EJB Core Contracts and Requirements + * Section 21.1.2 Programming Restrictions + * + * - The enterprise bean must not attempt to use the subclass and object substitution features of the + * Java Serialization Protocol. + * + * Allowing the enterprise bean to use these functions could compromise security. + */ from Callable origin, ForbiddenSerializationCallable target, Call call where ejbCalls(origin, target, call) -select origin, "EJB should not use a substitution feature of serialization by calling $@.", - call, target.getDeclaringType().getName() + "." + target.getName() + " $@" +select origin, "EJB should not use a substitution feature of serialization by calling $@.", call, + target.getDeclaringType().getName() + "." + target.getName() + " $@" diff --git a/java/ql/src/Frameworks/JavaEE/EJB/EjbSetSocketOrUrlFactory.ql b/java/ql/src/Frameworks/JavaEE/EJB/EjbSetSocketOrUrlFactory.ql index f27f4e18c3a..4a1524ee1b3 100644 --- a/java/ql/src/Frameworks/JavaEE/EJB/EjbSetSocketOrUrlFactory.ql +++ b/java/ql/src/Frameworks/JavaEE/EJB/EjbSetSocketOrUrlFactory.ql @@ -10,24 +10,25 @@ * @tags reliability * external/cwe/cwe-577 */ + import java import semmle.code.java.frameworks.javaee.ejb.EJB import semmle.code.java.frameworks.javaee.ejb.EJBRestrictions /* -JSR 220: Enterprise JavaBeansTM,Version 3.0 -EJB Core Contracts and Requirements -Section 21.1.2 Programming Restrictions - -- The enterprise bean must not attempt to set the socket factory used by ServerSocket, Socket, or -the stream handler factory used by URL. - -These networking functions are reserved for the EJB container. Allowing the enterprise bean to use -these functions could compromise security and decrease the container's ability to properly manage the -runtime environment. -*/ + * JSR 220: Enterprise JavaBeansTM,Version 3.0 + * EJB Core Contracts and Requirements + * Section 21.1.2 Programming Restrictions + * + * - The enterprise bean must not attempt to set the socket factory used by ServerSocket, Socket, or + * the stream handler factory used by URL. + * + * These networking functions are reserved for the EJB container. Allowing the enterprise bean to use + * these functions could compromise security and decrease the container's ability to properly manage the + * runtime environment. + */ from Callable origin, ForbiddenSetFactoryCallable target, Call call where ejbCalls(origin, target, call) -select origin, "EJB should not set a factory by calling $@.", - call, target.getDeclaringType().getName() + "." + target.getName() +select origin, "EJB should not set a factory by calling $@.", call, + target.getDeclaringType().getName() + "." + target.getName() diff --git a/java/ql/src/Frameworks/JavaEE/EJB/EjbSocketAsServer.ql b/java/ql/src/Frameworks/JavaEE/EJB/EjbSocketAsServer.ql index a1c5bff5d55..46f1edee9a4 100644 --- a/java/ql/src/Frameworks/JavaEE/EJB/EjbSocketAsServer.ql +++ b/java/ql/src/Frameworks/JavaEE/EJB/EjbSocketAsServer.ql @@ -10,24 +10,25 @@ * @tags reliability * external/cwe/cwe-577 */ + import java import semmle.code.java.frameworks.javaee.ejb.EJB import semmle.code.java.frameworks.javaee.ejb.EJBRestrictions /* -JSR 220: Enterprise JavaBeansTM,Version 3.0 -EJB Core Contracts and Requirements -Section 21.1.2 Programming Restrictions - -- An enterprise bean must not attempt to listen on a socket, accept connections on a socket, or -use a socket for multicast. - -The EJB architecture allows an enterprise bean instance to be a network socket client, but it does not -allow it to be a network server. Allowing the instance to become a network server would conflict with -the basic function of the enterprise bean -- to serve the EJB clients. -*/ + * JSR 220: Enterprise JavaBeansTM,Version 3.0 + * EJB Core Contracts and Requirements + * Section 21.1.2 Programming Restrictions + * + * - An enterprise bean must not attempt to listen on a socket, accept connections on a socket, or + * use a socket for multicast. + * + * The EJB architecture allows an enterprise bean instance to be a network socket client, but it does not + * allow it to be a network server. Allowing the instance to become a network server would conflict with + * the basic function of the enterprise bean -- to serve the EJB clients. + */ from Callable origin, ForbiddenServerSocketCallable target, Call call where ejbCalls(origin, target, call) -select origin, "EJB should not use a socket as a server by calling $@.", - call, target.getDeclaringType().getName() + "." + target.getName() +select origin, "EJB should not use a socket as a server by calling $@.", call, + target.getDeclaringType().getName() + "." + target.getName() diff --git a/java/ql/src/Frameworks/JavaEE/EJB/EjbStaticFieldNonFinal.ql b/java/ql/src/Frameworks/JavaEE/EJB/EjbStaticFieldNonFinal.ql index 3bc0bc8d4fa..18e7c6cbd26 100644 --- a/java/ql/src/Frameworks/JavaEE/EJB/EjbStaticFieldNonFinal.ql +++ b/java/ql/src/Frameworks/JavaEE/EJB/EjbStaticFieldNonFinal.ql @@ -10,29 +10,29 @@ * @tags reliability * external/cwe/cwe-573 */ + import java import semmle.code.java.frameworks.javaee.ejb.EJB import semmle.code.java.frameworks.javaee.ejb.EJBRestrictions /* -JSR 220: Enterprise JavaBeansTM,Version 3.0 -EJB Core Contracts and Requirements -Section 21.1.2 Programming Restrictions - -- An enterprise bean must not use read/write static fields. Using read-only static fields is -allowed. Therefore, it is recommended that all static fields in the enterprise bean class be -declared as final. - -This rule is required to ensure consistent runtime semantics because while some EJB containers may -use a single JVM to execute all enterprise bean's instances, others may distribute the instances across -multiple JVMs. -*/ + * JSR 220: Enterprise JavaBeansTM,Version 3.0 + * EJB Core Contracts and Requirements + * Section 21.1.2 Programming Restrictions + * + * - An enterprise bean must not use read/write static fields. Using read-only static fields is + * allowed. Therefore, it is recommended that all static fields in the enterprise bean class be + * declared as final. + * + * This rule is required to ensure consistent runtime semantics because while some EJB containers may + * use a single JVM to execute all enterprise bean's instances, others may distribute the instances across + * multiple JVMs. + */ from Callable origin, ForbiddenStaticFieldCallable target, Call call, FieldAccess fa, Field f where ejbCalls(origin, target, call) and fa = forbiddenStaticFieldUse(target) and fa.getField() = f -select origin, "EJB should not access non-final static field $@ $@.", - f, f.getDeclaringType().getName() + "." + f.getName(), - fa, "here" +select origin, "EJB should not access non-final static field $@ $@.", f, + f.getDeclaringType().getName() + "." + f.getName(), fa, "here" diff --git a/java/ql/src/Frameworks/JavaEE/EJB/EjbSynchronization.ql b/java/ql/src/Frameworks/JavaEE/EJB/EjbSynchronization.ql index 8f2207a614e..3b16ff0a142 100644 --- a/java/ql/src/Frameworks/JavaEE/EJB/EjbSynchronization.ql +++ b/java/ql/src/Frameworks/JavaEE/EJB/EjbSynchronization.ql @@ -9,23 +9,24 @@ * @tags reliability * external/cwe/cwe-574 */ + import java import semmle.code.java.frameworks.javaee.ejb.EJB import semmle.code.java.frameworks.javaee.ejb.EJBRestrictions /* -JSR 220: Enterprise JavaBeansTM,Version 3.0 -EJB Core Contracts and Requirements -Section 21.1.2 Programming Restrictions - -- An enterprise bean must not use thread synchronization primitives to synchronize execution of -multiple instances. - -This is for the same reason as above. Synchronization would not work if the EJB container distributed -enterprise bean's instances across multiple JVMs. -*/ + * JSR 220: Enterprise JavaBeansTM,Version 3.0 + * EJB Core Contracts and Requirements + * Section 21.1.2 Programming Restrictions + * + * - An enterprise bean must not use thread synchronization primitives to synchronize execution of + * multiple instances. + * + * This is for the same reason as above. Synchronization would not work if the EJB container distributed + * enterprise bean's instances across multiple JVMs. + */ from Callable origin, ForbiddenSynchronizationCallable target, Call call where ejbCalls(origin, target, call) -select origin, "EJB should not use synchronization by calling $@.", - call, target.getDeclaringType().getName() + "." + target.getName() +select origin, "EJB should not use synchronization by calling $@.", call, + target.getDeclaringType().getName() + "." + target.getName() diff --git a/java/ql/src/Frameworks/JavaEE/EJB/EjbThis.ql b/java/ql/src/Frameworks/JavaEE/EJB/EjbThis.ql index 1a5f73ea4df..0230cdf4dd2 100644 --- a/java/ql/src/Frameworks/JavaEE/EJB/EjbThis.ql +++ b/java/ql/src/Frameworks/JavaEE/EJB/EjbThis.ql @@ -11,24 +11,24 @@ * @tags portability * external/cwe/cwe-573 */ + import java import semmle.code.java.frameworks.javaee.ejb.EJB import semmle.code.java.frameworks.javaee.ejb.EJBRestrictions /* -JSR 220: Enterprise JavaBeansTM,Version 3.0 -EJB Core Contracts and Requirements -Section 21.1.2 Programming Restrictions - -- The enterprise bean must not attempt to pass this as an argument or method result. The -enterprise bean must pass the result of SessionContext.getBusinessObject, -SessionContext.getEJBObject, SessionContext.getEJBLocalObject, -EntityContext.getEJBObject, or EntityContext.getEJBLocalObject instead. -*/ + * JSR 220: Enterprise JavaBeansTM,Version 3.0 + * EJB Core Contracts and Requirements + * Section 21.1.2 Programming Restrictions + * + * - The enterprise bean must not attempt to pass this as an argument or method result. The + * enterprise bean must pass the result of SessionContext.getBusinessObject, + * SessionContext.getEJBObject, SessionContext.getEJBLocalObject, + * EntityContext.getEJBObject, or EntityContext.getEJBLocalObject instead. + */ from Callable origin, ForbiddenThisCallable target, Call call, ThisAccess ta where ejbCalls(origin, target, call) and ta = forbiddenThisUse(target) -select origin, "EJB should not use 'this' as a method argument or result $@.", - ta, "here" +select origin, "EJB should not use 'this' as a method argument or result $@.", ta, "here" diff --git a/java/ql/src/Frameworks/JavaEE/EJB/EjbThreads.ql b/java/ql/src/Frameworks/JavaEE/EJB/EjbThreads.ql index 0462c6210f4..fce68310e40 100644 --- a/java/ql/src/Frameworks/JavaEE/EJB/EjbThreads.ql +++ b/java/ql/src/Frameworks/JavaEE/EJB/EjbThreads.ql @@ -10,24 +10,25 @@ * external/cwe/cwe-383 * external/cwe/cwe-573 */ + import java import semmle.code.java.frameworks.javaee.ejb.EJB import semmle.code.java.frameworks.javaee.ejb.EJBRestrictions /* -JSR 220: Enterprise JavaBeansTM,Version 3.0 -EJB Core Contracts and Requirements -Section 21.1.2 Programming Restrictions - -- The enterprise bean must not attempt to manage threads. The enterprise bean must not attempt -to start, stop, suspend, or resume a thread, or to change a thread's priority or name. The enter- -prise bean must not attempt to manage thread groups. - -These functions are reserved for the EJB container. Allowing the enterprise bean to manage threads -would decrease the container's ability to properly manage the runtime environment. -*/ + * JSR 220: Enterprise JavaBeansTM,Version 3.0 + * EJB Core Contracts and Requirements + * Section 21.1.2 Programming Restrictions + * + * - The enterprise bean must not attempt to manage threads. The enterprise bean must not attempt + * to start, stop, suspend, or resume a thread, or to change a thread's priority or name. The enter- + * prise bean must not attempt to manage thread groups. + * + * These functions are reserved for the EJB container. Allowing the enterprise bean to manage threads + * would decrease the container's ability to properly manage the runtime environment. + */ from Callable origin, ForbiddenThreadingCallable target, Call call where ejbCalls(origin, target, call) -select origin, "EJB should not attempt to manage threads by calling $@.", - call, target.getDeclaringType().getName() + "." + target.getName() +select origin, "EJB should not attempt to manage threads by calling $@.", call, + target.getDeclaringType().getName() + "." + target.getName() diff --git a/java/ql/src/Frameworks/Spring/Architecture/Refactoring Opportunities/MissingParentBean.ql b/java/ql/src/Frameworks/Spring/Architecture/Refactoring Opportunities/MissingParentBean.ql index 2cbd7644488..dee5f78b675 100644 --- a/java/ql/src/Frameworks/Spring/Architecture/Refactoring Opportunities/MissingParentBean.ql +++ b/java/ql/src/Frameworks/Spring/Architecture/Refactoring Opportunities/MissingParentBean.ql @@ -9,6 +9,7 @@ * @tags maintainability * frameworks/spring */ + import java import semmle.code.java.frameworks.spring.Spring @@ -35,5 +36,4 @@ where select bean1, "Bean $@ has " + similarProps.toString() + " properties similar to $@. Consider introducing a common parent bean for these two beans.", - bean1, bean1.getBeanIdentifier(), - bean2, bean2.getBeanIdentifier() + bean1, bean1.getBeanIdentifier(), bean2, bean2.getBeanIdentifier() diff --git a/java/ql/src/Frameworks/Spring/Architecture/Refactoring Opportunities/TooManyBeans.ql b/java/ql/src/Frameworks/Spring/Architecture/Refactoring Opportunities/TooManyBeans.ql index f22f6634963..ce2fdf80c4b 100644 --- a/java/ql/src/Frameworks/Spring/Architecture/Refactoring Opportunities/TooManyBeans.ql +++ b/java/ql/src/Frameworks/Spring/Architecture/Refactoring Opportunities/TooManyBeans.ql @@ -8,6 +8,7 @@ * @tags maintainability * frameworks/spring */ + import java import semmle.code.java.frameworks.spring.Spring diff --git a/java/ql/src/Frameworks/Spring/Architecture/Refactoring Opportunities/UnusedBean.ql b/java/ql/src/Frameworks/Spring/Architecture/Refactoring Opportunities/UnusedBean.ql index e66de0097db..072db3e222d 100644 --- a/java/ql/src/Frameworks/Spring/Architecture/Refactoring Opportunities/UnusedBean.ql +++ b/java/ql/src/Frameworks/Spring/Architecture/Refactoring Opportunities/UnusedBean.ql @@ -37,12 +37,8 @@ class InstanceFieldWrite extends FieldWrite { */ class ImpureStmt extends Stmt { ImpureStmt() { - exists(Expr e | - e.getEnclosingStmt() = this - | - /* - * Only permit calls to set of whitelisted targets. - */ + exists(Expr e | e.getEnclosingStmt() = this | + // Only permit calls to set of whitelisted targets. ( e instanceof Call and not e.(Call).getCallee().getDeclaringType().hasQualifiedName("java.util", "Collections") @@ -59,12 +55,12 @@ class ImpureStmt extends Stmt { */ private Stmt getANestedStmt(Block block) { // Any non-block statement - not result instanceof Block and result = block.getAStmt() or + not result instanceof Block and result = block.getAStmt() + or // Or any statement nested in a block result = getANestedStmt(block.getAStmt()) } - /** * A class whose loading and construction by Spring does not have any side-effects outside the class. * @@ -73,16 +69,10 @@ private Stmt getANestedStmt(Block block) { class SpringPureClass extends Class { SpringPureClass() { ( - /* - * The only permitted statement in static initializers is the initialization of a static - * final or effectively final logger fields, or effectively immutable types. - */ - forall(Stmt s | - s = getANestedStmt(getAMember().(StaticInitializer).getBody()) - | - exists(Field f | - f = s.(ExprStmt).getExpr().(AssignExpr).getDest().(FieldWrite).getField() - | + // The only permitted statement in static initializers is the initialization of a static + // final or effectively final logger fields, or effectively immutable types. + forall(Stmt s | s = getANestedStmt(getAMember().(StaticInitializer).getBody()) | + exists(Field f | f = s.(ExprStmt).getExpr().(AssignExpr).getDest().(FieldWrite).getField() | ( // A logger field f.getName().toLowerCase() = "logger" or @@ -92,11 +82,7 @@ class SpringPureClass extends Class { ) and f.isStatic() and // Only written to in this statement e.g. final or effectively final - forall(FieldWrite fw | - fw = f.getAnAccess() - | - fw.getEnclosingStmt() = s - ) + forall(FieldWrite fw | fw = f.getAnAccess() | fw.getEnclosingStmt() = s) ) ) ) and @@ -107,20 +93,23 @@ class SpringPureClass extends Class { c = getAMember() ) and impureStmt.getEnclosingCallable() = c - | - c instanceof InstanceInitializer or - c instanceof Constructor or + | + c instanceof InstanceInitializer + or + c instanceof Constructor + or // afterPropertiesSet() method called after bean initialization - c = this.(InitializingBeanClass).getAfterPropertiesSet() or + c = this.(InitializingBeanClass).getAfterPropertiesSet() + or // Init and setter methods must be pure, because they are called when the bean is initialized - exists(SpringBean bean | - this = bean.getClass() - | + exists(SpringBean bean | this = bean.getClass() | c = bean.getInitMethod() or c = bean.getAProperty().getSetterMethod() - ) or + ) + or // Setter method by autowiring, either in the XML or by annotation - c = this.getAMethod().(SpringBeanAutowiredCallable) or + c = this.getAMethod().(SpringBeanAutowiredCallable) + or c = this.getAMethod().(SpringBeanXMLAutowiredSetterMethod) ) } @@ -134,7 +123,6 @@ class SpringBeanFactory extends ClassOrInterface { getAnAncestor().hasQualifiedName("org.springframework.beans.factory", "BeanFactory") } - /** * Get a bean constructed by a call to this bean factory. */ @@ -143,7 +131,7 @@ class SpringBeanFactory extends ClassOrInterface { getBean.hasName("getBean") and call.getMethod() = getBean and getBean.getDeclaringType() = this - | + | result.getBeanIdentifier() = call.getArgument(0).(CompileTimeConstantExpr).getStringValue() ) } @@ -162,13 +150,12 @@ class LiveSpringBean extends SpringBean { not isLazyInit() and // or has no side-effects when constructed not getClass() instanceof SpringPureClass - ) or + ) + or ( - /* - * If the class does not exist for this bean, or the class is not a source bean, then this is - * likely to be a definition using a library class, in which case we should consider it to be - * live. - */ + // If the class does not exist for this bean, or the class is not a source bean, then this is + // likely to be a definition using a library class, in which case we should consider it to be + // live. not exists(getClass()) or not getClass().fromSource() or // In alfresco, "webscript" beans should be considered live @@ -176,43 +163,45 @@ class LiveSpringBean extends SpringBean { // A live child bean implies this bean is live exists(LiveSpringBean child | this = child.getBeanParent()) or // Beans constructed by a bean factory are considered live - exists(SpringBeanFactory beanFactory | - this = beanFactory.getAConstructedBean() - ) - ) or + exists(SpringBeanFactory beanFactory | this = beanFactory.getAConstructedBean()) + ) + or ( // Referenced by a live bean, either as a property or argument in the XML exists(LiveSpringBean other | this = other.getAConstructorArg().getArgRefBean() or this = other.getAProperty().getPropertyRefBean() - ) or + ) + or // Referenced as a factory bean - exists(LiveSpringBean springBean | - this = springBean.getFactoryBean() - ) or + exists(LiveSpringBean springBean | this = springBean.getFactoryBean()) + or // Injected by @Autowired annotation exists(SpringBeanAutowiredCallable autowiredCallable | // The callable must be in a live class autowiredCallable.getEnclosingSpringBean() instanceof LiveSpringBean or autowiredCallable.getEnclosingSpringComponent().isLive() - | + | // This bean is injected into it this = autowiredCallable.getAnInjectedBean() - ) or + ) + or // Injected by @Autowired annotation on field exists(SpringBeanAutowiredField autowiredField | // The field must be in a live class autowiredField.getEnclosingSpringBean() instanceof LiveSpringBean or autowiredField.getEnclosingSpringComponent().isLive() - | + | // This bean is injected into it this = autowiredField.getInjectedBean() - ) or + ) + or // Injected by autowired specified in XML exists(SpringBeanXMLAutowiredSetterMethod setterMethod | // The config method must be on a live bean - setterMethod.getDeclaringType().(SpringBeanRefType).getSpringBean() instanceof LiveSpringBean - | + setterMethod.getDeclaringType().(SpringBeanRefType).getSpringBean() instanceof + LiveSpringBean + | // This bean is injected into it this = setterMethod.getInjectedBean() ) @@ -224,9 +213,7 @@ class LiveSpringBean extends SpringBean { * A `SpringBean` that can be safely removed from the program without changing overall behavior. */ class UnusedSpringBean extends SpringBean { - UnusedSpringBean() { - not this instanceof LiveSpringBean - } + UnusedSpringBean() { not this instanceof LiveSpringBean } } from UnusedSpringBean unused diff --git a/java/ql/src/Frameworks/Spring/Architecture/Refactoring Opportunities/UselessPropertyOverride.ql b/java/ql/src/Frameworks/Spring/Architecture/Refactoring Opportunities/UselessPropertyOverride.ql index 26d0aebd110..dda050506bb 100644 --- a/java/ql/src/Frameworks/Spring/Architecture/Refactoring Opportunities/UselessPropertyOverride.ql +++ b/java/ql/src/Frameworks/Spring/Architecture/Refactoring Opportunities/UselessPropertyOverride.ql @@ -9,19 +9,16 @@ * @tags maintainability * frameworks/spring */ + import java import semmle.code.java.frameworks.spring.Spring -from - SpringBean bean, - SpringProperty prop, - SpringProperty overriddenProp, - SpringBean ancestorBean +from SpringBean bean, SpringProperty prop, SpringProperty overriddenProp, SpringBean ancestorBean where prop = bean.getADeclaredProperty() and ancestorBean = bean.getBeanParent+() and ancestorBean.getADeclaredProperty() = overriddenProp and overriddenProp.getPropertyName() = prop.getPropertyName() and prop.isSimilar(overriddenProp) -select prop, "Property overrides $@ in parent, but has the same contents.", - overriddenProp, overriddenProp.toString() +select prop, "Property overrides $@ in parent, but has the same contents.", overriddenProp, + overriddenProp.toString() diff --git a/java/ql/src/Frameworks/Spring/Violations of Best Practice/AvoidAutowiring.ql b/java/ql/src/Frameworks/Spring/Violations of Best Practice/AvoidAutowiring.ql index a9f6431fc42..d8bab5ec324 100644 --- a/java/ql/src/Frameworks/Spring/Violations of Best Practice/AvoidAutowiring.ql +++ b/java/ql/src/Frameworks/Spring/Violations of Best Practice/AvoidAutowiring.ql @@ -8,6 +8,7 @@ * @tags maintainability * frameworks/spring */ + import java import semmle.code.java.frameworks.spring.Spring diff --git a/java/ql/src/Frameworks/Spring/Violations of Best Practice/DontUseConstructorArgIndex.ql b/java/ql/src/Frameworks/Spring/Violations of Best Practice/DontUseConstructorArgIndex.ql index 7aca9644a9e..e6496fa58a7 100644 --- a/java/ql/src/Frameworks/Spring/Violations of Best Practice/DontUseConstructorArgIndex.ql +++ b/java/ql/src/Frameworks/Spring/Violations of Best Practice/DontUseConstructorArgIndex.ql @@ -9,6 +9,7 @@ * @tags maintainability * frameworks/spring */ + import java import semmle.code.java.frameworks.spring.Spring diff --git a/java/ql/src/Frameworks/Spring/Violations of Best Practice/ImportsFirst.ql b/java/ql/src/Frameworks/Spring/Violations of Best Practice/ImportsFirst.ql index 14b0c6ce189..896e44d200b 100644 --- a/java/ql/src/Frameworks/Spring/Violations of Best Practice/ImportsFirst.ql +++ b/java/ql/src/Frameworks/Spring/Violations of Best Practice/ImportsFirst.ql @@ -9,8 +9,8 @@ * @tags maintainability * frameworks/spring */ -import java +import java import semmle.code.java.frameworks.spring.Spring from SpringImport i diff --git a/java/ql/src/Frameworks/Spring/Violations of Best Practice/NoBeanDescription.ql b/java/ql/src/Frameworks/Spring/Violations of Best Practice/NoBeanDescription.ql index 6b2517997d6..49c9d0243b1 100644 --- a/java/ql/src/Frameworks/Spring/Violations of Best Practice/NoBeanDescription.ql +++ b/java/ql/src/Frameworks/Spring/Violations of Best Practice/NoBeanDescription.ql @@ -7,9 +7,13 @@ * @id java/spring/missing-bean-description * @tags maintainability */ + import java import semmle.code.java.frameworks.spring.Spring from SpringBean b -where not exists(SpringDescription d | d = b.getASpringChild() or d = b.getSpringBeanFile().getBeansElement().getAChild()) +where + not exists(SpringDescription d | + d = b.getASpringChild() or d = b.getSpringBeanFile().getBeansElement().getAChild() + ) select b, "This bean does not have a description." diff --git a/java/ql/src/Frameworks/Spring/Violations of Best Practice/ParentShouldNotUseAbstractClass.ql b/java/ql/src/Frameworks/Spring/Violations of Best Practice/ParentShouldNotUseAbstractClass.ql index c40ee2aabd2..cc7807a048c 100644 --- a/java/ql/src/Frameworks/Spring/Violations of Best Practice/ParentShouldNotUseAbstractClass.ql +++ b/java/ql/src/Frameworks/Spring/Violations of Best Practice/ParentShouldNotUseAbstractClass.ql @@ -10,14 +10,12 @@ * maintainability * frameworks/spring */ -import java +import java import semmle.code.java.frameworks.spring.Spring class ParentBean extends SpringBean { - ParentBean() { - exists(SpringBean b | b.getBeanParent() = this) - } + ParentBean() { exists(SpringBean b | b.getBeanParent() = this) } RefType getDeclaredClass() { result = this.getClass() and @@ -28,5 +26,5 @@ class ParentBean extends SpringBean { from ParentBean parent where parent.getDeclaredClass().isAbstract() -select parent, "Parent bean $@ should not have an abstract class.", - parent, parent.getBeanIdentifier() +select parent, "Parent bean $@ should not have an abstract class.", parent, + parent.getBeanIdentifier() diff --git a/java/ql/src/Frameworks/Spring/Violations of Best Practice/UseIdInsteadOfName.ql b/java/ql/src/Frameworks/Spring/Violations of Best Practice/UseIdInsteadOfName.ql index fb5ffbdc90e..2be322583d9 100644 --- a/java/ql/src/Frameworks/Spring/Violations of Best Practice/UseIdInsteadOfName.ql +++ b/java/ql/src/Frameworks/Spring/Violations of Best Practice/UseIdInsteadOfName.ql @@ -10,6 +10,7 @@ * maintainability * frameworks/spring */ + import java import semmle.code.java.frameworks.spring.Spring @@ -17,4 +18,5 @@ from SpringBean b where not b.hasBeanId() and b.hasBeanName() -select b, "Use \"id\" instead of \"name\" to take advantage of the IDREF constraint in the XML parser." +select b, + "Use \"id\" instead of \"name\" to take advantage of the IDREF constraint in the XML parser." diff --git a/java/ql/src/Frameworks/Spring/Violations of Best Practice/UseLocalRef.ql b/java/ql/src/Frameworks/Spring/Violations of Best Practice/UseLocalRef.ql index 5dd56b9429a..cb9a2a7407d 100644 --- a/java/ql/src/Frameworks/Spring/Violations of Best Practice/UseLocalRef.ql +++ b/java/ql/src/Frameworks/Spring/Violations of Best Practice/UseLocalRef.ql @@ -10,6 +10,7 @@ * maintainability * frameworks/spring */ + import java import semmle.code.java.frameworks.spring.Spring diff --git a/java/ql/src/Frameworks/Spring/Violations of Best Practice/UseSetterInjection.ql b/java/ql/src/Frameworks/Spring/Violations of Best Practice/UseSetterInjection.ql index 2b1edc22351..397a1c349d3 100644 --- a/java/ql/src/Frameworks/Spring/Violations of Best Practice/UseSetterInjection.ql +++ b/java/ql/src/Frameworks/Spring/Violations of Best Practice/UseSetterInjection.ql @@ -9,6 +9,7 @@ * @tags maintainability * frameworks/spring */ + import java import semmle.code.java.frameworks.spring.Spring diff --git a/java/ql/src/Frameworks/Spring/Violations of Best Practice/UseShortcutForms.ql b/java/ql/src/Frameworks/Spring/Violations of Best Practice/UseShortcutForms.ql index 97dab395426..cc05679a15b 100644 --- a/java/ql/src/Frameworks/Spring/Violations of Best Practice/UseShortcutForms.ql +++ b/java/ql/src/Frameworks/Spring/Violations of Best Practice/UseShortcutForms.ql @@ -8,6 +8,7 @@ * @tags maintainability * frameworks/spring */ + import java import semmle.code.java.frameworks.spring.Spring @@ -52,7 +53,9 @@ class SpringPropertyUseShortcut extends SpringProperty { from SpringXMLElement springElement, string msg where - exists(SpringConstructorArgUseShortcut cons | cons = springElement and msg = cons.getMessage()) or - exists(SpringEntryUseShortcut entry | entry = springElement and msg = entry.getMessage()) or + exists(SpringConstructorArgUseShortcut cons | cons = springElement and msg = cons.getMessage()) + or + exists(SpringEntryUseShortcut entry | entry = springElement and msg = entry.getMessage()) + or exists(SpringPropertyUseShortcut prop | prop = springElement and msg = prop.getMessage()) select springElement, msg diff --git a/java/ql/src/Frameworks/Spring/XML Configuration Errors/MissingSetters.ql b/java/ql/src/Frameworks/Spring/XML Configuration Errors/MissingSetters.ql index f357997ab3a..3fd4138d993 100644 --- a/java/ql/src/Frameworks/Spring/XML Configuration Errors/MissingSetters.ql +++ b/java/ql/src/Frameworks/Spring/XML Configuration Errors/MissingSetters.ql @@ -10,6 +10,7 @@ * maintainability * frameworks/spring */ + import java import semmle.code.java.frameworks.spring.Spring @@ -17,5 +18,5 @@ from SpringProperty p where not p.getEnclosingBean().isAbstract() and not exists(p.getSetterMethod()) -select p, "This property is missing a setter method on $@.", - p.getEnclosingBean().getClass() as c, c.getName() +select p, "This property is missing a setter method on $@.", p.getEnclosingBean().getClass() as c, + c.getName() diff --git a/java/ql/src/Language Abuse/CastThisToTypeParameter.ql b/java/ql/src/Language Abuse/CastThisToTypeParameter.ql index 11a813bc449..bbdaf82cd07 100644 --- a/java/ql/src/Language Abuse/CastThisToTypeParameter.ql +++ b/java/ql/src/Language Abuse/CastThisToTypeParameter.ql @@ -22,6 +22,6 @@ where dest = cse.getType() ) and dest.getGenericType() = src -select e, "Casting 'this' to $@, a type parameter of $@, masks an implicit type constraint that should be explicitly stated.", - dest, dest.getName(), - src, src.getName() +select e, + "Casting 'this' to $@, a type parameter of $@, masks an implicit type constraint that should be explicitly stated.", + dest, dest.getName(), src, src.getName() diff --git a/java/ql/src/Language Abuse/ChainedInstanceof.ql b/java/ql/src/Language Abuse/ChainedInstanceof.ql index c53660df26d..bb646eeee78 100644 --- a/java/ql/src/Language Abuse/ChainedInstanceof.ql +++ b/java/ql/src/Language Abuse/ChainedInstanceof.ql @@ -14,18 +14,11 @@ import java int instanceofCountForIfChain(IfStmt is) { exists(int rest | ( - if is.getElse() instanceof IfStmt then - rest = instanceofCountForIfChain(is.getElse()) - else - rest = 0 - ) - and - ( - if is.getCondition() instanceof InstanceOfExpr then - result = 1 + rest - else - result = rest - ) + if is.getElse() instanceof IfStmt + then rest = instanceofCountForIfChain(is.getElse()) + else rest = 0 + ) and + (if is.getCondition() instanceof InstanceOfExpr then result = 1 + rest else result = rest) ) } @@ -36,4 +29,4 @@ where not exists(IfStmt other | is = other.getElse()) select is, "This if block performs a chain of " + n + - " type tests - consider alternatives, e.g. polymorphism or the visitor pattern." + " type tests - consider alternatives, e.g. polymorphism or the visitor pattern." diff --git a/java/ql/src/Language Abuse/DubiousDowncastOfThis.ql b/java/ql/src/Language Abuse/DubiousDowncastOfThis.ql index 87e19749f2e..3dc2d44ba5b 100644 --- a/java/ql/src/Language Abuse/DubiousDowncastOfThis.ql +++ b/java/ql/src/Language Abuse/DubiousDowncastOfThis.ql @@ -25,5 +25,4 @@ where src != dest and not dest instanceof TypeVariable select e, "Downcasting 'this' from $@ to $@ introduces a dependency cycle between the two types.", - src, src.getName(), - dest, dest.getName() + src, src.getName(), dest, dest.getName() diff --git a/java/ql/src/Language Abuse/DubiousTypeTestOfThis.ql b/java/ql/src/Language Abuse/DubiousTypeTestOfThis.ql index a26e77355e2..2b627149130 100644 --- a/java/ql/src/Language Abuse/DubiousTypeTestOfThis.ql +++ b/java/ql/src/Language Abuse/DubiousTypeTestOfThis.ql @@ -19,6 +19,6 @@ where t = ioe.getExpr().getType() and ct = ioe.getTypeName().getType() and ct.getASupertype*() = t -select ioe, "Testing whether 'this' is an instance of $@ in $@ introduces a dependency cycle between the two types.", - ct, ct.getName(), - t, t.getName() +select ioe, + "Testing whether 'this' is an instance of $@ in $@ introduces a dependency cycle between the two types.", + ct, ct.getName(), t, t.getName() diff --git a/java/ql/src/Language Abuse/EmptyStatement.ql b/java/ql/src/Language Abuse/EmptyStatement.ql index 0fcc7e7cadd..96ebcdd8c0d 100644 --- a/java/ql/src/Language Abuse/EmptyStatement.ql +++ b/java/ql/src/Language Abuse/EmptyStatement.ql @@ -13,7 +13,8 @@ import java from EmptyStmt empty, string action where - if exists(LoopStmt l | l.getBody() = empty) then ( + if exists(LoopStmt l | l.getBody() = empty) + then ( action = "turned into '{}'" ) else ( action = "deleted" diff --git a/java/ql/src/Language Abuse/EnumIdentifier.ql b/java/ql/src/Language Abuse/EnumIdentifier.ql index 9dfc7b8a563..9c7ac766747 100644 --- a/java/ql/src/Language Abuse/EnumIdentifier.ql +++ b/java/ql/src/Language Abuse/EnumIdentifier.ql @@ -13,9 +13,9 @@ import java Element elementNamedEnum() { - result.(CompilationUnit).getPackage().getName().regexpMatch("(.*\\.|)enum(\\..*|)") - or + result.(CompilationUnit).getPackage().getName().regexpMatch("(.*\\.|)enum(\\..*|)") or result.getName() = "enum" } -select elementNamedEnum(), "Code using 'enum' as an identifier will not compile with a recent version of Java." +select elementNamedEnum(), + "Code using 'enum' as an identifier will not compile with a recent version of Java." diff --git a/java/ql/src/Language Abuse/ImplementsAnnotation.ql b/java/ql/src/Language Abuse/ImplementsAnnotation.ql index 5732729bc6e..93647024347 100644 --- a/java/ql/src/Language Abuse/ImplementsAnnotation.ql +++ b/java/ql/src/Language Abuse/ImplementsAnnotation.ql @@ -14,4 +14,5 @@ import java from RefType type, AnnotationType annotation where type.getASupertype() = annotation -select type, "Should this class be annotated by '" + annotation.getName() + "', not have it as a super-type?" +select type, + "Should this class be annotated by '" + annotation.getName() + "', not have it as a super-type?" diff --git a/java/ql/src/Language Abuse/IterableIterator.ql b/java/ql/src/Language Abuse/IterableIterator.ql index 32e81193c83..c752607df09 100644 --- a/java/ql/src/Language Abuse/IterableIterator.ql +++ b/java/ql/src/Language Abuse/IterableIterator.ql @@ -10,14 +10,13 @@ * @tags correctness * reliability */ + import java import IterableClass /** An `Iterable` that is also its own `Iterator`. */ class IterableIterator extends Iterable { - IterableIterator() { - simpleIterator() instanceof ThisAccess - } + IterableIterator() { simpleIterator() instanceof ThisAccess } } /** An `IterableIterator` that never returns any elements. */ @@ -26,7 +25,14 @@ class EmptyIterableIterator extends IterableIterator { exists(Method m | m.getDeclaringType().getSourceDeclaration() = this and m.getName() = "hasNext" and - m.getBody().(SingletonBlock).getStmt().(ReturnStmt).getResult().(BooleanLiteral).getBooleanValue() = false + m + .getBody() + .(SingletonBlock) + .getStmt() + .(ReturnStmt) + .getResult() + .(BooleanLiteral) + .getBooleanValue() = false ) } } diff --git a/java/ql/src/Language Abuse/MissedTernaryOpportunity.ql b/java/ql/src/Language Abuse/MissedTernaryOpportunity.ql index 4a41fdff917..17485f02248 100644 --- a/java/ql/src/Language Abuse/MissedTernaryOpportunity.ql +++ b/java/ql/src/Language Abuse/MissedTernaryOpportunity.ql @@ -14,9 +14,7 @@ import java predicate complicatedBranch(Stmt branch) { - exists(ConditionalExpr ce | - ce.getParent*() = branch - ) or + exists(ConditionalExpr ce | ce.getParent*() = branch) or count(MethodAccess a | a.getParent*() = branch) > 1 } @@ -31,9 +29,11 @@ predicate toCompare(Expr left, Expr right) { exists(IfStmt is, AssignExpr at, AssignExpr ae | at.getParent() = is.getThen() and ae.getParent() = is.getElse() - | - left = at.getDest() and right = ae.getDest() or - left = at.getDest().(VarAccess).getQualifier() and right = ae.getDest().(VarAccess).getQualifier() + | + left = at.getDest() and right = ae.getDest() + or + left = at.getDest().(VarAccess).getQualifier() and + right = ae.getDest().(VarAccess).getQualifier() ) } @@ -45,7 +45,8 @@ predicate sameVariable(VarAccess left, VarAccess right) { left.getQualifier() = q1 and sameVariable(q1, q2) and right.getQualifier() = q2 - ) or + ) + or left.isLocal() and right.isLocal() ) } @@ -71,4 +72,5 @@ where complicatedBranch(is.getThen()) or complicatedBranch(is.getElse()) ) -select is, "Both branches of this 'if' statement " + what + " - consider using '?' to express intent better." +select is, + "Both branches of this 'if' statement " + what + " - consider using '?' to express intent better." diff --git a/java/ql/src/Language Abuse/OverridePackagePrivate.ql b/java/ql/src/Language Abuse/OverridePackagePrivate.ql index 8b6ec0e805a..d2866c76abc 100644 --- a/java/ql/src/Language Abuse/OverridePackagePrivate.ql +++ b/java/ql/src/Language Abuse/OverridePackagePrivate.ql @@ -20,5 +20,4 @@ where not superMethod.isProtected() and not superMethod.isPrivate() select method, "This method does not override $@ because it is private to another package.", - superMethod, - superMethod.getDeclaringType().getName() + "." + superMethod.getName() + superMethod, superMethod.getDeclaringType().getName() + "." + superMethod.getName() diff --git a/java/ql/src/Language Abuse/TypeVarExtendsFinalType.ql b/java/ql/src/Language Abuse/TypeVarExtendsFinalType.ql index c9247096f1a..77c318bcb9e 100644 --- a/java/ql/src/Language Abuse/TypeVarExtendsFinalType.ql +++ b/java/ql/src/Language Abuse/TypeVarExtendsFinalType.ql @@ -18,4 +18,5 @@ from TypeVariable v, RefType bound where v.getATypeBound().getType() = bound and bound.isFinal() -select v, "Type '" + bound + "' is final, so <" + v.getName() + " extends " + bound + "> is confusing." +select v, + "Type '" + bound + "' is final, so <" + v.getName() + " extends " + bound + "> is confusing." diff --git a/java/ql/src/Language Abuse/TypeVariableHidesType.ql b/java/ql/src/Language Abuse/TypeVariableHidesType.ql index 0fd4dfaf045..fc0084f37d9 100644 --- a/java/ql/src/Language Abuse/TypeVariableHidesType.ql +++ b/java/ql/src/Language Abuse/TypeVariableHidesType.ql @@ -14,10 +14,8 @@ import java RefType anOuterType(TypeVariable var) { - var.getGenericCallable().getDeclaringType() = result - or - var.getGenericType() = result - or + var.getGenericCallable().getDeclaringType() = result or + var.getGenericType() = result or result = anOuterType(var).(NestedType).getEnclosingType() } diff --git a/java/ql/src/Language Abuse/UselessNullCheck.ql b/java/ql/src/Language Abuse/UselessNullCheck.ql index 16f024c9137..ec651428a20 100644 --- a/java/ql/src/Language Abuse/UselessNullCheck.ql +++ b/java/ql/src/Language Abuse/UselessNullCheck.ql @@ -19,10 +19,12 @@ from Expr guard, Expr e, Expr reason, string msg where guard = basicNullGuard(e, _, true) and e = clearlyNotNullExpr(reason) and - (if reason instanceof Guard then - msg = "This check is useless, $@ cannot be null here, since it is guarded by $@." - else if reason != e then - msg = "This check is useless, $@ cannot be null here, since $@ always is non-null." - else - msg = "This check is useless, since $@ always is non-null.") + ( + if reason instanceof Guard + then msg = "This check is useless, $@ cannot be null here, since it is guarded by $@." + else + if reason != e + then msg = "This check is useless, $@ cannot be null here, since $@ always is non-null." + else msg = "This check is useless, since $@ always is non-null." + ) select guard, msg, e, e.toString(), reason, reason.toString() diff --git a/java/ql/src/Language Abuse/UselessTypeTest.ql b/java/ql/src/Language Abuse/UselessTypeTest.ql index 25085212544..fac42d30596 100644 --- a/java/ql/src/Language Abuse/UselessTypeTest.ql +++ b/java/ql/src/Language Abuse/UselessTypeTest.ql @@ -17,6 +17,6 @@ where t = ioe.getExpr().getType() and ct = ioe.getTypeName().getType() and ct = t.getASupertype+() -select ioe, "There is no need to test whether an instance of $@ is also an instance of $@ - it always is.", - t, t.getName(), - ct, ct.getName() +select ioe, + "There is no need to test whether an instance of $@ is also an instance of $@ - it always is.", t, + t.getName(), ct, ct.getName() diff --git a/java/ql/src/Language Abuse/UselessUpcast.ql b/java/ql/src/Language Abuse/UselessUpcast.ql index fe8b6fe6a0c..5c34d4d4cff 100644 --- a/java/ql/src/Language Abuse/UselessUpcast.ql +++ b/java/ql/src/Language Abuse/UselessUpcast.ql @@ -19,13 +19,13 @@ predicate usefulUpcast(CastExpr e) { target = c.getCallee() and // An upcast to the type of the corresponding parameter. e.getType() = target.getParameterType(i) - | + | // There is an overloaded method/constructor in the class that we might be trying to avoid. exists(Callable other | other.getName() = target.getName() and other.getSourceDeclaration() != target.getSourceDeclaration() - | - c.(MethodAccess).getReceiverType().(RefType).inherits((Method)other) or + | + c.(MethodAccess).getReceiverType().(RefType).inherits(other.(Method)) or other = target.(Constructor).getDeclaringType().getAConstructor() ) ) @@ -36,7 +36,9 @@ predicate usefulUpcast(CastExpr e) { ) or // Upcasts that are performed on an operand of a ternary expression. - exists(ConditionalExpr ce | e = ce.getTrueExpr().getProperExpr() or e = ce.getFalseExpr().getProperExpr()) + exists(ConditionalExpr ce | + e = ce.getTrueExpr().getProperExpr() or e = ce.getFalseExpr().getProperExpr() + ) or // Upcasts to raw types. e.getType() instanceof RawType @@ -46,10 +48,13 @@ predicate usefulUpcast(CastExpr e) { // Upcasts that are performed to affect field, private method, or static method resolution. exists(FieldAccess fa | e = fa.getQualifier().getProperExpr() | not e.getExpr().getType().(RefType).inherits(fa.getField()) - ) or + ) + or exists(MethodAccess ma, Method m | - e = ma.getQualifier().getProperExpr() and m = ma.getMethod() and (m.isStatic() or m.isPrivate()) - | + e = ma.getQualifier().getProperExpr() and + m = ma.getMethod() and + (m.isStatic() or m.isPrivate()) + | not e.getExpr().getType().(RefType).inherits(m) ) } @@ -63,6 +68,5 @@ where ) and dest = src.getASupertype+() and not usefulUpcast(e) -select e, "There is no need to upcast from $@ to $@ - the conversion can be done implicitly.", - src, src.getName(), - dest, dest.getName() +select e, "There is no need to upcast from $@ to $@ - the conversion can be done implicitly.", src, + src.getName(), dest, dest.getName() diff --git a/java/ql/src/Language Abuse/WrappedIterator.ql b/java/ql/src/Language Abuse/WrappedIterator.ql index 2376d87c4e7..2fa31b88517 100644 --- a/java/ql/src/Language Abuse/WrappedIterator.ql +++ b/java/ql/src/Language Abuse/WrappedIterator.ql @@ -9,6 +9,7 @@ * @tags correctness * reliability */ + import java import IterableClass @@ -18,18 +19,25 @@ predicate iteratorWrapper(Iterable it, Field f, boolean wrap) { // declares a final or effectively final field ... f.getDeclaringType().getSourceDeclaration() = it and ( - f.isFinal() or + f.isFinal() + or ( strictcount(f.getAnAssignedValue()) = 1 and f.getAnAssignedValue().getEnclosingCallable() instanceof InitializerMethod ) ) and // ... whose type is a sub-type of `java.util.Iterator` and ... - f.getType().(RefType).getASupertype*().getSourceDeclaration().hasQualifiedName("java.util", "Iterator") and + f + .getType() + .(RefType) + .getASupertype*() + .getSourceDeclaration() + .hasQualifiedName("java.util", "Iterator") and // ... whose value is returned by the `iterator()` method of this class ... exists(Expr iterator | iterator = it.simpleIterator() | // ... either directly ... - iterator = f.getAnAccess() and wrap = false or + iterator = f.getAnAccess() and wrap = false + or // ... or wrapped in another Iterator. exists(ClassInstanceExpr cie | cie = iterator and wrap = true | cie.getAnArgument() = f.getAnAccess() or @@ -41,9 +49,11 @@ predicate iteratorWrapper(Iterable it, Field f, boolean wrap) { from Iterable i, Field f, boolean wrap, string appearto, string iteratorbasedon where iteratorWrapper(i, f, wrap) and - ( wrap = true and appearto = "appear to " and iteratorbasedon = "an iterator based on " or + ( + wrap = true and appearto = "appear to " and iteratorbasedon = "an iterator based on " + or wrap = false and appearto = "" and iteratorbasedon = "" ) -select i, "This class implements Iterable, but does not " + appearto + "support multiple iterations," + - " since its iterator method always returns " + iteratorbasedon + "the same $@.", - f, "iterator" +select i, + "This class implements Iterable, but does not " + appearto + "support multiple iterations," + + " since its iterator method always returns " + iteratorbasedon + "the same $@.", f, "iterator" diff --git a/java/ql/src/Likely Bugs/Arithmetic/BadAbsOfRandom.ql b/java/ql/src/Likely Bugs/Arithmetic/BadAbsOfRandom.ql index 27dc29d21d9..f8cad3dae37 100644 --- a/java/ql/src/Likely Bugs/Arithmetic/BadAbsOfRandom.ql +++ b/java/ql/src/Likely Bugs/Arithmetic/BadAbsOfRandom.ql @@ -9,16 +9,17 @@ * @tags reliability * maintainability */ + import java from MethodAccess ma, Method abs, Method nextIntOrLong, MethodAccess nma where ma.getMethod() = abs and abs.hasName("abs") and - abs.getDeclaringType().hasQualifiedName("java.lang","Math") and + abs.getDeclaringType().hasQualifiedName("java.lang", "Math") and ma.getAnArgument() = nma and nma.getMethod() = nextIntOrLong and (nextIntOrLong.hasName("nextInt") or nextIntOrLong.hasName("nextLong")) and - nextIntOrLong.getDeclaringType().hasQualifiedName("java.util","Random") and + nextIntOrLong.getDeclaringType().hasQualifiedName("java.util", "Random") and nextIntOrLong.hasNoParameters() select ma, "Incorrect computation of abs of signed integral random value." diff --git a/java/ql/src/Likely Bugs/Arithmetic/BadCheckOdd.ql b/java/ql/src/Likely Bugs/Arithmetic/BadCheckOdd.ql index cde280a2e87..ead6919f8be 100644 --- a/java/ql/src/Likely Bugs/Arithmetic/BadCheckOdd.ql +++ b/java/ql/src/Likely Bugs/Arithmetic/BadCheckOdd.ql @@ -10,6 +10,7 @@ * correctness * types */ + import java import semmle.code.java.Collections @@ -28,8 +29,10 @@ where not isDefinitelyPositive(lhs.getLeftOperand()) and lhs.getRightOperand().getProperExpr().(IntegerLiteral).getIntValue() = 2 and ( - t instanceof EQExpr and rhs.getIntValue() = 1 and parity = "oddness" or - t instanceof NEExpr and rhs.getIntValue() = 1 and parity = "evenness" or + t instanceof EQExpr and rhs.getIntValue() = 1 and parity = "oddness" + or + t instanceof NEExpr and rhs.getIntValue() = 1 and parity = "evenness" + or t instanceof GTExpr and rhs.getIntValue() = 0 and parity = "oddness" ) select t, "Possibly invalid test for " + parity + ". This will fail for negative numbers." diff --git a/java/ql/src/Likely Bugs/Arithmetic/CondExprTypes.ql b/java/ql/src/Likely Bugs/Arithmetic/CondExprTypes.ql index 78101eb303a..16e6ddc10d7 100644 --- a/java/ql/src/Likely Bugs/Arithmetic/CondExprTypes.ql +++ b/java/ql/src/Likely Bugs/Arithmetic/CondExprTypes.ql @@ -9,16 +9,12 @@ * @tags reliability * correctness */ + import java -class CharType extends PrimitiveType { - CharType() { - this.hasName("char") - } -} +class CharType extends PrimitiveType { CharType() { this.hasName("char") } } -private -Type getABranchType(ConditionalExpr ce) { +private Type getABranchType(ConditionalExpr ce) { result = ce.getTrueExpr().getType() or result = ce.getFalseExpr().getType() } @@ -30,6 +26,5 @@ where t instanceof PrimitiveType and not t instanceof CharType ) -select ce, "Mismatch between types of branches: $@ and $@.", - ce.getTrueExpr(), ce.getTrueExpr().getType().getName(), - ce.getFalseExpr(), ce.getFalseExpr().getType().getName() +select ce, "Mismatch between types of branches: $@ and $@.", ce.getTrueExpr(), + ce.getTrueExpr().getType().getName(), ce.getFalseExpr(), ce.getFalseExpr().getType().getName() diff --git a/java/ql/src/Likely Bugs/Arithmetic/ConstantExpAppearsNonConstant.ql b/java/ql/src/Likely Bugs/Arithmetic/ConstantExpAppearsNonConstant.ql index a5991c360ab..b155e93d6b8 100644 --- a/java/ql/src/Likely Bugs/Arithmetic/ConstantExpAppearsNonConstant.ql +++ b/java/ql/src/Likely Bugs/Arithmetic/ConstantExpAppearsNonConstant.ql @@ -8,19 +8,16 @@ * @tags maintainability * useless-code */ + import java -int integralTypeWidth (IntegralType t) { - if (t.hasName("long") or t.hasName("Long")) - then result = 64 - else result = 32 +int integralTypeWidth(IntegralType t) { + if (t.hasName("long") or t.hasName("Long")) then result = 64 else result = 32 } -int eval (Expr e) { - result = e.(CompileTimeConstantExpr).getIntValue() -} +int eval(Expr e) { result = e.(CompileTimeConstantExpr).getIntValue() } -predicate isConstantExp (Expr e) { +predicate isConstantExp(Expr e) { // A literal is constant. e instanceof Literal or @@ -58,9 +55,7 @@ predicate isConstantExp (Expr e) { ) ) or - exists(AndBitwiseExpr a | a = e | - eval(a.getAnOperand().getProperExpr()) = 0 - ) + exists(AndBitwiseExpr a | a = e | eval(a.getAnOperand().getProperExpr()) = 0) or exists(AndLogicalExpr a | a = e | a.getAnOperand().getProperExpr().(BooleanLiteral).getBooleanValue() = false diff --git a/java/ql/src/Likely Bugs/Arithmetic/InformationLoss.ql b/java/ql/src/Likely Bugs/Arithmetic/InformationLoss.ql index f5cd52bf35c..aec8e9bc94c 100644 --- a/java/ql/src/Likely Bugs/Arithmetic/InformationLoss.ql +++ b/java/ql/src/Likely Bugs/Arithmetic/InformationLoss.ql @@ -14,6 +14,7 @@ * external/cwe/cwe-197 * external/cwe/cwe-681 */ + import semmle.code.java.arithmetic.Overflow class DangerousAssignOpExpr extends AssignOp { @@ -23,14 +24,12 @@ class DangerousAssignOpExpr extends AssignOp { } } -predicate problematicCasting(Type t, Expr e) { - e.getType().(NumType).widerThan((NumType)t) -} +predicate problematicCasting(Type t, Expr e) { e.getType().(NumType).widerThan(t.(NumType)) } from DangerousAssignOpExpr a, Expr e where e = a.getSource() and problematicCasting(a.getDest().getType(), e) select a, - "Implicit cast of source type " + e.getType().getName() + - " to narrower destination type " + a.getDest().getType().getName() + "." + "Implicit cast of source type " + e.getType().getName() + " to narrower destination type " + + a.getDest().getType().getName() + "." diff --git a/java/ql/src/Likely Bugs/Arithmetic/MultiplyRemainder.ql b/java/ql/src/Likely Bugs/Arithmetic/MultiplyRemainder.ql index ada97743b0c..8653f9cc8d5 100644 --- a/java/ql/src/Likely Bugs/Arithmetic/MultiplyRemainder.ql +++ b/java/ql/src/Likely Bugs/Arithmetic/MultiplyRemainder.ql @@ -9,6 +9,7 @@ * @tags maintainability * correctness */ + import java from MulExpr e diff --git a/java/ql/src/Likely Bugs/Arithmetic/OctalLiteral.ql b/java/ql/src/Likely Bugs/Arithmetic/OctalLiteral.ql index 3e27b935ab6..1a8021253df 100644 --- a/java/ql/src/Likely Bugs/Arithmetic/OctalLiteral.ql +++ b/java/ql/src/Likely Bugs/Arithmetic/OctalLiteral.ql @@ -11,6 +11,7 @@ * @tags maintainability * correctness */ + import java from IntegerLiteral lit, string val diff --git a/java/ql/src/Likely Bugs/Arithmetic/RandomUsedOnce.ql b/java/ql/src/Likely Bugs/Arithmetic/RandomUsedOnce.ql index f54d1f60f8f..20cbeaa911d 100644 --- a/java/ql/src/Likely Bugs/Arithmetic/RandomUsedOnce.ql +++ b/java/ql/src/Likely Bugs/Arithmetic/RandomUsedOnce.ql @@ -10,11 +10,12 @@ * maintainability * external/cwe/cwe-335 */ + import java from MethodAccess ma, Method random where - random.getDeclaringType().hasQualifiedName("java.util","Random") and + random.getDeclaringType().hasQualifiedName("java.util", "Random") and ma.getMethod() = random and ma.getQualifier() instanceof ClassInstanceExpr select ma, "Random object created and used only once." diff --git a/java/ql/src/Likely Bugs/Arithmetic/WhitespaceContradictsPrecedence.ql b/java/ql/src/Likely Bugs/Arithmetic/WhitespaceContradictsPrecedence.ql index 6f47f6f4c06..73ce40d5f21 100644 --- a/java/ql/src/Likely Bugs/Arithmetic/WhitespaceContradictsPrecedence.ql +++ b/java/ql/src/Likely Bugs/Arithmetic/WhitespaceContradictsPrecedence.ql @@ -70,9 +70,15 @@ class AssocNestedExpr extends BinaryExpr { AssocNestedExpr() { exists(BinaryExpr parent, int idx | this.isNthChildOf(parent, idx) | // `+`, `*`, `&&`, `||` and the bitwise operations are associative. - ((this instanceof AddExpr or this instanceof MulExpr or - this instanceof BitwiseExpr or this instanceof LogicalExpr) and - parent.getKind() = this.getKind()) + ( + ( + this instanceof AddExpr or + this instanceof MulExpr or + this instanceof BitwiseExpr or + this instanceof LogicalExpr + ) and + parent.getKind() = this.getKind() + ) or // Equality tests are associate over each other. (this instanceof EqualityTest and parent instanceof EqualityTest) @@ -96,7 +102,10 @@ class AssocNestedExpr extends BinaryExpr { class HarmlessNestedExpr extends BinaryExpr { HarmlessNestedExpr() { exists(BinaryExpr parent | this = parent.getAChildExpr() | - (parent instanceof RelationExpr and (this instanceof ArithmeticExpr or this instanceof ShiftExpr)) + ( + parent instanceof RelationExpr and + (this instanceof ArithmeticExpr or this instanceof ShiftExpr) + ) or (parent instanceof LogicalExpr and this instanceof RelationExpr) ) @@ -134,7 +143,9 @@ predicate interestingNesting(BinaryExpr inner, BinaryExpr outer) { from BinaryExpr inner, BinaryExpr outer, int wsouter, int wsinner where interestingNesting(inner, outer) and - wsinner = operatorWS(inner) and wsouter = operatorWS(outer) and - wsinner % 2 = 0 and wsouter % 2 = 0 and + wsinner = operatorWS(inner) and + wsouter = operatorWS(outer) and + wsinner % 2 = 0 and + wsouter % 2 = 0 and wsinner > wsouter select outer, "Whitespace around nested operators contradicts precedence." diff --git a/java/ql/src/Likely Bugs/Cloning/MissingCallToSuperClone.ql b/java/ql/src/Likely Bugs/Cloning/MissingCallToSuperClone.ql index 9340798599e..8e107359dbb 100644 --- a/java/ql/src/Likely Bugs/Cloning/MissingCallToSuperClone.ql +++ b/java/ql/src/Likely Bugs/Cloning/MissingCallToSuperClone.ql @@ -11,6 +11,7 @@ * maintainability * external/cwe/cwe-580 */ + import java from CloneMethod c, CloneMethod sc @@ -19,5 +20,5 @@ where c.fromSource() and exists(sc.getBody()) and not exists(CloneMethod ssc | sc.callsSuper(ssc)) -select sc, "This clone method does not call super.clone(), but is " - + "overridden and called $@.", c, "in a subclass" +select sc, "This clone method does not call super.clone(), but is " + "overridden and called $@.", + c, "in a subclass" diff --git a/java/ql/src/Likely Bugs/Cloning/MissingMethodClone.ql b/java/ql/src/Likely Bugs/Cloning/MissingMethodClone.ql index 7376ba9785f..a23a8576f86 100644 --- a/java/ql/src/Likely Bugs/Cloning/MissingMethodClone.ql +++ b/java/ql/src/Likely Bugs/Cloning/MissingMethodClone.ql @@ -9,6 +9,7 @@ * @tags reliability * maintainability */ + import java from Class t, TypeCloneable cloneable diff --git a/java/ql/src/Likely Bugs/Collections/ArrayIndexOutOfBounds.ql b/java/ql/src/Likely Bugs/Collections/ArrayIndexOutOfBounds.ql index 36c416fd96d..51a137feb36 100644 --- a/java/ql/src/Likely Bugs/Collections/ArrayIndexOutOfBounds.ql +++ b/java/ql/src/Likely Bugs/Collections/ArrayIndexOutOfBounds.ql @@ -23,7 +23,7 @@ predicate boundedArrayAccess(ArrayAccess aa, int k) { aa.getIndexExpr() = index and aa.getArray() = arr.getAUse() and bounded(index, b, delta, true, _) - | + | exists(FieldAccess len | len.getField() instanceof ArrayLengthField and len.getQualifier() = arr.getAUse() and @@ -33,13 +33,14 @@ predicate boundedArrayAccess(ArrayAccess aa, int k) { or exists(ArrayCreationExpr arraycreation | arraycreation = arr.(SsaExplicitUpdate).getDefiningExpr().(VariableAssign).getSource() - | + | k = delta and arraycreation.getDimension(0) = b.getExpr() or exists(int arrlen | arraycreation.getFirstDimensionSize() = arrlen and - b instanceof ZeroBound and k = delta - arrlen + b instanceof ZeroBound and + k = delta - arrlen ) ) ) @@ -59,4 +60,5 @@ where k >= 0 and if k = 0 then kstr = "" else kstr = " + " + k select aa, - "This array access might be out of bounds, as the index might be equal to the array length" + kstr + "." + "This array access might be out of bounds, as the index might be equal to the array length" + kstr + + "." diff --git a/java/ql/src/Likely Bugs/Collections/ContainsTypeMismatch.ql b/java/ql/src/Likely Bugs/Collections/ContainsTypeMismatch.ql index 7c48b8a0ffc..356997e48e7 100644 --- a/java/ql/src/Likely Bugs/Collections/ContainsTypeMismatch.ql +++ b/java/ql/src/Likely Bugs/Collections/ContainsTypeMismatch.ql @@ -11,31 +11,100 @@ * correctness * logic */ + import java import semmle.code.java.Collections predicate containerAccess(string package, string type, int p, string signature, int i) { - package = "java.util" and type = "Collection" and p = 0 and signature = "contains(java.lang.Object)" and i = 0 or - package = "java.util" and type = "Dictionary" and p = 0 and signature = "get(java.lang.Object)" and i = 0 or - package = "java.util" and type = "Hashtable" and p = 1 and signature = "contains(java.lang.Object)" and i = 0 or - package = "java.util" and type = "List" and p = 0 and signature = "indexOf(java.lang.Object)" and i = 0 or - package = "java.util" and type = "List" and p = 0 and signature = "lastIndexOf(java.lang.Object)" and i = 0 or - package = "java.util" and type = "Map" and p = 0 and signature = "get(java.lang.Object)" and i = 0 or - package = "java.util" and type = "Map" and p = 0 and signature = "getOrDefault(java.lang.Object,java.lang.Object)" and i = 0 or - package = "java.util" and type = "Map" and p = 0 and signature = "containsKey(java.lang.Object)" and i = 0 or - package = "java.util" and type = "Map" and p = 1 and signature = "containsValue(java.lang.Object)" and i = 0 or - package = "java.util" and type = "Stack" and p = 0 and signature = "search(java.lang.Object)" and i = 0 or - package = "java.util" and type = "Vector" and p = 0 and signature = "indexOf(java.lang.Object,int)" and i = 0 or - package = "java.util" and type = "Vector" and p = 0 and signature = "lastIndexOf(java.lang.Object,int)" and i = 0 or - package = "java.util.concurrent" and type = "ConcurrentHashMap" and p = 1 and signature = "contains(java.lang.Object)" and i = 0 + package = "java.util" and + type = "Collection" and + p = 0 and + signature = "contains(java.lang.Object)" and + i = 0 + or + package = "java.util" and + type = "Dictionary" and + p = 0 and + signature = "get(java.lang.Object)" and + i = 0 + or + package = "java.util" and + type = "Hashtable" and + p = 1 and + signature = "contains(java.lang.Object)" and + i = 0 + or + package = "java.util" and + type = "List" and + p = 0 and + signature = "indexOf(java.lang.Object)" and + i = 0 + or + package = "java.util" and + type = "List" and + p = 0 and + signature = "lastIndexOf(java.lang.Object)" and + i = 0 + or + package = "java.util" and + type = "Map" and + p = 0 and + signature = "get(java.lang.Object)" and + i = 0 + or + package = "java.util" and + type = "Map" and + p = 0 and + signature = "getOrDefault(java.lang.Object,java.lang.Object)" and + i = 0 + or + package = "java.util" and + type = "Map" and + p = 0 and + signature = "containsKey(java.lang.Object)" and + i = 0 + or + package = "java.util" and + type = "Map" and + p = 1 and + signature = "containsValue(java.lang.Object)" and + i = 0 + or + package = "java.util" and + type = "Stack" and + p = 0 and + signature = "search(java.lang.Object)" and + i = 0 + or + package = "java.util" and + type = "Vector" and + p = 0 and + signature = "indexOf(java.lang.Object,int)" and + i = 0 + or + package = "java.util" and + type = "Vector" and + p = 0 and + signature = "lastIndexOf(java.lang.Object,int)" and + i = 0 + or + package = "java.util.concurrent" and + type = "ConcurrentHashMap" and + p = 1 and + signature = "contains(java.lang.Object)" and + i = 0 } class MismatchedContainerAccess extends MethodAccess { MismatchedContainerAccess() { exists(string package, string type, int i | containerAccess(package, type, _, getCallee().getSignature(), i) - | - getCallee().getDeclaringType().getASupertype*().getSourceDeclaration().hasQualifiedName(package, type) and + | + getCallee() + .getDeclaringType() + .getASupertype*() + .getSourceDeclaration() + .hasQualifiedName(package, type) and getCallee().getParameter(i).getType() instanceof TypeObject ) } @@ -47,7 +116,7 @@ class MismatchedContainerAccess extends MethodAccess { RefType getReceiverElementType(int i) { exists(RefType t, GenericType g, string package, string type, int p | containerAccess(package, type, p, getCallee().getSignature(), i) - | + | t = getCallee().getDeclaringType() and t.getASupertype*().getSourceDeclaration() = g and g.hasQualifiedName(package, type) and @@ -71,5 +140,6 @@ where typearg = ma.getReceiverElementType(idx).getSourceDeclaration() and argtype = ma.getArgumentType(idx) and not haveIntersection(typearg, argtype) -select ma.getArgument(idx), "Actual argument type '" + argtype.getName() + "'" - + " is incompatible with expected argument type '" + typearg.getName() + "'." +select ma.getArgument(idx), + "Actual argument type '" + argtype.getName() + "'" + + " is incompatible with expected argument type '" + typearg.getName() + "'." diff --git a/java/ql/src/Likely Bugs/Collections/IteratorRemoveMayFail.ql b/java/ql/src/Likely Bugs/Collections/IteratorRemoveMayFail.ql index eccb0aeebdc..9d3b74ce08e 100644 --- a/java/ql/src/Likely Bugs/Collections/IteratorRemoveMayFail.ql +++ b/java/ql/src/Likely Bugs/Collections/IteratorRemoveMayFail.ql @@ -15,23 +15,32 @@ import java class SpecialCollectionCreation extends MethodAccess { SpecialCollectionCreation() { - exists(Method m, RefType rt | m = this.(MethodAccess).getCallee() and rt = m.getDeclaringType() | - (rt.hasQualifiedName("java.util", "Arrays") and m.hasName("asList")) or - (rt.hasQualifiedName("java.util", "Collections") and m.getName().regexpMatch("singleton.*|unmodifiable.*")) + exists(Method m, RefType rt | + m = this.(MethodAccess).getCallee() and rt = m.getDeclaringType() + | + (rt.hasQualifiedName("java.util", "Arrays") and m.hasName("asList")) + or + ( + rt.hasQualifiedName("java.util", "Collections") and + m.getName().regexpMatch("singleton.*|unmodifiable.*") + ) ) } } predicate containsSpecialCollection(Expr e, SpecialCollectionCreation origin) { - e = origin or + e = origin + or exists(Variable v | containsSpecialCollection(v.getAnAssignedValue(), origin) and e = v.getAnAccess() - ) or + ) + or exists(Call c, int i | containsSpecialCollection(c.getArgument(i), origin) and e = c.getCallee().getParameter(i).getAnAccess() - ) or + ) + or exists(Call c, ReturnStmt r | e = c | r.getEnclosingCallable() = c.getCallee() and containsSpecialCollection(r.getResult(), origin) @@ -42,15 +51,18 @@ predicate iterOfSpecialCollection(Expr e, SpecialCollectionCreation origin) { exists(MethodAccess ma | ma = e | containsSpecialCollection(ma.getQualifier(), origin) and ma.getCallee().hasName("iterator") - ) or + ) + or exists(Variable v | iterOfSpecialCollection(v.getAnAssignedValue(), origin) and e = v.getAnAccess() - ) or + ) + or exists(Call c, int i | iterOfSpecialCollection(c.getArgument(i), origin) and e = c.getCallee().getParameter(i).getAnAccess() - ) or + ) + or exists(Call c, ReturnStmt r | e = c | r.getEnclosingCallable() = c.getCallee() and iterOfSpecialCollection(r.getResult(), origin) diff --git a/java/ql/src/Likely Bugs/Collections/ReadOnlyContainer.ql b/java/ql/src/Likely Bugs/Collections/ReadOnlyContainer.ql index 0d0dc5da229..aa961a3a4a9 100644 --- a/java/ql/src/Likely Bugs/Collections/ReadOnlyContainer.ql +++ b/java/ql/src/Likely Bugs/Collections/ReadOnlyContainer.ql @@ -26,11 +26,15 @@ where // Every access to `v` is either... forall(VarAccess va | va = v.getAnAccess() | // ...an assignment storing a fresh container into `v`, - exists(AssignExpr assgn | va = assgn.getDest() | assgn.getSource() instanceof FreshContainer) or - /// ...a return (but only if `v` is a local variable) - (v instanceof LocalVariableDecl and exists(ReturnStmt ret | ret.getResult() = va)) or + exists(AssignExpr assgn | va = assgn.getDest() | assgn.getSource() instanceof FreshContainer) + or + // ...a return (but only if `v` is a local variable) + (v instanceof LocalVariableDecl and exists(ReturnStmt ret | ret.getResult() = va)) + or // ...or a call to a query method on `v`. - exists(MethodAccess ma | va = ma.getQualifier() | ma.getMethod() instanceof ContainerQueryMethod) + exists(MethodAccess ma | va = ma.getQualifier() | + ma.getMethod() instanceof ContainerQueryMethod + ) ) and // There is at least one call to a query method. exists(MethodAccess ma | v.getAnAccess() = ma.getQualifier() | diff --git a/java/ql/src/Likely Bugs/Collections/RemoveTypeMismatch.ql b/java/ql/src/Likely Bugs/Collections/RemoveTypeMismatch.ql index 7285713714f..c8ed3aa0d06 100644 --- a/java/ql/src/Likely Bugs/Collections/RemoveTypeMismatch.ql +++ b/java/ql/src/Likely Bugs/Collections/RemoveTypeMismatch.ql @@ -11,26 +11,70 @@ * correctness * logic */ + import java import semmle.code.java.Collections predicate containerModification(string package, string type, int p, string signature, int i) { - package = "java.util" and type = "Collection" and p = 0 and signature = "remove(java.lang.Object)" and i = 0 or - package = "java.util" and type = "Deque" and p = 0 and signature = "removeFirstOccurrence(java.lang.Object)" and i = 0 or - package = "java.util" and type = "Deque" and p = 0 and signature = "removeLastOccurrence(java.lang.Object)" and i = 0 or - package = "java.util" and type = "Dictionary" and p = 0 and signature = "remove(java.lang.Object)" and i = 0 or - package = "java.util" and type = "Map" and p = 0 and signature = "remove(java.lang.Object)" and i = 0 or - package = "java.util" and type = "Map" and p = 0 and signature = "remove(java.lang.Object,java.lang.Object)" and i = 0 or - package = "java.util" and type = "Map" and p = 1 and signature = "remove(java.lang.Object,java.lang.Object)" and i = 1 or - package = "java.util" and type = "Vector" and p = 0 and signature = "removeElement(java.lang.Object)" and i = 0 + package = "java.util" and + type = "Collection" and + p = 0 and + signature = "remove(java.lang.Object)" and + i = 0 + or + package = "java.util" and + type = "Deque" and + p = 0 and + signature = "removeFirstOccurrence(java.lang.Object)" and + i = 0 + or + package = "java.util" and + type = "Deque" and + p = 0 and + signature = "removeLastOccurrence(java.lang.Object)" and + i = 0 + or + package = "java.util" and + type = "Dictionary" and + p = 0 and + signature = "remove(java.lang.Object)" and + i = 0 + or + package = "java.util" and + type = "Map" and + p = 0 and + signature = "remove(java.lang.Object)" and + i = 0 + or + package = "java.util" and + type = "Map" and + p = 0 and + signature = "remove(java.lang.Object,java.lang.Object)" and + i = 0 + or + package = "java.util" and + type = "Map" and + p = 1 and + signature = "remove(java.lang.Object,java.lang.Object)" and + i = 1 + or + package = "java.util" and + type = "Vector" and + p = 0 and + signature = "removeElement(java.lang.Object)" and + i = 0 } class MismatchedContainerModification extends MethodAccess { MismatchedContainerModification() { exists(string package, string type, int i | containerModification(package, type, _, getCallee().getSignature(), i) - | - getCallee().getDeclaringType().getASupertype*().getSourceDeclaration().hasQualifiedName(package, type) and + | + getCallee() + .getDeclaringType() + .getASupertype*() + .getSourceDeclaration() + .hasQualifiedName(package, type) and getCallee().getParameter(i).getType() instanceof TypeObject ) } @@ -42,7 +86,7 @@ class MismatchedContainerModification extends MethodAccess { RefType getReceiverElementType(int i) { exists(RefType t, GenericType g, string package, string type, int p | containerModification(package, type, p, getCallee().getSignature(), i) - | + | t = getCallee().getDeclaringType() and t.getASupertype*().getSourceDeclaration() = g and g.hasQualifiedName(package, type) and @@ -66,5 +110,6 @@ where elementtype = ma.getReceiverElementType(idx).getSourceDeclaration() and argtype = ma.getArgumentType(idx) and not haveIntersection(elementtype, argtype) -select ma.getArgument(idx), "Actual argument type '" + argtype.getName() + "'" - + " is incompatible with expected argument type '" + elementtype.getName() + "'." +select ma.getArgument(idx), + "Actual argument type '" + argtype.getName() + "'" + + " is incompatible with expected argument type '" + elementtype.getName() + "'." diff --git a/java/ql/src/Likely Bugs/Collections/WriteOnlyContainer.ql b/java/ql/src/Likely Bugs/Collections/WriteOnlyContainer.ql index 6ba317b93e6..689d223c72b 100644 --- a/java/ql/src/Likely Bugs/Collections/WriteOnlyContainer.ql +++ b/java/ql/src/Likely Bugs/Collections/WriteOnlyContainer.ql @@ -30,7 +30,10 @@ where // Every access to `v` is either... forex(VarAccess va | va = v.getAnAccess() | // ...an assignment storing a new container into `v`, - exists(AssignExpr assgn | va = assgn.getDest() and assgn.getSource() instanceof ClassInstanceExpr) or + exists(AssignExpr assgn | + va = assgn.getDest() and assgn.getSource() instanceof ClassInstanceExpr + ) + or // ...or a call to a mutator method on `v` such that the result of the call is not checked. exists(ContainerMutation cm | va = cm.getQualifier() and not cm.resultIsChecked()) ) and diff --git a/java/ql/src/Likely Bugs/Comparison/BitwiseSignCheck.ql b/java/ql/src/Likely Bugs/Comparison/BitwiseSignCheck.ql index d3945141018..4ed6845c70e 100644 --- a/java/ql/src/Likely Bugs/Comparison/BitwiseSignCheck.ql +++ b/java/ql/src/Likely Bugs/Comparison/BitwiseSignCheck.ql @@ -8,6 +8,7 @@ * @tags reliability * correctness */ + import java from ComparisonExpr e diff --git a/java/ql/src/Likely Bugs/Comparison/CompareIdenticalValues.ql b/java/ql/src/Likely Bugs/Comparison/CompareIdenticalValues.ql index bb27663f69e..4111276f084 100644 --- a/java/ql/src/Likely Bugs/Comparison/CompareIdenticalValues.ql +++ b/java/ql/src/Likely Bugs/Comparison/CompareIdenticalValues.ql @@ -15,7 +15,8 @@ import java predicate comparison(BinaryExpr binop, Expr left, Expr right) { (binop instanceof ComparisonExpr or binop instanceof EqualityTest) and - binop.getLeftOperand() = left and binop.getRightOperand() = right + binop.getLeftOperand() = left and + binop.getRightOperand() = right } /** @@ -41,7 +42,8 @@ predicate varsToCompare(VarAccess left, VarAccess right, Variable v1, Variable v predicate sameVariable(VarAccess left, VarAccess right, Variable v) { varsToCompare(left, right, v, v) and ( - sameVariable(left.getQualifier(), right.getQualifier(), _) or + sameVariable(left.getQualifier(), right.getQualifier(), _) + or left.isLocal() and right.isLocal() ) } @@ -50,8 +52,10 @@ predicate sameVariable(VarAccess left, VarAccess right, Variable v) { predicate equal(Expr left, Expr right) { toCompare(left, right) and ( - left.(Literal).getValue() = right.(Literal).getValue() or - sameVariable(left, right, _) or + left.(Literal).getValue() = right.(Literal).getValue() + or + sameVariable(left, right, _) + or exists(BinaryExpr bLeft, BinaryExpr bRight | bLeft = left and bRight = right | bLeft.getKind() = bRight.getKind() and equal(bLeft.getLeftOperand(), bRight.getLeftOperand()) and @@ -78,6 +82,8 @@ where ( specialCase(comparison, equiv) and msg = "Comparison is " + equiv or - not specialCase(comparison, _) and msg = "Comparison of identical values " + left + " and " + right and equiv="" + not specialCase(comparison, _) and + msg = "Comparison of identical values " + left + " and " + right and + equiv = "" ) select comparison, msg + "." diff --git a/java/ql/src/Likely Bugs/Comparison/CovariantCompareTo.ql b/java/ql/src/Likely Bugs/Comparison/CovariantCompareTo.ql index f54b64ec512..daa81df97e7 100644 --- a/java/ql/src/Likely Bugs/Comparison/CovariantCompareTo.ql +++ b/java/ql/src/Likely Bugs/Comparison/CovariantCompareTo.ql @@ -9,12 +9,12 @@ * @tags reliability * correctness */ + import java -private -predicate implementsComparable(RefType t, RefType param) -{ - exists(ParameterizedType pt | t.getASupertype*() = pt and +private predicate implementsComparable(RefType t, RefType param) { + exists(ParameterizedType pt | + t.getASupertype*() = pt and pt.getSourceDeclaration().hasQualifiedName("java.lang", "Comparable") and param = pt.getATypeArgument() and not param instanceof Wildcard and @@ -22,26 +22,24 @@ predicate implementsComparable(RefType t, RefType param) ) } -private -predicate mostSpecificComparableTypeArgument(RefType t, RefType param) -{ +private predicate mostSpecificComparableTypeArgument(RefType t, RefType param) { implementsComparable(t, param) and not implementsComparable(t, param.getASubtype+()) } -private -predicate mostSpecificComparableTypeArgumentOrTypeObject(RefType t, RefType param) -{ +private predicate mostSpecificComparableTypeArgumentOrTypeObject(RefType t, RefType param) { if mostSpecificComparableTypeArgument(t, _) - then mostSpecificComparableTypeArgument(t, param) - else param instanceof TypeObject + then mostSpecificComparableTypeArgument(t, param) + else param instanceof TypeObject } -private -predicate compareTo(RefType declaring, Method m, RefType param) -{ - m.hasName("compareTo") and m.isPublic() and m.getNumberOfParameters() = 1 and - m.fromSource() and m.getAParamType() = param and declaring = m.getDeclaringType() and +private predicate compareTo(RefType declaring, Method m, RefType param) { + m.hasName("compareTo") and + m.isPublic() and + m.getNumberOfParameters() = 1 and + m.fromSource() and + m.getAParamType() = param and + declaring = m.getDeclaringType() and declaring.getASupertype*().getSourceDeclaration().hasQualifiedName("java.lang", "Comparable") } @@ -52,5 +50,6 @@ where actual != desired and not compareTo(t, _, desired) and not actual instanceof TypeVariable -select m, "The parameter of compareTo should have type '" + desired.getName() - + "' when implementing 'Comparable<" + desired.getName() + ">'." +select m, + "The parameter of compareTo should have type '" + desired.getName() + + "' when implementing 'Comparable<" + desired.getName() + ">'." diff --git a/java/ql/src/Likely Bugs/Comparison/CovariantEquals.ql b/java/ql/src/Likely Bugs/Comparison/CovariantEquals.ql index 926b61d5cd5..13f63f15a72 100644 --- a/java/ql/src/Likely Bugs/Comparison/CovariantEquals.ql +++ b/java/ql/src/Likely Bugs/Comparison/CovariantEquals.ql @@ -9,6 +9,7 @@ * @tags reliability * correctness */ + import java from RefType t, Method equals @@ -18,5 +19,4 @@ where equals.hasName("equals") and equals.getNumberOfParameters() = 1 and not t.getAMethod() instanceof EqualsMethod -select equals, - "To override the equals method, the parameter must be of type java.lang.Object." +select equals, "To override the equals method, the parameter must be of type java.lang.Object." diff --git a/java/ql/src/Likely Bugs/Comparison/DefineEqualsWhenAddingFields.ql b/java/ql/src/Likely Bugs/Comparison/DefineEqualsWhenAddingFields.ql index 1c11f1ab7e3..7e688adb85b 100644 --- a/java/ql/src/Likely Bugs/Comparison/DefineEqualsWhenAddingFields.ql +++ b/java/ql/src/Likely Bugs/Comparison/DefineEqualsWhenAddingFields.ql @@ -10,10 +10,12 @@ * @tags reliability * correctness */ + import java predicate okForEquals(Class c) { - c.getAMethod() instanceof EqualsMethod or + c.getAMethod() instanceof EqualsMethod + or ( not exists(c.getAField()) and okForEquals(c.getASupertype()) @@ -23,7 +25,8 @@ predicate okForEquals(Class c) { /** Holds if method `em` implements a reference equality check. */ predicate checksReferenceEquality(EqualsMethod em) { // `java.lang.Object.equals` is the prototypical reference equality implementation. - em.getDeclaringType() instanceof TypeObject or + em.getDeclaringType() instanceof TypeObject + or // Custom reference equality implementations observed in open-source projects. exists(SingletonBlock blk, EQExpr eq | blk = em.getBody() and @@ -31,7 +34,8 @@ predicate checksReferenceEquality(EqualsMethod em) { eq.getAnOperand().(VarAccess).getVariable() = em.getParameter(0) and ( // `{ return (ojb==this); }` - eq = blk.getStmt().(ReturnStmt).getResult().getProperExpr() or + eq = blk.getStmt().(ReturnStmt).getResult().getProperExpr() + or // `{ if (ojb==this) return true; else return false; }` exists(IfStmt ifStmt | ifStmt = blk.getStmt() | eq = ifStmt.getCondition().getProperExpr() and @@ -39,7 +43,8 @@ predicate checksReferenceEquality(EqualsMethod em) { ifStmt.getElse().(ReturnStmt).getResult().(BooleanLiteral).getBooleanValue() = false ) ) - ) or + ) + or // Check whether `em` delegates to another method checking reference equality. // More precisely, we check whether the body of `em` is of the form `return super.equals(o);`, // where `o` is the (only) parameter of `em`, and the invoked method is a reference equality check. @@ -70,9 +75,7 @@ predicate overridesDelegateEquals(EqualsMethod em, Class c) { ) } -predicate readsOwnField(Method m) { - m.reads(m.getDeclaringType().getAField()) -} +predicate readsOwnField(Method m) { m.reads(m.getDeclaringType().getAField()) } from Class c, InstanceField f, EqualsMethod em where @@ -87,7 +90,5 @@ where c.fromSource() and not c instanceof EnumType and not f.isFinal() -select - c, c.getName() + " inherits $@ but adds $@.", - em.getSourceDeclaration(), em.getDeclaringType().getName() + "." + em.getName(), - f, "the field " + f.getName() +select c, c.getName() + " inherits $@ but adds $@.", em.getSourceDeclaration(), + em.getDeclaringType().getName() + "." + em.getName(), f, "the field " + f.getName() diff --git a/java/ql/src/Likely Bugs/Comparison/EqualsArray.ql b/java/ql/src/Likely Bugs/Comparison/EqualsArray.ql index 4461257fb9a..c7324012fc2 100644 --- a/java/ql/src/Likely Bugs/Comparison/EqualsArray.ql +++ b/java/ql/src/Likely Bugs/Comparison/EqualsArray.ql @@ -9,6 +9,7 @@ * @tags reliability * correctness */ + import java from MethodAccess ma, Array recvtype, Method m @@ -19,6 +20,8 @@ where m instanceof HashCodeMethod or m instanceof EqualsMethod and - haveIntersection(recvtype, (Array)ma.getArgument(0).getType()) + haveIntersection(recvtype, ma.getArgument(0).getType().(Array)) ) -select ma, "The " + m.getName() + " method on arrays only considers object identity and ignores array contents." +select ma, + "The " + m.getName() + + " method on arrays only considers object identity and ignores array contents." diff --git a/java/ql/src/Likely Bugs/Comparison/EqualsUsesInstanceOf.ql b/java/ql/src/Likely Bugs/Comparison/EqualsUsesInstanceOf.ql index d0cd57a84ad..18a734a1c23 100644 --- a/java/ql/src/Likely Bugs/Comparison/EqualsUsesInstanceOf.ql +++ b/java/ql/src/Likely Bugs/Comparison/EqualsUsesInstanceOf.ql @@ -10,6 +10,7 @@ * @tags reliability * correctness */ + import java predicate instanceofInEquals(EqualsMethod m, InstanceOfExpr e) { @@ -29,6 +30,7 @@ where exists(m.getBody()) and m2.fromSource() and exists(Method overridden | overridden.getSourceDeclaration() = m | m2.overrides+(overridden)) -select e, "Possible violation of equals contract due to use of instanceof in $@ and/or overriding $@.", - m, m.getDeclaringType().getName() + "." + m.getName(), - m2, m2.getDeclaringType().getName() + "." + m2.getName() +select e, + "Possible violation of equals contract due to use of instanceof in $@ and/or overriding $@.", m, + m.getDeclaringType().getName() + "." + m.getName(), m2, + m2.getDeclaringType().getName() + "." + m2.getName() diff --git a/java/ql/src/Likely Bugs/Comparison/HashedButNoHash.ql b/java/ql/src/Likely Bugs/Comparison/HashedButNoHash.ql index 7b71da26ae8..1d20e98a21b 100644 --- a/java/ql/src/Likely Bugs/Comparison/HashedButNoHash.ql +++ b/java/ql/src/Likely Bugs/Comparison/HashedButNoHash.ql @@ -9,6 +9,7 @@ * @tags reliability * correctness */ + import java import Equality @@ -34,12 +35,16 @@ predicate hashingMethod(Method m) { /** Holds if `e` is an expression in which `t` is used in a hashing data structure. */ predicate usedInHash(RefType t, Expr e) { - exists(RefType s | s.getName().matches("%Hash%") and not s.getSourceDeclaration().getName() = "IdentityHashMap" | + exists(RefType s | + s.getName().matches("%Hash%") and not s.getSourceDeclaration().getName() = "IdentityHashMap" + | exists(MethodAccess ma | ma.getQualifier().getType() = s and ma.getArgument(0).getType() = t and - e = ma and hashingMethod(ma.getMethod()) - ) or + e = ma and + hashingMethod(ma.getMethod()) + ) + or exists(ConstructorCall cc | cc.getConstructedType() = s and s.(ParameterizedType).getTypeArgument(0) = t and @@ -52,5 +57,6 @@ from RefType t, Expr e where usedInHash(t, e) and eqNoHash(t.getSourceDeclaration()) -select e, "Type '" + t.getName() + "' does not define hashCode(), " - + "but is used in a hashing data-structure." +select e, + "Type '" + t.getName() + "' does not define hashCode(), " + + "but is used in a hashing data-structure." diff --git a/java/ql/src/Likely Bugs/Comparison/IncomparableEquals.ql b/java/ql/src/Likely Bugs/Comparison/IncomparableEquals.ql index d900e9311b4..c083c80c21d 100644 --- a/java/ql/src/Likely Bugs/Comparison/IncomparableEquals.ql +++ b/java/ql/src/Likely Bugs/Comparison/IncomparableEquals.ql @@ -9,13 +9,12 @@ * @tags reliability * correctness */ + import java /** A call to an `equals` method. */ class EqualsCall extends MethodAccess { - EqualsCall() { - this.getMethod() instanceof EqualsMethod - } + EqualsCall() { this.getMethod() instanceof EqualsMethod } /** * A whitelist of method accesses allowed to perform @@ -28,14 +27,10 @@ class EqualsCall extends MethodAccess { } /** Holds if the callee of this method access is `Object.equals`. */ - predicate invokesObjectEquals() { - this.getMethod().getDeclaringType() instanceof TypeObject - } + predicate invokesObjectEquals() { this.getMethod().getDeclaringType() instanceof TypeObject } /** Return the (static) type of the argument to `equals`. */ - RefType getArgumentType() { - result = this.getArgument(0).getType() - } + RefType getArgumentType() { result = this.getArgument(0).getType() } } /* @@ -52,12 +47,17 @@ class EqualsCall extends MethodAccess { * operand to be a subtype of `A`. Hence, if `A` and the static type of the argument * have no intersection, the result is again guaranteed to be false. */ + from EqualsCall ma, RefType recvtp, RefType argtp where not ma.whitelisted() and - (if ma.invokesObjectEquals() - then recvtp = ma.getReceiverType() - else recvtp = ma.getMethod().getDeclaringType()) and + ( + if ma.invokesObjectEquals() + then recvtp = ma.getReceiverType() + else recvtp = ma.getMethod().getDeclaringType() + ) and argtp = ma.getArgumentType() and not haveIntersection(recvtp, argtp) -select ma, "Call to equals() comparing incomparable types " + recvtp.getName() + " and " + argtp.getName() + "." +select ma, + "Call to equals() comparing incomparable types " + recvtp.getName() + " and " + argtp.getName() + + "." diff --git a/java/ql/src/Likely Bugs/Comparison/InconsistentCompareTo.ql b/java/ql/src/Likely Bugs/Comparison/InconsistentCompareTo.ql index ef434c20359..e5b784e6f6e 100644 --- a/java/ql/src/Likely Bugs/Comparison/InconsistentCompareTo.ql +++ b/java/ql/src/Likely Bugs/Comparison/InconsistentCompareTo.ql @@ -9,6 +9,7 @@ * @tags reliability * correctness */ + import java import semmle.code.java.frameworks.Lombok @@ -17,9 +18,10 @@ predicate implementsComparableOn(RefType t, RefType typeArg) { exists(RefType cmp | t.getAnAncestor() = cmp and cmp.getSourceDeclaration().hasQualifiedName("java.lang", "Comparable") - | + | // Either `t` extends `Comparable`, in which case `typeArg` is `T`, ... - typeArg = cmp.(ParameterizedType).getATypeArgument() and not typeArg instanceof Wildcard or + typeArg = cmp.(ParameterizedType).getATypeArgument() and not typeArg instanceof Wildcard + or // ... or it extends the raw type `Comparable`, in which case `typeArg` is `Object`. cmp instanceof RawType and typeArg instanceof TypeObject ) diff --git a/java/ql/src/Likely Bugs/Comparison/InconsistentEqualsHashCode.ql b/java/ql/src/Likely Bugs/Comparison/InconsistentEqualsHashCode.ql index e740d0547c0..b788caec0e1 100644 --- a/java/ql/src/Likely Bugs/Comparison/InconsistentEqualsHashCode.ql +++ b/java/ql/src/Likely Bugs/Comparison/InconsistentEqualsHashCode.ql @@ -10,6 +10,7 @@ * correctness * external/cwe/cwe-581 */ + import java import Equality @@ -23,7 +24,9 @@ where or not exists(HashCodeMethod h | h.getDeclaringType() = c) and // If the inherited `equals` is a refining `equals` then the superclass hash code is still valid. - exists(EqualsMethod e | e.getDeclaringType() = c and e = existingMethod and not e instanceof RefiningEquals) and + exists(EqualsMethod e | + e.getDeclaringType() = c and e = existingMethod and not e instanceof RefiningEquals + ) and message = "Class " + c.getName() + " overrides $@ but not hashCode." ) select c, message, existingMethod, existingMethod.getName() diff --git a/java/ql/src/Likely Bugs/Comparison/MissingInstanceofInEquals.ql b/java/ql/src/Likely Bugs/Comparison/MissingInstanceofInEquals.ql index e49fec8f6ee..fdc8a8b1908 100644 --- a/java/ql/src/Likely Bugs/Comparison/MissingInstanceofInEquals.ql +++ b/java/ql/src/Likely Bugs/Comparison/MissingInstanceofInEquals.ql @@ -9,6 +9,7 @@ * @tags reliability * correctness */ + import semmle.code.java.Member import semmle.code.java.JDK @@ -22,12 +23,11 @@ class CheckedCast extends CastExpr { ) } - Variable castVariable() { - result.getAnAccess() = this.getExpr() - } + Variable castVariable() { result.getAnAccess() = this.getExpr() } } -/** An `equals` method with a body of either `return o == this;` +/** + * An `equals` method with a body of either `return o == this;` * or `return o == field;` */ class ReferenceEquals extends EqualsMethod { @@ -35,7 +35,11 @@ class ReferenceEquals extends EqualsMethod { exists(Block b, ReturnStmt ret, EQExpr eq | this.getBody() = b and b.getStmt(0) = ret and - (ret.getResult() = eq or exists(ParExpr pe | ret.getResult() = pe and pe.getExpr() = eq)) and + ( + ret.getResult() = eq + or + exists(ParExpr pe | ret.getResult() = pe and pe.getExpr() = eq) + ) and eq.getAnOperand() = this.getAParameter().getAnAccess() and (eq.getAnOperand() instanceof ThisAccess or eq.getAnOperand() instanceof FieldAccess) ) @@ -53,10 +57,14 @@ where ) and // Exclude cases that are probably OK. not exists(MethodAccess ma, Method c | ma.getEnclosingCallable() = m and ma.getMethod() = c | - c.hasName("getClass") or - c.hasName("compareTo") or - c.hasName("equals") or - c.hasName("isInstance") or + c.hasName("getClass") + or + c.hasName("compareTo") + or + c.hasName("equals") + or + c.hasName("isInstance") + or c.hasName("reflectionEquals") or // If both `this` and the argument are passed to another method, @@ -64,7 +72,8 @@ where // that method may do the right thing. ma.getAnArgument() = m.getParameter().getAnAccess() and ( - ma.getAnArgument() instanceof ThisAccess or + ma.getAnArgument() instanceof ThisAccess + or exists(Method delegate | delegate.getSourceDeclaration() = ma.getMethod() | m.getDeclaringType().inherits(delegate) ) diff --git a/java/ql/src/Likely Bugs/Comparison/NoAssignInBooleanExprs.ql b/java/ql/src/Likely Bugs/Comparison/NoAssignInBooleanExprs.ql index b3e8351a2af..b04f8de49b5 100644 --- a/java/ql/src/Likely Bugs/Comparison/NoAssignInBooleanExprs.ql +++ b/java/ql/src/Likely Bugs/Comparison/NoAssignInBooleanExprs.ql @@ -10,6 +10,7 @@ * readability * external/cwe/cwe-481 */ + import semmle.code.java.Expr import semmle.code.java.Statement diff --git a/java/ql/src/Likely Bugs/Comparison/NoComparisonOnFloats.ql b/java/ql/src/Likely Bugs/Comparison/NoComparisonOnFloats.ql index 992e6e8c779..9c96dc67d63 100644 --- a/java/ql/src/Likely Bugs/Comparison/NoComparisonOnFloats.ql +++ b/java/ql/src/Likely Bugs/Comparison/NoComparisonOnFloats.ql @@ -8,6 +8,7 @@ * @tags reliability * correctness */ + import semmle.code.java.Type import semmle.code.java.Expr @@ -30,18 +31,18 @@ predicate trivialLiteral(Literal e) { predicate definedConstant(Expr e) { exists(Field f | - f.isStatic() and ( + f.isStatic() and + ( f.getDeclaringType().hasName("Float") or f.getDeclaringType().hasName("Double") - ) | + ) + | e = f.getAnAccess() ) } // The contract of `compareTo` would not really allow anything other than `<` or `>` on floats. -predicate comparisonMethod(Method m) { - m.getName() = "compareTo" -} +predicate comparisonMethod(Method m) { m.getName() = "compareTo" } // Check for equalities of the form `a.x == b.x` or `a.x == x`, where `x` is assigned to `a.x`, // which are less interesting but occur often. @@ -49,7 +50,8 @@ predicate similarVarComparison(EqualityTest e) { exists(Field f | e.getLeftOperand() = f.getAnAccess() and e.getRightOperand() = f.getAnAccess() - ) or + ) + or exists(Field f, Variable v | e.getAnOperand() = f.getAnAccess() and e.getAnOperand() = v.getAnAccess() and diff --git a/java/ql/src/Likely Bugs/Comparison/ObjectComparison.ql b/java/ql/src/Likely Bugs/Comparison/ObjectComparison.ql index 7d07d033a75..2958e690a2f 100644 --- a/java/ql/src/Likely Bugs/Comparison/ObjectComparison.ql +++ b/java/ql/src/Likely Bugs/Comparison/ObjectComparison.ql @@ -10,14 +10,13 @@ * correctness * external/cwe/cwe-595 */ + import semmle.code.java.Member import semmle.code.java.JDK /** An expression that accesses a field declared `final`. */ class FinalFieldAccess extends VarAccess { - FinalFieldAccess() { - this.getVariable().(Field).isFinal() - } + FinalFieldAccess() { this.getVariable().(Field).isFinal() } } class ReferenceEqualityTestOnObject extends EqualityTest { diff --git a/java/ql/src/Likely Bugs/Comparison/RefEqBoxed.ql b/java/ql/src/Likely Bugs/Comparison/RefEqBoxed.ql index 6c053638f82..bf97d94b3e2 100644 --- a/java/ql/src/Likely Bugs/Comparison/RefEqBoxed.ql +++ b/java/ql/src/Likely Bugs/Comparison/RefEqBoxed.ql @@ -10,6 +10,7 @@ * correctness * external/cwe/cwe-595 */ + import java from EqualityTest c diff --git a/java/ql/src/Likely Bugs/Comparison/StringComparison.ql b/java/ql/src/Likely Bugs/Comparison/StringComparison.ql index a76a57d9382..1bb67c04a67 100644 --- a/java/ql/src/Likely Bugs/Comparison/StringComparison.ql +++ b/java/ql/src/Likely Bugs/Comparison/StringComparison.ql @@ -9,13 +9,12 @@ * @tags reliability * external/cwe/cwe-597 */ + import java /** An expression of type `java.lang.String`. */ class StringValue extends Expr { - StringValue() { - this.getType() instanceof TypeString - } + StringValue() { this.getType() instanceof TypeString } predicate isInterned() { // A call to `String.intern()`. diff --git a/java/ql/src/Likely Bugs/Comparison/UselessComparisonTest.ql b/java/ql/src/Likely Bugs/Comparison/UselessComparisonTest.ql index c9a76381cd3..818ba676241 100644 --- a/java/ql/src/Likely Bugs/Comparison/UselessComparisonTest.ql +++ b/java/ql/src/Likely Bugs/Comparison/UselessComparisonTest.ql @@ -12,6 +12,7 @@ * external/cwe/cwe-570 * external/cwe/cwe-571 */ + import semmle.code.java.controlflow.Guards import semmle.code.java.dataflow.SSA import semmle.code.java.dataflow.SignAnalysis @@ -19,45 +20,67 @@ import semmle.code.java.dataflow.RangeAnalysis /** Holds if `cond` always evaluates to `isTrue`. */ predicate constCond(BinaryExpr cond, boolean isTrue, Reason reason) { - exists(ComparisonExpr comp, Expr lesser, Expr greater, Bound b, int d1, int d2, Reason r1, Reason r2 | + exists( + ComparisonExpr comp, Expr lesser, Expr greater, Bound b, int d1, int d2, Reason r1, Reason r2 + | comp = cond and lesser = comp.getLesserOperand() and greater = comp.getGreaterOperand() and bounded(lesser, b, d1, isTrue, r1) and bounded(greater, b, d2, isTrue.booleanNot(), r2) and (reason = r1 or reason = r2) and - (r1 instanceof NoReason and r2 instanceof NoReason or not reason instanceof NoReason) - | - isTrue = true and comp.isStrict() and d1 < d2 or - isTrue = true and not comp.isStrict() and d1 <= d2 or - isTrue = false and comp.isStrict() and d1 >= d2 or + ( + r1 instanceof NoReason and r2 instanceof NoReason + or + not reason instanceof NoReason + ) + | + isTrue = true and comp.isStrict() and d1 < d2 + or + isTrue = true and not comp.isStrict() and d1 <= d2 + or + isTrue = false and comp.isStrict() and d1 >= d2 + or isTrue = false and not comp.isStrict() and d1 > d2 - ) or + ) + or exists(EqualityTest eq, Expr lhs, Expr rhs | eq = cond and lhs = eq.getLeftOperand() and rhs = eq.getRightOperand() - | + | exists(Bound b, int d1, int d2, boolean upper, Reason r1, Reason r2 | bounded(lhs, b, d1, upper, r1) and bounded(rhs, b, d2, upper.booleanNot(), r2) and isTrue = eq.polarity().booleanNot() and (reason = r1 or reason = r2) and - (r1 instanceof NoReason and r2 instanceof NoReason or not reason instanceof NoReason) - | - upper = true and d1 < d2 or // lhs <= b + d1 < b + d2 <= rhs - upper = false and d1 > d2 // lhs >= b + d1 > b + d2 >= rhs - ) or + ( + r1 instanceof NoReason and r2 instanceof NoReason + or + not reason instanceof NoReason + ) + | + upper = true and d1 < d2 // lhs <= b + d1 < b + d2 <= rhs + or + upper = false and d1 > d2 // lhs >= b + d1 > b + d2 >= rhs + ) + or exists(Bound b, int d, Reason r1, Reason r2, Reason r3, Reason r4 | bounded(lhs, b, d, true, r1) and bounded(lhs, b, d, false, r2) and bounded(rhs, b, d, true, r3) and bounded(rhs, b, d, false, r4) and isTrue = eq.polarity() - | + | (reason = r1 or reason = r2 or reason = r3 or reason = r4) and - (r1 instanceof NoReason and r2 instanceof NoReason and r3 instanceof NoReason and r4 instanceof NoReason or - not reason instanceof NoReason) + ( + r1 instanceof NoReason and + r2 instanceof NoReason and + r3 instanceof NoReason and + r4 instanceof NoReason + or + not reason instanceof NoReason + ) ) ) } @@ -73,34 +96,41 @@ Expr overFlowCand() { result = bin and positive(bin.getLeftOperand()) and positive(bin.getRightOperand()) - | + | bin instanceof AddExpr or bin instanceof MulExpr or bin instanceof LShiftExpr - ) or + ) + or exists(AssignOp op | result = op and positive(op.getDest()) and positive(op.getRhs()) - | + | op instanceof AssignAddExpr or op instanceof AssignMulExpr or op instanceof AssignLShiftExpr - ) or + ) + or exists(AddExpr add, CompileTimeConstantExpr c | result = add and add.hasOperands(overFlowCand(), c) and c.getIntValue() >= 0 - ) or + ) + or exists(AssignAddExpr add, CompileTimeConstantExpr c | result = add and add.getDest() = overFlowCand() and add.getRhs() = c and c.getIntValue() >= 0 - ) or - exists(SsaExplicitUpdate x | result = x.getAUse() and x.getDefiningExpr() = overFlowCand()) or - result.(ParExpr).getExpr() = overFlowCand() or - result.(AssignExpr).getRhs() = overFlowCand() or + ) + or + exists(SsaExplicitUpdate x | result = x.getAUse() and x.getDefiningExpr() = overFlowCand()) + or + result.(ParExpr).getExpr() = overFlowCand() + or + result.(AssignExpr).getRhs() = overFlowCand() + or result.(LocalVariableDeclExpr).getInit() = overFlowCand() } @@ -110,15 +140,20 @@ Expr increaseOfVar(SsaVariable v) { result = add and positive(add.getDest()) and add.getRhs() = v.getAUse() - ) or + ) + or exists(AddExpr add, Expr e | result = add and add.hasOperands(v.getAUse(), e) and positive(e) - ) or - exists(SsaExplicitUpdate x | result = x.getAUse() and x.getDefiningExpr() = increaseOfVar(v)) or - result.(ParExpr).getExpr() = increaseOfVar(v) or - result.(AssignExpr).getRhs() = increaseOfVar(v) or + ) + or + exists(SsaExplicitUpdate x | result = x.getAUse() and x.getDefiningExpr() = increaseOfVar(v)) + or + result.(ParExpr).getExpr() = increaseOfVar(v) + or + result.(AssignExpr).getRhs() = increaseOfVar(v) + or result.(LocalVariableDeclExpr).getInit() = increaseOfVar(v) } @@ -126,12 +161,12 @@ predicate overFlowTest(ComparisonExpr comp) { exists(SsaVariable v | comp.getLesserOperand() = increaseOfVar(v) and comp.getGreaterOperand() = v.getAUse() - ) or + ) + or comp.getLesserOperand() = overFlowCand() and comp.getGreaterOperand().(IntegerLiteral).getIntValue() = 0 } - /** * Holds if `test` and `guard` are equality tests of the same integral variable v with constants `c1` and `c2`. */ @@ -160,12 +195,19 @@ predicate uselessEqTest(EqualityTest test, boolean testIsTrue, Guard guard) { from BinaryExpr test, boolean testIsTrue, string reason, ExprParent reasonElem where ( - if uselessEqTest(test, _, _) then - exists(EqualityTest r | uselessEqTest(test, testIsTrue, r) and reason = ", because of $@" and reasonElem = r) - else if constCondSimple(test, _) then - (constCondSimple(test, testIsTrue) and reason = "" and reasonElem = test) // dummy reason element + if uselessEqTest(test, _, _) + then + exists(EqualityTest r | + uselessEqTest(test, testIsTrue, r) and reason = ", because of $@" and reasonElem = r + ) else - exists(CondReason r | constCond(test, testIsTrue, r) and reason = ", because of $@" and reasonElem = r.getCond()) + if constCondSimple(test, _) + then ( + constCondSimple(test, testIsTrue) and reason = "" and reasonElem = test // dummy reason element + ) else + exists(CondReason r | + constCond(test, testIsTrue, r) and reason = ", because of $@" and reasonElem = r.getCond() + ) ) and not overFlowTest(test) and not exists(AssertStmt assert | assert.getExpr() = test.getParent*()) diff --git a/java/ql/src/Likely Bugs/Comparison/WrongNanComparison.ql b/java/ql/src/Likely Bugs/Comparison/WrongNanComparison.ql index 5feafcec9a8..b66b8e7323a 100644 --- a/java/ql/src/Likely Bugs/Comparison/WrongNanComparison.ql +++ b/java/ql/src/Likely Bugs/Comparison/WrongNanComparison.ql @@ -8,6 +8,7 @@ * @id java/comparison-with-nan * @tags correctness */ + import java predicate nanField(Field f) { @@ -16,5 +17,8 @@ predicate nanField(Field f) { } from EqualityTest eq, Field f, string classname -where eq.getAnOperand() = f.getAnAccess() and nanField(f) and f.getDeclaringType().hasName(classname) -select eq, "This comparison will always yield the same result since 'NaN != NaN'. Consider using " + classname + ".isNaN instead" +where + eq.getAnOperand() = f.getAnAccess() and nanField(f) and f.getDeclaringType().hasName(classname) +select eq, + "This comparison will always yield the same result since 'NaN != NaN'. Consider using " + + classname + ".isNaN instead" diff --git a/java/ql/src/Likely Bugs/Concurrency/BusyWait.ql b/java/ql/src/Likely Bugs/Concurrency/BusyWait.ql index 191f14a769a..d71570cc6b3 100644 --- a/java/ql/src/Likely Bugs/Concurrency/BusyWait.ql +++ b/java/ql/src/Likely Bugs/Concurrency/BusyWait.ql @@ -13,6 +13,7 @@ * correctness * concurrency */ + import java class ReachFromStmt extends Stmt { @@ -25,14 +26,12 @@ class ReachFromStmt extends Stmt { class SleepMethod extends Method { SleepMethod() { this.getName() = "sleep" and - this.getDeclaringType().hasQualifiedName("java.lang","Thread") + this.getDeclaringType().hasQualifiedName("java.lang", "Thread") } } class SleepMethodAccess extends MethodAccess { - SleepMethodAccess() { - this.getMethod() instanceof SleepMethod - } + SleepMethodAccess() { this.getMethod() instanceof SleepMethod } } class WaitMethod extends Method { @@ -43,9 +42,7 @@ class WaitMethod extends Method { } class ConcurrentMethod extends Method { - ConcurrentMethod() { - this.getDeclaringType().getQualifiedName().matches("java.util.concurrent%") - } + ConcurrentMethod() { this.getDeclaringType().getQualifiedName().matches("java.util.concurrent%") } } class CommunicationMethod extends Method { @@ -67,9 +64,7 @@ predicate callsCommunicationMethod(Method source) { } class DangerStmt extends Stmt { - DangerStmt() { - exists(SleepMethodAccess sleep | sleep.getEnclosingStmt() = this) - } + DangerStmt() { exists(SleepMethodAccess sleep | sleep.getEnclosingStmt() = this) } } from WhileStmt s, DangerStmt d diff --git a/java/ql/src/Likely Bugs/Concurrency/CallsToConditionWait.ql b/java/ql/src/Likely Bugs/Concurrency/CallsToConditionWait.ql index d92d3e92986..9962596d5b6 100644 --- a/java/ql/src/Likely Bugs/Concurrency/CallsToConditionWait.ql +++ b/java/ql/src/Likely Bugs/Concurrency/CallsToConditionWait.ql @@ -11,6 +11,7 @@ * concurrency * external/cwe/cwe-662 */ + import java class WaitMethod extends Method { @@ -22,9 +23,7 @@ class WaitMethod extends Method { } class ConditionInterface extends Interface { - ConditionInterface() { - this.hasQualifiedName("java.util.concurrent.locks", "Condition") - } + ConditionInterface() { this.hasQualifiedName("java.util.concurrent.locks", "Condition") } } from MethodAccess ma, ConditionInterface condition diff --git a/java/ql/src/Likely Bugs/Concurrency/CallsToRunnableRun.ql b/java/ql/src/Likely Bugs/Concurrency/CallsToRunnableRun.ql index de5c596978f..110ccce02ca 100644 --- a/java/ql/src/Likely Bugs/Concurrency/CallsToRunnableRun.ql +++ b/java/ql/src/Likely Bugs/Concurrency/CallsToRunnableRun.ql @@ -11,10 +11,11 @@ * concurrency * external/cwe/cwe-572 */ + import java -class RunMethod extends Method{ - RunMethod(){ +class RunMethod extends Method { + RunMethod() { this.hasName("run") and this.hasNoParameters() and this.getDeclaringType().getASupertype*().hasQualifiedName("java.lang", "Thread") diff --git a/java/ql/src/Likely Bugs/Concurrency/DateFormatThreadUnsafe.ql b/java/ql/src/Likely Bugs/Concurrency/DateFormatThreadUnsafe.ql index 1d4873f77ec..19da60422c8 100644 --- a/java/ql/src/Likely Bugs/Concurrency/DateFormatThreadUnsafe.ql +++ b/java/ql/src/Likely Bugs/Concurrency/DateFormatThreadUnsafe.ql @@ -10,6 +10,7 @@ * correctness * concurrency */ + import java from Field f, Class dateFormat @@ -20,5 +21,6 @@ where dateFormat.hasQualifiedName("java.text", "DateFormat") and f.getType().(RefType).hasSupertype*(dateFormat) and exists(MethodAccess m | m.getQualifier().(VarAccess).getVariable() = f) -select f, "Found static field of type " + f.getType().getName() + " in " - + f.getDeclaringType().getName() + "." +select f, + "Found static field of type " + f.getType().getName() + " in " + f.getDeclaringType().getName() + + "." diff --git a/java/ql/src/Likely Bugs/Concurrency/EmptyRunMethodInThread.ql b/java/ql/src/Likely Bugs/Concurrency/EmptyRunMethodInThread.ql index 25388345b4c..8459fc1e59a 100644 --- a/java/ql/src/Likely Bugs/Concurrency/EmptyRunMethodInThread.ql +++ b/java/ql/src/Likely Bugs/Concurrency/EmptyRunMethodInThread.ql @@ -10,12 +10,11 @@ * correctness * concurrency */ + import java class ThreadClass extends Class { - ThreadClass() { - this.hasQualifiedName("java.lang", "Thread") - } + ThreadClass() { this.hasQualifiedName("java.lang", "Thread") } /** * Any constructor of `java.lang.Thread` _without_ a parameter of type `Runnable`; @@ -24,11 +23,13 @@ class ThreadClass extends Class { Constructor getAConstructorWithoutRunnableParam() { result = this.getAConstructor() and ( - result.getNumberOfParameters() = 0 or + result.getNumberOfParameters() = 0 + or ( result.getNumberOfParameters() = 1 and result.getParameter(0).getType().(RefType).hasQualifiedName("java.lang", "String") - ) or + ) + or ( result.getNumberOfParameters() = 2 and result.getParameter(0).getType().(RefType).hasQualifiedName("java.lang", "ThreadGroup") and @@ -61,4 +62,5 @@ where ) and not cie.getConstructor().callsConstructor*(thread.getAConstructorWithRunnableParam()) and cie.getType().(RefType).getSourceDeclaration() = emptythread -select cie, "Thread " + emptythread.getName() + " has a useless empty run() inherited from java.lang.Thread." +select cie, + "Thread " + emptythread.getName() + " has a useless empty run() inherited from java.lang.Thread." diff --git a/java/ql/src/Likely Bugs/Concurrency/FutileSynchOnField.ql b/java/ql/src/Likely Bugs/Concurrency/FutileSynchOnField.ql index 5e575c38e10..92c48bac81d 100644 --- a/java/ql/src/Likely Bugs/Concurrency/FutileSynchOnField.ql +++ b/java/ql/src/Likely Bugs/Concurrency/FutileSynchOnField.ql @@ -12,22 +12,17 @@ * language-features * external/cwe/cwe-662 */ + import java -private -Field synchField(SynchronizedStmt s) { - result = s.getExpr().(VarAccess).getVariable() -} +private Field synchField(SynchronizedStmt s) { result = s.getExpr().(VarAccess).getVariable() } -private -Field assignmentToField(Assignment a) { - result = a.getDest().(VarAccess).getVariable() -} +private Field assignmentToField(Assignment a) { result = a.getDest().(VarAccess).getVariable() } from SynchronizedStmt s, Field f, Assignment a where synchField(s) = f and assignmentToField(a) = f and a.getEnclosingStmt().getParent*() = s -select a, "Synchronization on field $@ in futile attempt to guard that field.", - f, f.getDeclaringType().getName() + "." + f.getName() +select a, "Synchronization on field $@ in futile attempt to guard that field.", f, + f.getDeclaringType().getName() + "." + f.getName() diff --git a/java/ql/src/Likely Bugs/Concurrency/InconsistentAccess.ql b/java/ql/src/Likely Bugs/Concurrency/InconsistentAccess.ql index 83c46e623ad..7ed282549e0 100644 --- a/java/ql/src/Likely Bugs/Concurrency/InconsistentAccess.ql +++ b/java/ql/src/Likely Bugs/Concurrency/InconsistentAccess.ql @@ -15,6 +15,7 @@ * statistical * non-attributable */ + import java predicate withinInitializer(Expr e) { @@ -29,7 +30,9 @@ predicate locallySynchronized(MethodAccess ma) { predicate hasUnsynchronizedCall(Method m) { (m.isPublic() and not m.isSynchronized()) or - exists(MethodAccess ma, Method caller | ma.getMethod() = m and caller = ma.getEnclosingCallable() | + exists(MethodAccess ma, Method caller | + ma.getMethod() = m and caller = ma.getEnclosingCallable() + | hasUnsynchronizedCall(caller) and not caller.isSynchronized() and not locallySynchronized(ma) @@ -50,15 +53,15 @@ class MyField extends Field { } int getNumSynchedAccesses() { - result = count(Expr synched | synched = this.getAnAccess() and withinLocalSynchronization(synched)) + result = count(Expr synched | + synched = this.getAnAccess() and withinLocalSynchronization(synched) + ) } - int getNumAccesses() { - result = count(this.getAnAccess()) - } + int getNumAccesses() { result = count(this.getAnAccess()) } float getPercentSynchedAccesses() { - result = (float)this.getNumSynchedAccesses() / this.getNumAccesses() + result = this.getNumSynchedAccesses().(float) / this.getNumAccesses() } } @@ -71,5 +74,7 @@ where f.getNumSynchedAccesses() > 0 and percent = (f.getPercentSynchedAccesses() * 100).floor() and percent > 80 -select e, "Unsynchronized access to $@, but " + percent.toString() + "% of accesses to this field are synchronized.", - f, f.getDeclaringType().getName() + "." + f.getName() +select e, + "Unsynchronized access to $@, but " + percent.toString() + + "% of accesses to this field are synchronized.", f, + f.getDeclaringType().getName() + "." + f.getName() diff --git a/java/ql/src/Likely Bugs/Concurrency/LazyInitStaticField.ql b/java/ql/src/Likely Bugs/Concurrency/LazyInitStaticField.ql index 7b3000789ff..4fa44a12da8 100644 --- a/java/ql/src/Likely Bugs/Concurrency/LazyInitStaticField.ql +++ b/java/ql/src/Likely Bugs/Concurrency/LazyInitStaticField.ql @@ -12,26 +12,17 @@ * external/cwe/cwe-543 * external/cwe/cwe-609 */ + import java /** A comparison (using `==`) with `null`. */ -class NullEQExpr extends EQExpr { - NullEQExpr() { - exists(NullLiteral l | l.getParent() = this) - } -} +class NullEQExpr extends EQExpr { NullEQExpr() { exists(NullLiteral l | l.getParent() = this) } } /** An assignment to a static field. */ class StaticFieldInit extends AssignExpr { - StaticFieldInit() { - exists(Field f | f.isStatic() | - f.getAnAccess() = this.getDest() - ) - } + StaticFieldInit() { exists(Field f | f.isStatic() | f.getAnAccess() = this.getDest()) } - Field getField() { - result.getAnAccess() = this.getDest() - } + Field getField() { result.getAnAccess() = this.getDest() } IfStmt getAnEnclosingNullCheck() { result.getThen().getAChild*() = this.getEnclosingStmt() and @@ -58,9 +49,13 @@ class LockObjectField extends Field { class ValidSynchStmt extends Stmt { ValidSynchStmt() { // It's OK to lock the enclosing class. - this.(SynchronizedStmt).getExpr().(TypeLiteral).getTypeName().getType() = this.getEnclosingCallable().getDeclaringType() or + this.(SynchronizedStmt).getExpr().(TypeLiteral).getTypeName().getType() = this + .getEnclosingCallable() + .getDeclaringType() + or // It's OK to lock on a "lock object field". - this.(SynchronizedStmt).getExpr().(FieldRead).getField() instanceof LockObjectField or + this.(SynchronizedStmt).getExpr().(FieldRead).getField() instanceof LockObjectField + or // Locking via `ReentrantLock` lock object instead of synchronized statement. exists(TryStmt try, LockObjectField lockField | this = try.getBlock() and @@ -99,15 +94,17 @@ where exists(IfStmt unsyncNullCheck | unsyncNullCheck = init.getAnEnclosingNullCheck() | not unsyncNullCheck.getParent+() instanceof ValidSynchStmt ) and - if (i.getParent+() instanceof ValidSynchStmt) then ( + if (i.getParent+() instanceof ValidSynchStmt) + then ( not init.getField().isVolatile() and message = "The field must be volatile." ) else ( - if (i.getParent+() instanceof SynchronizedStmt) then ( + if (i.getParent+() instanceof SynchronizedStmt) + then ( message = "Bad synchronization." ) else ( message = "Missing synchronization." ) ) -select init, "Incorrect lazy initialization of static field $@: " + message, - init.getField() as f, f.getName() +select init, "Incorrect lazy initialization of static field $@: " + message, init.getField() as f, + f.getName() diff --git a/java/ql/src/Likely Bugs/Concurrency/NonSynchronizedOverride.ql b/java/ql/src/Likely Bugs/Concurrency/NonSynchronizedOverride.ql index eca0dc5f041..735d594d398 100644 --- a/java/ql/src/Likely Bugs/Concurrency/NonSynchronizedOverride.ql +++ b/java/ql/src/Likely Bugs/Concurrency/NonSynchronizedOverride.ql @@ -24,8 +24,10 @@ predicate delegatingSuperCall(Expr e, Method target) { call.getQualifier() instanceof SuperAccess and call.getCallee() = target and forall(Expr arg | arg = call.getAnArgument() | arg instanceof VarAccess) - ) or - delegatingSuperCall(e.(CastExpr).getExpr(), target) or + ) + or + delegatingSuperCall(e.(CastExpr).getExpr(), target) + or delegatingSuperCall(e.(ParExpr).getExpr(), target) } diff --git a/java/ql/src/Likely Bugs/Concurrency/NotifyWithoutSynch.ql b/java/ql/src/Likely Bugs/Concurrency/NotifyWithoutSynch.ql index aab5f55798f..0c3ba8baedc 100644 --- a/java/ql/src/Likely Bugs/Concurrency/NotifyWithoutSynch.ql +++ b/java/ql/src/Likely Bugs/Concurrency/NotifyWithoutSynch.ql @@ -10,6 +10,7 @@ * concurrency * language-features */ + import java /** The set of methods to test: `wait`, `notify`, `notifyAll`. */ @@ -19,9 +20,8 @@ class MethodRequiresSynch extends Method { this.hasName("wait") or this.hasName("notify") or this.hasName("notifyAll") - ) - and - this.getDeclaringType().hasQualifiedName("java.lang","Object") + ) and + this.getDeclaringType().hasQualifiedName("java.lang", "Object") } } @@ -44,9 +44,9 @@ class MethodRequiresSynch extends Method { * } * ``` */ -private -predicate synchronizedCallable(Callable c) { - c.isSynchronized() or +private predicate synchronizedCallable(Callable c) { + c.isSynchronized() + or ( c.isPrivate() and forall(MethodAccess parent | parent.getCallee() = c | @@ -62,14 +62,14 @@ predicate synchronizedCallable(Callable c) { * example, if the method call is `MyClass.wait()`, then the predicate * holds if there is an enclosing synchronization on `MyClass.this`. */ -private -predicate synchronizedThisAccess(MethodAccess ma, Type thisType) { +private predicate synchronizedThisAccess(MethodAccess ma, Type thisType) { // Are we inside a synchronized method? exists(Callable c | c = ma.getEnclosingCallable() and c.getDeclaringType() = thisType and synchronizedCallable(c) - ) or + ) + or // Is there an enclosing `synchronized` statement? exists(SynchronizedStmt s, ThisAccess x | s.getAChild*() = ma.getEnclosingStmt() and @@ -96,8 +96,7 @@ predicate synchronizedVarAccess(VarAccess x) { * such as `this.wait()`, and it is not inside a synchronized statement * or method. */ -private -predicate unsynchronizedExplicitThisAccess(MethodAccess ma) { +private predicate unsynchronizedExplicitThisAccess(MethodAccess ma) { exists(ThisAccess x | x = ma.getQualifier() and not synchronizedThisAccess(ma, x.getType()) @@ -109,8 +108,7 @@ predicate unsynchronizedExplicitThisAccess(MethodAccess ma) { * such as `wait()`, and it is not inside a synchronized statement * or method. */ -private -predicate unsynchronizedImplicitThisAccess(MethodAccess ma) { +private predicate unsynchronizedImplicitThisAccess(MethodAccess ma) { not ma.hasQualifier() and not synchronizedThisAccess(ma, ma.getEnclosingCallable().getDeclaringType()) } @@ -119,8 +117,7 @@ predicate unsynchronizedImplicitThisAccess(MethodAccess ma) { * Holds if the `MethodAccess` is on a variable, * such as `x.wait()`, and it is not inside a synchronized statement. */ -private -predicate unsynchronizedVarAccess(MethodAccess ma) { +private predicate unsynchronizedVarAccess(MethodAccess ma) { exists(VarAccess x | x = ma.getQualifier() and not synchronizedVarAccess(x) diff --git a/java/ql/src/Likely Bugs/Concurrency/PriorityCalls.ql b/java/ql/src/Likely Bugs/Concurrency/PriorityCalls.ql index 4a0612c74c6..3c309eb7938 100644 --- a/java/ql/src/Likely Bugs/Concurrency/PriorityCalls.ql +++ b/java/ql/src/Likely Bugs/Concurrency/PriorityCalls.ql @@ -10,19 +10,18 @@ * correctness * concurrency */ + import java class PriorityMethod extends Method { PriorityMethod() { (this.getName() = "setPriority" or this.getName() = "getPriority") and - this.getDeclaringType().hasQualifiedName("java.lang","Thread") + this.getDeclaringType().hasQualifiedName("java.lang", "Thread") } } class PriorityMethodAccess extends MethodAccess { - PriorityMethodAccess() { - this.getMethod() instanceof PriorityMethod - } + PriorityMethodAccess() { this.getMethod() instanceof PriorityMethod } } from PriorityMethodAccess ma diff --git a/java/ql/src/Likely Bugs/Concurrency/SleepWithLock.ql b/java/ql/src/Likely Bugs/Concurrency/SleepWithLock.ql index e0aa8dfc579..3aa18c4db17 100644 --- a/java/ql/src/Likely Bugs/Concurrency/SleepWithLock.ql +++ b/java/ql/src/Likely Bugs/Concurrency/SleepWithLock.ql @@ -11,6 +11,7 @@ * concurrency * external/cwe/cwe-833 */ + import java from MethodAccess ma, Method sleep diff --git a/java/ql/src/Likely Bugs/Concurrency/StartInConstructor.ql b/java/ql/src/Likely Bugs/Concurrency/StartInConstructor.ql index 7a1f6ef12c6..fa145ebb1b4 100644 --- a/java/ql/src/Likely Bugs/Concurrency/StartInConstructor.ql +++ b/java/ql/src/Likely Bugs/Concurrency/StartInConstructor.ql @@ -11,6 +11,7 @@ * correctness * concurrency */ + import java /** @@ -21,7 +22,8 @@ private predicate cannotBeExtended(RefType t) { t.isFinal() or // If the class is private, all possible subclasses are known. - t.isPrivate() and not exists(RefType sub | sub != t | sub.getAnAncestor() = t) + t.isPrivate() and + not exists(RefType sub | sub != t | sub.getAnAncestor() = t) } from MethodAccess m, Constructor c, Class clazz diff --git a/java/ql/src/Likely Bugs/Concurrency/SynchSetUnsynchGet.ql b/java/ql/src/Likely Bugs/Concurrency/SynchSetUnsynchGet.ql index 4fbd06097b4..df620ca08d8 100644 --- a/java/ql/src/Likely Bugs/Concurrency/SynchSetUnsynchGet.ql +++ b/java/ql/src/Likely Bugs/Concurrency/SynchSetUnsynchGet.ql @@ -14,6 +14,7 @@ * external/cwe/cwe-413 * external/cwe/cwe-662 */ + import java /** @@ -23,11 +24,10 @@ import java predicate isSynchronizedByBlock(Method m) { exists(SynchronizedStmt sync, Expr on | sync = m.getBody().getAChild*() and on = sync.getExpr().getProperExpr() - | - if m.isStatic() then - on.(TypeLiteral).getTypeName().getType() = m.getDeclaringType() - else - on.(ThisAccess).getType().(RefType).getSourceDeclaration() = m.getDeclaringType() + | + if m.isStatic() + then on.(TypeLiteral).getTypeName().getType() = m.getDeclaringType() + else on.(ThisAccess).getType().(RefType).getSourceDeclaration() = m.getDeclaringType() ) } @@ -48,10 +48,10 @@ from Method set, Method get where set.getDeclaringType() = get.getDeclaringType() and set.getName().matches("set%") and - get.getName() = "get"+set.getName().substring(3,set.getName().length()) and + get.getName() = "get" + set.getName().substring(3, set.getName().length()) and set.isSynchronized() and not (get.isSynchronized() or isSynchronizedByBlock(get)) and not bothAccessVolatileField(set, get) and set.fromSource() -select get, "This get method is unsynchronized, but the corresponding $@ is synchronized.", - set, "set method" +select get, "This get method is unsynchronized, but the corresponding $@ is synchronized.", set, + "set method" diff --git a/java/ql/src/Likely Bugs/Concurrency/SynchWriteObject.ql b/java/ql/src/Likely Bugs/Concurrency/SynchWriteObject.ql index c3189f65d6e..dc35a5db380 100644 --- a/java/ql/src/Likely Bugs/Concurrency/SynchWriteObject.ql +++ b/java/ql/src/Likely Bugs/Concurrency/SynchWriteObject.ql @@ -12,6 +12,7 @@ * language-features * external/cwe/cwe-662 */ + import java from Method m @@ -19,7 +20,7 @@ where m.getDeclaringType().getASupertype*() instanceof TypeSerializable and m.hasName("writeObject") and m.getNumberOfParameters() = 1 and - m.getAParamType().(Class).hasQualifiedName("java.io","ObjectOutputStream") and + m.getAParamType().(Class).hasQualifiedName("java.io", "ObjectOutputStream") and m.isSynchronized() and not exists(Method s | m.getDeclaringType().inherits(s) and diff --git a/java/ql/src/Likely Bugs/Concurrency/UnreleasedLock.ql b/java/ql/src/Likely Bugs/Concurrency/UnreleasedLock.ql index f16844588bd..40fb18543d1 100644 --- a/java/ql/src/Likely Bugs/Concurrency/UnreleasedLock.ql +++ b/java/ql/src/Likely Bugs/Concurrency/UnreleasedLock.ql @@ -11,6 +11,7 @@ * external/cwe/cwe-764 * external/cwe/cwe-833 */ + import java import semmle.code.java.controlflow.Guards import semmle.code.java.dataflow.SSA @@ -69,10 +70,12 @@ predicate unlockBlock(LockType t, BasicBlock b, int unlocks) { * equals the number of locks minus the number of unlocks. */ predicate lockUnlockBlock(LockType t, BasicBlock b, int netlocks) { - lockBlock(t, b, netlocks) and not unlockBlock(t, b, _) or + lockBlock(t, b, netlocks) and not unlockBlock(t, b, _) + or exists(int unlocks | not lockBlock(t, b, _) and unlockBlock(t, b, unlocks) and netlocks = -unlocks - ) or + ) + or exists(int locks, int unlocks | lockBlock(t, b, locks) and unlockBlock(t, b, unlocks) and netlocks = locks - unlocks ) @@ -93,8 +96,7 @@ predicate failedLock(LockType t, BasicBlock lockblock, BasicBlock exblock) { lock = lockbool.getAUse() and lockbool.getDefiningExpr().(VariableAssign).getSource() = t.getLockAccess() ) - ) - and + ) and ( lock.getAnExceptionSuccessor() = exblock or lock.(ConditionNode).getAFalseSuccessor() = exblock @@ -109,7 +111,7 @@ predicate failedLock(LockType t, BasicBlock lockblock, BasicBlock exblock) { predicate heldByCurrentThreadCheck(LockType t, BasicBlock checkblock, BasicBlock falsesucc) { exists(ConditionBlock conditionBlock | conditionBlock.getCondition() = t.getIsHeldByCurrentThreadAccess() - | + | conditionBlock.getBasicBlock() = checkblock and conditionBlock.getTestSuccessor(false) = falsesucc ) @@ -122,20 +124,23 @@ predicate heldByCurrentThreadCheck(LockType t, BasicBlock checkblock, BasicBlock predicate blockIsLocked(LockType t, BasicBlock src, BasicBlock b, int locks) { lockUnlockBlock(t, b, locks) and src = b and locks > 0 or - exists(BasicBlock pred, int predlocks, int curlocks, int failedlock | pred = b.getABBPredecessor() | + exists(BasicBlock pred, int predlocks, int curlocks, int failedlock | + pred = b.getABBPredecessor() + | // The number of net locks from the `src` block to the predecessor block `pred` is `predlocks`. blockIsLocked(t, src, pred, predlocks) and - /* - * The recursive call ensures that at least one lock is held, so do not consider the false - * successor of the `isHeldByCurrentThread()` check. - */ + // The recursive call ensures that at least one lock is held, so do not consider the false + // successor of the `isHeldByCurrentThread()` check. not heldByCurrentThreadCheck(t, pred, b) and // Count a failed lock as an unlock so the net is zero. - ( if failedLock(t, pred, b) then failedlock = 1 else failedlock = 0 ) and - ( not lockUnlockBlock(t, b, _) and curlocks = 0 or + (if failedLock(t, pred, b) then failedlock = 1 else failedlock = 0) and + ( + not lockUnlockBlock(t, b, _) and curlocks = 0 + or lockUnlockBlock(t, b, curlocks) ) and - locks = predlocks + curlocks - failedlock and locks > 0 and + locks = predlocks + curlocks - failedlock and + locks > 0 and // Arbitrary bound in order to fail gracefully in case of locking in a loop. locks < 10 ) @@ -147,6 +152,6 @@ where t.getUnlockAccess().getEnclosingCallable() = c and blockIsLocked(t, src, exit, _) and exit.getLastNode() = c and - lock = src.getANode() and lock = t.getLockAccess() -select - lock, "This lock might not be unlocked or might be locked more times than it is unlocked." + lock = src.getANode() and + lock = t.getLockAccess() +select lock, "This lock might not be unlocked or might be locked more times than it is unlocked." diff --git a/java/ql/src/Likely Bugs/Concurrency/WaitOutsideLoop.ql b/java/ql/src/Likely Bugs/Concurrency/WaitOutsideLoop.ql index 36d1f4b2dd3..c0d8a47ecec 100644 --- a/java/ql/src/Likely Bugs/Concurrency/WaitOutsideLoop.ql +++ b/java/ql/src/Likely Bugs/Concurrency/WaitOutsideLoop.ql @@ -10,6 +10,7 @@ * correctness * concurrency */ + import java class WaitMethod extends Method { diff --git a/java/ql/src/Likely Bugs/Concurrency/WaitWithTwoLocks.ql b/java/ql/src/Likely Bugs/Concurrency/WaitWithTwoLocks.ql index 25ebe28b72f..03eeba75ae1 100644 --- a/java/ql/src/Likely Bugs/Concurrency/WaitWithTwoLocks.ql +++ b/java/ql/src/Likely Bugs/Concurrency/WaitWithTwoLocks.ql @@ -10,6 +10,7 @@ * concurrency * external/cwe/cwe-833 */ + import java /** A `synchronized` method or statement. */ diff --git a/java/ql/src/Likely Bugs/Concurrency/YieldCalls.ql b/java/ql/src/Likely Bugs/Concurrency/YieldCalls.ql index 7ccc3b83047..91ae12b6464 100644 --- a/java/ql/src/Likely Bugs/Concurrency/YieldCalls.ql +++ b/java/ql/src/Likely Bugs/Concurrency/YieldCalls.ql @@ -10,19 +10,18 @@ * correctness * concurrency */ + import java class YieldMethod extends Method { YieldMethod() { this.getName() = "yield" and - this.getDeclaringType().hasQualifiedName("java.lang","Thread") + this.getDeclaringType().hasQualifiedName("java.lang", "Thread") } } class YieldMethodAccess extends MethodAccess { - YieldMethodAccess() { - this.getMethod() instanceof YieldMethod - } + YieldMethodAccess() { this.getMethod() instanceof YieldMethod } } from YieldMethodAccess yield diff --git a/java/ql/src/Likely Bugs/Finalization/NullifiedSuperFinalize.ql b/java/ql/src/Likely Bugs/Finalization/NullifiedSuperFinalize.ql index ad1a5c39ac5..60a11154215 100644 --- a/java/ql/src/Likely Bugs/Finalization/NullifiedSuperFinalize.ql +++ b/java/ql/src/Likely Bugs/Finalization/NullifiedSuperFinalize.ql @@ -10,6 +10,7 @@ * maintainability * external/cwe/cwe-568 */ + import java from FinalizeMethod m, Class c, FinalizeMethod mSuper, Class cSuper diff --git a/java/ql/src/Likely Bugs/Frameworks/JUnit/BadSuiteMethod.ql b/java/ql/src/Likely Bugs/Frameworks/JUnit/BadSuiteMethod.ql index d1c9ca2ce7b..14395bc72b3 100644 --- a/java/ql/src/Likely Bugs/Frameworks/JUnit/BadSuiteMethod.ql +++ b/java/ql/src/Likely Bugs/Frameworks/JUnit/BadSuiteMethod.ql @@ -10,6 +10,7 @@ * maintainability * frameworks/junit */ + import java from TypeJUnitTestCase junitTestCase, TypeJUnitTest junitTest, Method m diff --git a/java/ql/src/Likely Bugs/Frameworks/JUnit/TearDownNoSuper.ql b/java/ql/src/Likely Bugs/Frameworks/JUnit/TearDownNoSuper.ql index 06e5f88220f..3ea143916a1 100644 --- a/java/ql/src/Likely Bugs/Frameworks/JUnit/TearDownNoSuper.ql +++ b/java/ql/src/Likely Bugs/Frameworks/JUnit/TearDownNoSuper.ql @@ -11,6 +11,7 @@ * maintainability * frameworks/junit */ + import java from TearDownMethod m1 diff --git a/java/ql/src/Likely Bugs/Frameworks/JUnit/TestCaseNoTests.ql b/java/ql/src/Likely Bugs/Frameworks/JUnit/TestCaseNoTests.ql index 364d4d969d9..75fea5ac311 100644 --- a/java/ql/src/Likely Bugs/Frameworks/JUnit/TestCaseNoTests.ql +++ b/java/ql/src/Likely Bugs/Frameworks/JUnit/TestCaseNoTests.ql @@ -10,6 +10,7 @@ * maintainability * frameworks/junit */ + import java // `suite()` methods in `TestCase`s also count as test methods. diff --git a/java/ql/src/Likely Bugs/Frameworks/Swing/BadlyOverriddenAdapter.ql b/java/ql/src/Likely Bugs/Frameworks/Swing/BadlyOverriddenAdapter.ql index 5f8ac8f20bb..2d9d49802bf 100644 --- a/java/ql/src/Likely Bugs/Frameworks/Swing/BadlyOverriddenAdapter.ql +++ b/java/ql/src/Likely Bugs/Frameworks/Swing/BadlyOverriddenAdapter.ql @@ -11,6 +11,7 @@ * maintainability * frameworks/swing */ + import java class Adapter extends Class { @@ -27,13 +28,11 @@ from Class c, Adapter adapter, Method m where adapter = c.getASupertype() and c = m.getDeclaringType() and - exists(Method original | adapter = original.getDeclaringType() | - m.getName() = original.getName() - ) and - not exists(Method overridden | adapter = overridden.getDeclaringType() | - m.overrides(overridden) - ) and + exists(Method original | adapter = original.getDeclaringType() | m.getName() = original.getName()) and + not exists(Method overridden | adapter = overridden.getDeclaringType() | m.overrides(overridden)) and // The method is not used for any other purpose. not exists(MethodAccess ma | ma.getMethod() = m) -select m, "Method " + m.getName() + " attempts to override a method in " + adapter.getName() + - ", but does not have the same argument types. " + m.getName() + " will not be called when an event occurs." +select m, + "Method " + m.getName() + " attempts to override a method in " + adapter.getName() + + ", but does not have the same argument types. " + m.getName() + + " will not be called when an event occurs." diff --git a/java/ql/src/Likely Bugs/Frameworks/Swing/ThreadSafety.ql b/java/ql/src/Likely Bugs/Frameworks/Swing/ThreadSafety.ql index 9ffa8cfcaa7..7feac69647e 100644 --- a/java/ql/src/Likely Bugs/Frameworks/Swing/ThreadSafety.ql +++ b/java/ql/src/Likely Bugs/Frameworks/Swing/ThreadSafety.ql @@ -15,14 +15,16 @@ import java from MethodAccess ma, Method m, MainMethod main where - ma.getQualifier().getType().getCompilationUnit().getPackage().getName() - .matches("javax.swing%") and + ma.getQualifier().getType().getCompilationUnit().getPackage().getName().matches("javax.swing%") and ( - m.hasName("show") and m.hasNoParameters() or - m.hasName("pack") and m.hasNoParameters() or + m.hasName("show") and m.hasNoParameters() + or + m.hasName("pack") and m.hasNoParameters() + or m.hasName("setVisible") and m.getNumberOfParameters() = 1 ) and ma.getMethod() = m and ma.getEnclosingCallable() = main -select ma, "Call to swing method in " + main.getDeclaringType().getName() - + " needs to be performed in Swing event thread." +select ma, + "Call to swing method in " + main.getDeclaringType().getName() + + " needs to be performed in Swing event thread." diff --git a/java/ql/src/Likely Bugs/I18N/MissingLocaleArgument.ql b/java/ql/src/Likely Bugs/I18N/MissingLocaleArgument.ql index 08d437435a1..2af7402661c 100644 --- a/java/ql/src/Likely Bugs/I18N/MissingLocaleArgument.ql +++ b/java/ql/src/Likely Bugs/I18N/MissingLocaleArgument.ql @@ -9,6 +9,7 @@ * @tags reliability * maintainability */ + import java from MethodAccess ma, Method changecase diff --git a/java/ql/src/Likely Bugs/Inheritance/NoNonFinalInConstructor.ql b/java/ql/src/Likely Bugs/Inheritance/NoNonFinalInConstructor.ql index e13c8e99904..bc37d39c1b2 100644 --- a/java/ql/src/Likely Bugs/Inheritance/NoNonFinalInConstructor.ql +++ b/java/ql/src/Likely Bugs/Inheritance/NoNonFinalInConstructor.ql @@ -10,37 +10,36 @@ * correctness * logic */ + import java -private -predicate writtenInOneCallable(Field f) { - strictcount(Callable m | m.writes(f)) = 1 -} +private predicate writtenInOneCallable(Field f) { strictcount(Callable m | m.writes(f)) = 1 } -private -FieldWrite fieldWriteOnlyIn(Callable m, Field f) { +private FieldWrite fieldWriteOnlyIn(Callable m, Field f) { result.getField() = f and m.writes(f) and writtenInOneCallable(f) } -private -FieldRead nonFinalFieldRead(Callable m, Field f) { +private FieldRead nonFinalFieldRead(Callable m, Field f) { result.getField() = f and result.getEnclosingCallable() = m and not f.isFinal() } -private -MethodAccess unqualifiedCallToNonAbstractMethod(Constructor c, Method m) { +private MethodAccess unqualifiedCallToNonAbstractMethod(Constructor c, Method m) { result.getEnclosingCallable() = c and - (not exists(result.getQualifier()) or - result.getQualifier().(ThisAccess).getType() = c.getDeclaringType()) and + ( + not exists(result.getQualifier()) or + result.getQualifier().(ThisAccess).getType() = c.getDeclaringType() + ) and m = result.getMethod() and not m.isAbstract() } -from Constructor c, MethodAccess ma, Method m, Method n, Field f, FieldRead fa, Constructor d, FieldWrite fw +from + Constructor c, MethodAccess ma, Method m, Method n, Field f, FieldRead fa, Constructor d, + FieldWrite fw where // Method access in a constructor // which is an access to the object being initialized, ... @@ -58,11 +57,6 @@ where fw = fieldWriteOnlyIn(d, f) and // ... the subtype constructor calls (possibly indirectly) the offending super constructor. d.callsConstructor+(c) -select - ma, "One $@ $@ a $@ that is only $@ in the $@, so it is uninitialized in this $@.", - n, "overriding implementation", - fa, "reads", - f, "subclass field", - fw, "initialized", - d, "subclass constructor", - c, "super constructor" +select ma, "One $@ $@ a $@ that is only $@ in the $@, so it is uninitialized in this $@.", n, + "overriding implementation", fa, "reads", f, "subclass field", fw, "initialized", d, + "subclass constructor", c, "super constructor" diff --git a/java/ql/src/Likely Bugs/Likely Typos/ConstructorTypo.ql b/java/ql/src/Likely Bugs/Likely Typos/ConstructorTypo.ql index 7656d061f5f..2682386d0bb 100644 --- a/java/ql/src/Likely Bugs/Likely Typos/ConstructorTypo.ql +++ b/java/ql/src/Likely Bugs/Likely Typos/ConstructorTypo.ql @@ -10,11 +10,11 @@ * readability * naming */ + import java from Method m where m.hasName(m.getDeclaringType().getName()) and m.fromSource() -select m, "This method has the same name as its declaring class." - + " Should it be a constructor?" +select m, "This method has the same name as its declaring class." + " Should it be a constructor?" diff --git a/java/ql/src/Likely Bugs/Likely Typos/ContainerSizeCmpZero.ql b/java/ql/src/Likely Bugs/Likely Typos/ContainerSizeCmpZero.ql index 304b32b05ff..4e30b900003 100644 --- a/java/ql/src/Likely Bugs/Likely Typos/ContainerSizeCmpZero.ql +++ b/java/ql/src/Likely Bugs/Likely Typos/ContainerSizeCmpZero.ql @@ -15,42 +15,32 @@ import semmle.code.java.Collections import semmle.code.java.Maps /** A union of the possible kinds of container size calls. */ -abstract class SizeOfContainer extends Expr { - abstract string getContainerKind(); -} +abstract class SizeOfContainer extends Expr { abstract string getContainerKind(); } /** A read access to the `length` field of an array. */ class ArrayLengthRead extends FieldRead, SizeOfContainer { - ArrayLengthRead() { - this.getField() instanceof ArrayLengthField - } + ArrayLengthRead() { this.getField() instanceof ArrayLengthField } override string getContainerKind() { result = "an array" } } /** An access to `String.length()`. */ class StringLengthRead extends MethodAccess, SizeOfContainer { - StringLengthRead() { - this.getMethod() instanceof StringLengthMethod - } + StringLengthRead() { this.getMethod() instanceof StringLengthMethod } override string getContainerKind() { result = "a string" } } /** An access to `Collection.size()`. */ class CollectionSizeCall extends MethodAccess, SizeOfContainer { - CollectionSizeCall() { - this.getMethod() instanceof CollectionSizeMethod - } + CollectionSizeCall() { this.getMethod() instanceof CollectionSizeMethod } override string getContainerKind() { result = "a collection" } } /** An access to `Map.size()`. */ class MapSizeCall extends MethodAccess, SizeOfContainer { - MapSizeCall() { - this.getMethod() instanceof MapSizeMethod - } + MapSizeCall() { this.getMethod() instanceof MapSizeMethod } override string getContainerKind() { result = "a map" } } @@ -62,23 +52,42 @@ class IntegralZeroLiteral extends Literal { } } -private predicate comparisonOfContainerSizeToZero(BinaryExpr e, string containerKind, string trueOrFalse) { +private predicate comparisonOfContainerSizeToZero( + BinaryExpr e, string containerKind, string trueOrFalse +) { exists(Expr l, Expr r | l = e.getLeftOperand() and r = e.getRightOperand() | - (e instanceof LTExpr and l.(SizeOfContainer).getContainerKind() = containerKind and - r instanceof IntegralZeroLiteral and trueOrFalse = "false") + ( + e instanceof LTExpr and + l.(SizeOfContainer).getContainerKind() = containerKind and + r instanceof IntegralZeroLiteral and + trueOrFalse = "false" + ) or - (e instanceof GTExpr and l instanceof IntegralZeroLiteral and - r.(SizeOfContainer).getContainerKind() = containerKind and trueOrFalse = "false") + ( + e instanceof GTExpr and + l instanceof IntegralZeroLiteral and + r.(SizeOfContainer).getContainerKind() = containerKind and + trueOrFalse = "false" + ) or - (e instanceof GEExpr and l.(SizeOfContainer).getContainerKind() = containerKind and - r instanceof IntegralZeroLiteral and trueOrFalse = "true") + ( + e instanceof GEExpr and + l.(SizeOfContainer).getContainerKind() = containerKind and + r instanceof IntegralZeroLiteral and + trueOrFalse = "true" + ) or - (e instanceof LEExpr and l instanceof IntegralZeroLiteral and - r.(SizeOfContainer).getContainerKind() = containerKind and trueOrFalse = "true") + ( + e instanceof LEExpr and + l instanceof IntegralZeroLiteral and + r.(SizeOfContainer).getContainerKind() = containerKind and + trueOrFalse = "true" + ) ) } from BinaryExpr e, string containerKind, string trueOrFalse where comparisonOfContainerSizeToZero(e, containerKind, trueOrFalse) -select e, "This expression is always " + trueOrFalse + ", since " + - containerKind + " can never have negative size." +select e, + "This expression is always " + trueOrFalse + ", since " + containerKind + + " can never have negative size." diff --git a/java/ql/src/Likely Bugs/Likely Typos/ContradictoryTypeChecks.ql b/java/ql/src/Likely Bugs/Likely Typos/ContradictoryTypeChecks.ql index 95047d4507d..6a9fc9b7051 100644 --- a/java/ql/src/Likely Bugs/Likely Typos/ContradictoryTypeChecks.ql +++ b/java/ql/src/Likely Bugs/Likely Typos/ContradictoryTypeChecks.ql @@ -24,7 +24,8 @@ predicate instanceOfCheck(InstanceOfExpr ioe, VarAccess va, RefType t) { /** Expression `e` assumes that `va` could be of type `t`. */ predicate requiresInstanceOf(Expr e, VarAccess va, RefType t) { // `e` is a cast of the form `(t)va` - e.(CastExpr).getExpr() = va and t = e.getType().(RefType).getSourceDeclaration() or + e.(CastExpr).getExpr() = va and t = e.getType().(RefType).getSourceDeclaration() + or // `e` is `va instanceof t` instanceOfCheck(e, va, t) } @@ -44,7 +45,6 @@ predicate contradictoryTypeCheck(Expr e, Variable v, RefType t, RefType sup, Exp } from Expr e, Variable v, RefType t, RefType sup, Expr cond -where - contradictoryTypeCheck(e, v, t, sup, cond) -select e, "Variable $@ cannot be of type $@ here, since $@ ensures that it is not of type $@.", - v, v.getName(), t, t.getName(), cond, "this expression", sup, sup.getName() +where contradictoryTypeCheck(e, v, t, sup, cond) +select e, "Variable $@ cannot be of type $@ here, since $@ ensures that it is not of type $@.", v, + v.getName(), t, t.getName(), cond, "this expression", sup, sup.getName() diff --git a/java/ql/src/Likely Bugs/Likely Typos/DangerousNonCircuitLogic.ql b/java/ql/src/Likely Bugs/Likely Typos/DangerousNonCircuitLogic.ql index 85606732456..738a26518fc 100644 --- a/java/ql/src/Likely Bugs/Likely Typos/DangerousNonCircuitLogic.ql +++ b/java/ql/src/Likely Bugs/Likely Typos/DangerousNonCircuitLogic.ql @@ -11,6 +11,7 @@ * readability * external/cwe/cwe-691 */ + import java /** An expression containing a method access, array access, or qualified field access. */ diff --git a/java/ql/src/Likely Bugs/Likely Typos/EqualsTypo.ql b/java/ql/src/Likely Bugs/Likely Typos/EqualsTypo.ql index 4874ca9a149..585306be958 100644 --- a/java/ql/src/Likely Bugs/Likely Typos/EqualsTypo.ql +++ b/java/ql/src/Likely Bugs/Likely Typos/EqualsTypo.ql @@ -9,6 +9,7 @@ * readability * naming */ + import java from Method equal diff --git a/java/ql/src/Likely Bugs/Likely Typos/HashCodeTypo.ql b/java/ql/src/Likely Bugs/Likely Typos/HashCodeTypo.ql index d43c8cd4e25..7a69f9f7953 100644 --- a/java/ql/src/Likely Bugs/Likely Typos/HashCodeTypo.ql +++ b/java/ql/src/Likely Bugs/Likely Typos/HashCodeTypo.ql @@ -9,6 +9,7 @@ * readability * naming */ + import java from Method m diff --git a/java/ql/src/Likely Bugs/Likely Typos/MissingFormatArg.ql b/java/ql/src/Likely Bugs/Likely Typos/MissingFormatArg.ql index 87057f3ed50..2297873be82 100644 --- a/java/ql/src/Likely Bugs/Likely Typos/MissingFormatArg.ql +++ b/java/ql/src/Likely Bugs/Likely Typos/MissingFormatArg.ql @@ -9,6 +9,7 @@ * @tags correctness * external/cwe/cwe-685 */ + import java import semmle.code.java.StringFormat @@ -18,4 +19,5 @@ where refs = fmt.getMaxFmtSpecIndex() and args = fmtcall.getVarargsCount() and refs > args -select fmtcall, "This format call refers to " + refs + " argument(s) but only supplies " + args + " argument(s)." +select fmtcall, + "This format call refers to " + refs + " argument(s) but only supplies " + args + " argument(s)." diff --git a/java/ql/src/Likely Bugs/Likely Typos/MissingSpaceTypo.ql b/java/ql/src/Likely Bugs/Likely Typos/MissingSpaceTypo.ql index 5bbe10f9bf0..fde6da4aea4 100644 --- a/java/ql/src/Likely Bugs/Likely Typos/MissingSpaceTypo.ql +++ b/java/ql/src/Likely Bugs/Likely Typos/MissingSpaceTypo.ql @@ -9,12 +9,11 @@ * @id java/missing-space-in-concatenation * @tags readability */ + import java class SourceStringLiteral extends StringLiteral { - SourceStringLiteral() { - this.getCompilationUnit().fromSource() - } + SourceStringLiteral() { this.getCompilationUnit().fromSource() } } from SourceStringLiteral s, string word @@ -24,6 +23,9 @@ where // completely to distinguish grammatical punctuation after which a space is // needed, and intra-identifier punctuation in, for example, a fully // qualified java class name. - s.getLiteral().regexpCapture(".* (([-A-Za-z/'\\.:,]*[a-zA-Z]|[0-9]+)[\\.:,;!?']*)\"[^\"]*\\+[^\"]*\"[a-zA-Z].*", 1) = word and + s + .getLiteral() + .regexpCapture(".* (([-A-Za-z/'\\.:,]*[a-zA-Z]|[0-9]+)[\\.:,;!?']*)\"[^\"]*\\+[^\"]*\"[a-zA-Z].*", + 1) = word and not word.regexpMatch(".*[,\\.:].*[a-zA-Z].*[^a-zA-Z]") select s, "This string appears to be missing a space after '" + word + "'." diff --git a/java/ql/src/Likely Bugs/Likely Typos/NestedLoopsSameVariable.ql b/java/ql/src/Likely Bugs/Likely Typos/NestedLoopsSameVariable.ql index bdf710d506f..b7ddecbe1a3 100644 --- a/java/ql/src/Likely Bugs/Likely Typos/NestedLoopsSameVariable.ql +++ b/java/ql/src/Likely Bugs/Likely Typos/NestedLoopsSameVariable.ql @@ -10,6 +10,7 @@ * correctness * logic */ + import java from ForStmt inner, Variable iteration, ForStmt outer @@ -18,7 +19,5 @@ where iteration = outer.getAnIterationVariable() and inner.getParent+() = outer and inner.getBasicBlock().getABBSuccessor+() = outer.getCondition().getBasicBlock() -select - inner.getCondition(), "Nested for statement uses loop variable $@ of enclosing $@.", - iteration, iteration.getName(), - outer, "for statement" +select inner.getCondition(), "Nested for statement uses loop variable $@ of enclosing $@.", + iteration, iteration.getName(), outer, "for statement" diff --git a/java/ql/src/Likely Bugs/Likely Typos/SelfAssignment.ql b/java/ql/src/Likely Bugs/Likely Typos/SelfAssignment.ql index 29618cfcb2e..3ae663ff764 100644 --- a/java/ql/src/Likely Bugs/Likely Typos/SelfAssignment.ql +++ b/java/ql/src/Likely Bugs/Likely Typos/SelfAssignment.ql @@ -23,7 +23,8 @@ predicate toCompare(VarAccess left, VarAccess right) { } predicate local(RefType enclosingType, VarAccess v) { - enclosingType = v.getQualifier().(ThisAccess).getType() or + enclosingType = v.getQualifier().(ThisAccess).getType() + or not exists(v.getQualifier()) and enclosingType = v.getEnclosingCallable().getDeclaringType() } @@ -35,10 +36,9 @@ predicate sameVariable(VarAccess left, VarAccess right) { q1 = left.getQualifier() and sameVariable(q1, q2) and q2 = right.getQualifier() - ) or - exists(RefType enclosingType | - local(enclosingType, left) and local(enclosingType, right) ) + or + exists(RefType enclosingType | local(enclosingType, left) and local(enclosingType, right)) ) } @@ -46,4 +46,4 @@ from AssignExpr assign where sameVariable(assign.getDest(), assign.getSource()) select assign, "This assigns the variable " + assign.getDest().(VarAccess).getVariable().getName() + - " to itself and has no effect." + " to itself and has no effect." diff --git a/java/ql/src/Likely Bugs/Likely Typos/StringBufferCharInit.ql b/java/ql/src/Likely Bugs/Likely Typos/StringBufferCharInit.ql index 15fb7b076f9..c410c7745ee 100644 --- a/java/ql/src/Likely Bugs/Likely Typos/StringBufferCharInit.ql +++ b/java/ql/src/Likely Bugs/Likely Typos/StringBufferCharInit.ql @@ -9,6 +9,7 @@ * @tags reliability * maintainability */ + import java class NewStringBufferOrBuilder extends ClassInstanceExpr { @@ -19,12 +20,10 @@ class NewStringBufferOrBuilder extends ClassInstanceExpr { ) } - string getName() { - result = this.getConstructedType().getName() - } + string getName() { result = this.getConstructedType().getName() } } from NewStringBufferOrBuilder nsb where nsb.getArgument(0).getType().hasName("char") -select nsb, "A character value passed to 'new " + nsb.getName() + - "' is interpreted as the buffer capacity." +select nsb, + "A character value passed to 'new " + nsb.getName() + "' is interpreted as the buffer capacity." diff --git a/java/ql/src/Likely Bugs/Likely Typos/ToStringTypo.ql b/java/ql/src/Likely Bugs/Likely Typos/ToStringTypo.ql index b310bda898a..928d9f5a7cc 100644 --- a/java/ql/src/Likely Bugs/Likely Typos/ToStringTypo.ql +++ b/java/ql/src/Likely Bugs/Likely Typos/ToStringTypo.ql @@ -9,6 +9,7 @@ * readability * naming */ + import java from Method m diff --git a/java/ql/src/Likely Bugs/Likely Typos/UnusedFormatArg.ql b/java/ql/src/Likely Bugs/Likely Typos/UnusedFormatArg.ql index 01cd76212d2..67fb610a25c 100644 --- a/java/ql/src/Likely Bugs/Likely Typos/UnusedFormatArg.ql +++ b/java/ql/src/Likely Bugs/Likely Typos/UnusedFormatArg.ql @@ -11,6 +11,7 @@ * useless-code * external/cwe/cwe-685 */ + import java import semmle.code.java.StringFormat @@ -18,8 +19,10 @@ int getNumberOfReferencedIndices(FormattingCall fmtcall) { exists(int maxref, int skippedrefs | maxref = max(FormatString fmt | fmtcall.getAFormatString() = fmt | fmt.getMaxFmtSpecIndex()) and skippedrefs = count(int i | - forex(FormatString fmt | fmtcall.getAFormatString() = fmt | i = fmt.getASkippedFmtSpecIndex()) - ) and + forex(FormatString fmt | fmtcall.getAFormatString() = fmt | + i = fmt.getASkippedFmtSpecIndex() + ) + ) and result = maxref - skippedrefs ) } @@ -30,4 +33,5 @@ where args = fmtcall.getVarargsCount() and refs < args and not (fmtcall.hasTrailingThrowableArgument() and refs = args - 1) -select fmtcall, "This format call refers to " + refs + " argument(s) but supplies " + args + " argument(s)." +select fmtcall, + "This format call refers to " + refs + " argument(s) but supplies " + args + " argument(s)." diff --git a/java/ql/src/Likely Bugs/Nullness/NullMaybe.ql b/java/ql/src/Likely Bugs/Nullness/NullMaybe.ql index cadcf6d04ab..d29ebd7fb89 100644 --- a/java/ql/src/Likely Bugs/Nullness/NullMaybe.ql +++ b/java/ql/src/Likely Bugs/Nullness/NullMaybe.ql @@ -22,5 +22,5 @@ where nullDeref(var, access, msg, reason) and // Exclude definite nulls here, as these are covered by `NullAlways.ql`. not alwaysNullDeref(var, access) -select access, "Variable $@ may be null here " + msg + ".", - var.getVariable(), var.getVariable().getName(), reason, "this" +select access, "Variable $@ may be null here " + msg + ".", var.getVariable(), + var.getVariable().getName(), reason, "this" diff --git a/java/ql/src/Likely Bugs/Reflection/AnnotationPresentCheck.ql b/java/ql/src/Likely Bugs/Reflection/AnnotationPresentCheck.ql index 6c77168c213..6af39558a8c 100644 --- a/java/ql/src/Likely Bugs/Reflection/AnnotationPresentCheck.ql +++ b/java/ql/src/Likely Bugs/Reflection/AnnotationPresentCheck.ql @@ -9,6 +9,7 @@ * @tags correctness * logic */ + import java from MethodAccess c, Method m, ParameterizedClass p, AnnotationType t diff --git a/java/ql/src/Likely Bugs/Resource Leaks/CloseReader.ql b/java/ql/src/Likely Bugs/Resource Leaks/CloseReader.ql index 1fd9bddc7bf..9d62237bd71 100644 --- a/java/ql/src/Likely Bugs/Resource Leaks/CloseReader.ql +++ b/java/ql/src/Likely Bugs/Resource Leaks/CloseReader.ql @@ -12,6 +12,7 @@ * external/cwe/cwe-404 * external/cwe/cwe-772 */ + import CloseType predicate readerType(RefType t) { diff --git a/java/ql/src/Likely Bugs/Resource Leaks/CloseSql.ql b/java/ql/src/Likely Bugs/Resource Leaks/CloseSql.ql index a2803d7525e..44e77f3fe8f 100644 --- a/java/ql/src/Likely Bugs/Resource Leaks/CloseSql.ql +++ b/java/ql/src/Likely Bugs/Resource Leaks/CloseSql.ql @@ -10,6 +10,7 @@ * external/cwe/cwe-404 * external/cwe/cwe-772 */ + import CloseType from CloseableInitExpr cie, RefType t diff --git a/java/ql/src/Likely Bugs/Resource Leaks/CloseWriter.ql b/java/ql/src/Likely Bugs/Resource Leaks/CloseWriter.ql index f854c6c7ab6..113f3bd3267 100644 --- a/java/ql/src/Likely Bugs/Resource Leaks/CloseWriter.ql +++ b/java/ql/src/Likely Bugs/Resource Leaks/CloseWriter.ql @@ -12,6 +12,7 @@ * external/cwe/cwe-404 * external/cwe/cwe-772 */ + import CloseType predicate writerType(RefType t) { diff --git a/java/ql/src/Likely Bugs/Serialization/IncorrectSerialVersionUID.ql b/java/ql/src/Likely Bugs/Serialization/IncorrectSerialVersionUID.ql index 65385db5fa8..59388163757 100644 --- a/java/ql/src/Likely Bugs/Serialization/IncorrectSerialVersionUID.ql +++ b/java/ql/src/Likely Bugs/Serialization/IncorrectSerialVersionUID.ql @@ -10,6 +10,7 @@ * maintainability * language-features */ + import java from Field f diff --git a/java/ql/src/Likely Bugs/Serialization/IncorrectSerializableMethods.ql b/java/ql/src/Likely Bugs/Serialization/IncorrectSerializableMethods.ql index da1d442987d..3990f94936b 100644 --- a/java/ql/src/Likely Bugs/Serialization/IncorrectSerializableMethods.ql +++ b/java/ql/src/Likely Bugs/Serialization/IncorrectSerializableMethods.ql @@ -10,6 +10,7 @@ * maintainability * language-features */ + import java from Method m, TypeSerializable serializable diff --git a/java/ql/src/Likely Bugs/Serialization/MissingVoidConstructorOnExternalizable.ql b/java/ql/src/Likely Bugs/Serialization/MissingVoidConstructorOnExternalizable.ql index 43e9bab3b5d..44c92634fe0 100644 --- a/java/ql/src/Likely Bugs/Serialization/MissingVoidConstructorOnExternalizable.ql +++ b/java/ql/src/Likely Bugs/Serialization/MissingVoidConstructorOnExternalizable.ql @@ -10,6 +10,7 @@ * maintainability * language-features */ + import java from Class extern, Interface externalizable diff --git a/java/ql/src/Likely Bugs/Serialization/MissingVoidConstructorsOnSerializable.ql b/java/ql/src/Likely Bugs/Serialization/MissingVoidConstructorsOnSerializable.ql index 66ff53f6950..988f38e6933 100644 --- a/java/ql/src/Likely Bugs/Serialization/MissingVoidConstructorsOnSerializable.ql +++ b/java/ql/src/Likely Bugs/Serialization/MissingVoidConstructorsOnSerializable.ql @@ -11,6 +11,7 @@ * maintainability * language-features */ + import java from Class serial, Class nonserial, TypeSerializable serializable @@ -21,10 +22,9 @@ where not exists(Constructor c | c = nonserial.getSourceDeclaration().getAConstructor() and c.hasNoParameters() and - not(c.isPrivate()) + not (c.isPrivate()) ) and serial.fromSource() select serial, "This class is serializable, but its non-serializable " + - "super-class $@ does not declare a no-argument constructor.", - nonserial, nonserial.getName() + "super-class $@ does not declare a no-argument constructor.", nonserial, nonserial.getName() diff --git a/java/ql/src/Likely Bugs/Serialization/NonSerializableComparator.ql b/java/ql/src/Likely Bugs/Serialization/NonSerializableComparator.ql index 3adf36b3f3b..40e8a1a3ed5 100644 --- a/java/ql/src/Likely Bugs/Serialization/NonSerializableComparator.ql +++ b/java/ql/src/Likely Bugs/Serialization/NonSerializableComparator.ql @@ -10,6 +10,7 @@ * maintainability * language-features */ + import java predicate nonSerializableComparator(Class c) { @@ -34,7 +35,8 @@ predicate sortedCollectionType(RefType t) { string nameFor(Class c) { nonSerializableComparator(c) and ( - (c instanceof AnonymousClass and result = "This comparator") or + (c instanceof AnonymousClass and result = "This comparator") + or (not c instanceof AnonymousClass and result = c.getName()) ) } @@ -47,4 +49,4 @@ where sortedCollectionType(cie.getType()) select arg, nameFor(c) + " is not serializable, so should not be used as the comparator in a " + - cie.getType().getName() + "." + cie.getType().getName() + "." diff --git a/java/ql/src/Likely Bugs/Serialization/NonSerializableField.ql b/java/ql/src/Likely Bugs/Serialization/NonSerializableField.ql index 9e69bc59a86..eefc373dbe9 100644 --- a/java/ql/src/Likely Bugs/Serialization/NonSerializableField.ql +++ b/java/ql/src/Likely Bugs/Serialization/NonSerializableField.ql @@ -10,6 +10,7 @@ * maintainability * language-features */ + import java import semmle.code.java.JDKAnnotations import semmle.code.java.Collections @@ -25,22 +26,24 @@ predicate serializableOrExternalizable(Interface interface) { interface instanceof TypeSerializable } -predicate collectionOrMapType(RefType t) { - t instanceof CollectionType or t instanceof MapType -} +predicate collectionOrMapType(RefType t) { t instanceof CollectionType or t instanceof MapType } predicate serializableType(RefType t) { - exists(RefType sup | sup = t.getASupertype*() | serializableOrExternalizable(sup)) or + exists(RefType sup | sup = t.getASupertype*() | serializableOrExternalizable(sup)) + or ( // Collection interfaces are not serializable, but their implementations are // likely to be. collectionOrMapType(t) and - forall(RefType param | param = t.(ParameterizedType).getATypeArgument() | serializableType(param)) - ) or + forall(RefType param | param = t.(ParameterizedType).getATypeArgument() | + serializableType(param) + ) + ) + or exists(BoundedType bt | bt = t | serializableType(bt.getUpperBoundType())) } -RefType reasonForNonSerializableCollection(ParameterizedType par){ +RefType reasonForNonSerializableCollection(ParameterizedType par) { collectionOrMapType(par) and result = par.getATypeArgument() and not serializableType(result) @@ -48,42 +51,44 @@ RefType reasonForNonSerializableCollection(ParameterizedType par){ string nonSerialReason(RefType t) { not serializableType(t) and - if exists(reasonForNonSerializableCollection(t)) then - result = reasonForNonSerializableCollection(t).getName() + " is not serializable" - else - result = t.getName() + " is not serializable" + if exists(reasonForNonSerializableCollection(t)) + then result = reasonForNonSerializableCollection(t).getName() + " is not serializable" + else result = t.getName() + " is not serializable" } -predicate exceptions(Class c, Field f){ - f.getDeclaringType() = c and ( - // `Serializable` objects with custom `readObject` or `writeObject` methods - // may write out the "non-serializable" fields in a different way. - c.declaresMethod("readObject") or - c.declaresMethod("writeObject") or - - // Exclude classes with suppressed warnings. - c.suppressesWarningsAbout("serial") or - - // Exclude anonymous classes whose `ClassInstanceExpr` is assigned to - // a variable on which serialization warnings are suppressed. - exists(Variable v | - v.getAnAssignedValue() = c.(AnonymousClass).getClassInstanceExpr() and - v.suppressesWarningsAbout("serial") - ) or - - f.isTransient() or - f.isStatic() or - - // Classes that implement `Externalizable` completely take over control during serialization. - externalizable(c.getASupertype+()) or - - // Stateless session beans are not normally serialized during their usual life-cycle - // but are forced by their expected supertype to be serializable. - // Arguably, warnings for their non-serializable fields can therefore be suppressed in practice. - c instanceof StatelessSessionEJB or - - // Enum types are serialized by name, so it doesn't matter if they have non-serializable fields. - c instanceof EnumType +predicate exceptions(Class c, Field f) { + f.getDeclaringType() = c and + ( + // `Serializable` objects with custom `readObject` or `writeObject` methods + // may write out the "non-serializable" fields in a different way. + c.declaresMethod("readObject") + or + c.declaresMethod("writeObject") + or + // Exclude classes with suppressed warnings. + c.suppressesWarningsAbout("serial") + or + // Exclude anonymous classes whose `ClassInstanceExpr` is assigned to + // a variable on which serialization warnings are suppressed. + exists(Variable v | + v.getAnAssignedValue() = c.(AnonymousClass).getClassInstanceExpr() and + v.suppressesWarningsAbout("serial") + ) + or + f.isTransient() + or + f.isStatic() + or + // Classes that implement `Externalizable` completely take over control during serialization. + externalizable(c.getASupertype+()) + or + // Stateless session beans are not normally serialized during their usual life-cycle + // but are forced by their expected supertype to be serializable. + // Arguably, warnings for their non-serializable fields can therefore be suppressed in practice. + c instanceof StatelessSessionEJB + or + // Enum types are serialized by name, so it doesn't matter if they have non-serializable fields. + c instanceof EnumType ) } @@ -94,5 +99,6 @@ where f.getDeclaringType() = c and not exceptions(c, f) and reason = nonSerialReason(f.getType()) -select f, "This field is in a serializable class, " - + " but is not serializable itself because " + reason + "." +select f, + "This field is in a serializable class, " + " but is not serializable itself because " + reason + + "." diff --git a/java/ql/src/Likely Bugs/Serialization/NonSerializableInnerClass.ql b/java/ql/src/Likely Bugs/Serialization/NonSerializableInnerClass.ql index e9fdbc0c806..db015fff086 100644 --- a/java/ql/src/Likely Bugs/Serialization/NonSerializableInnerClass.ql +++ b/java/ql/src/Likely Bugs/Serialization/NonSerializableInnerClass.ql @@ -10,59 +10,55 @@ * maintainability * language-features */ + import java import semmle.code.java.JDKAnnotations -predicate isSerializable(RefType t) { - exists(TypeSerializable ts | ts = t.getASupertype*()) -} +predicate isSerializable(RefType t) { exists(TypeSerializable ts | ts = t.getASupertype*()) } predicate withinStaticContext(NestedClass c) { c.isStatic() or c.(AnonymousClass).getClassInstanceExpr().getEnclosingCallable().isStatic() // JLS 15.9.2 } -RefType enclosingInstanceType(Class inner){ +RefType enclosingInstanceType(Class inner) { not withinStaticContext(inner) and result = inner.(NestedClass).getEnclosingType() } -predicate castTo(ClassInstanceExpr cie, RefType to){ - exists(LocalVariableDeclExpr lvd | lvd.getInit() = cie | - to = lvd.getType() - ) or - exists(Assignment a | a.getSource() = cie | - to = a.getType() - ) or - exists(Call call, int n | call.getArgument(n) = cie | - to = call.getCallee().getParameterType(n) - ) or - exists(ReturnStmt ret | ret.getResult() = cie | - to = ret.getEnclosingCallable().getReturnType() - ) or +predicate castTo(ClassInstanceExpr cie, RefType to) { + exists(LocalVariableDeclExpr lvd | lvd.getInit() = cie | to = lvd.getType()) + or + exists(Assignment a | a.getSource() = cie | to = a.getType()) + or + exists(Call call, int n | call.getArgument(n) = cie | to = call.getCallee().getParameterType(n)) + or + exists(ReturnStmt ret | ret.getResult() = cie | to = ret.getEnclosingCallable().getReturnType()) + or exists(ArrayCreationExpr ace | ace.getInit().getAnInit() = cie | to = ace.getType().(Array).getComponentType() ) } -predicate exceptions(NestedClass inner){ - inner instanceof AnonymousClass or - +predicate exceptions(NestedClass inner) { + inner instanceof AnonymousClass + or // Serializable objects with custom `readObject` or `writeObject` methods may write out // the "non-serializable" fields in a different way. - inner.declaresMethod("readObject") or - inner.declaresMethod("writeObject") or - + inner.declaresMethod("readObject") + or + inner.declaresMethod("writeObject") + or // Exclude cases where serialization warnings are deliberately suppressed. - inner.suppressesWarningsAbout("serial") or - + inner.suppressesWarningsAbout("serial") + or // The class `inner` is a local class or non-public member class and // all its instance expressions are cast to non-serializable types. ( (inner instanceof LocalClass or not inner.isPublic()) and forall(ClassInstanceExpr cie, RefType target | cie.getConstructedType() = inner and castTo(cie, target) - | + | not isSerializable(target) ) and // Exception 1: the expression is used as an argument to `writeObject()`. @@ -90,9 +86,9 @@ where not isSerializable(outer) and not exceptions(inner) and ( - if (inner instanceof LocalClass) then - advice = "Consider implementing readObject() and writeObject()." - else - advice = "Consider making the class static or implementing readObject() and writeObject()." + if (inner instanceof LocalClass) + then advice = "Consider implementing readObject() and writeObject()." + else advice = "Consider making the class static or implementing readObject() and writeObject()." ) -select inner, "Serializable inner class of non-serializable class $@. " + advice, outer, outer.getName() +select inner, "Serializable inner class of non-serializable class $@. " + advice, outer, + outer.getName() diff --git a/java/ql/src/Likely Bugs/Serialization/ReadResolveObject.ql b/java/ql/src/Likely Bugs/Serialization/ReadResolveObject.ql index 63d275bfb78..64e5a483362 100644 --- a/java/ql/src/Likely Bugs/Serialization/ReadResolveObject.ql +++ b/java/ql/src/Likely Bugs/Serialization/ReadResolveObject.ql @@ -11,6 +11,7 @@ * maintainability * language-features */ + import java from TypeSerializable serializable, Class c, Method m @@ -20,6 +21,6 @@ where m.hasName("readResolve") and m.hasNoParameters() and not m.getReturnType() instanceof TypeObject -select m, "The method " + m.getName() - + " must be declared with a return type of Object rather than " - + m.getReturnType().getName() + "." +select m, + "The method " + m.getName() + " must be declared with a return type of Object rather than " + + m.getReturnType().getName() + "." diff --git a/java/ql/src/Likely Bugs/Serialization/TransientNotSerializable.ql b/java/ql/src/Likely Bugs/Serialization/TransientNotSerializable.ql index 6f6f2b71189..0afcaa424b6 100644 --- a/java/ql/src/Likely Bugs/Serialization/TransientNotSerializable.ql +++ b/java/ql/src/Likely Bugs/Serialization/TransientNotSerializable.ql @@ -9,6 +9,7 @@ * maintainability * language-features */ + import java from TypeSerializable serializable, Class c, Field f @@ -16,5 +17,4 @@ where not c.hasSupertype+(serializable) and f.getDeclaringType() = c and f.isTransient() -select - f, "The field " + f.getName() + " is transient but " + c.getName() + " is not Serializable." +select f, "The field " + f.getName() + " is transient but " + c.getName() + " is not Serializable." diff --git a/java/ql/src/Likely Bugs/Statements/EmptyBlock.ql b/java/ql/src/Likely Bugs/Statements/EmptyBlock.ql index 796e4ef307c..0aed1f33d68 100644 --- a/java/ql/src/Likely Bugs/Statements/EmptyBlock.ql +++ b/java/ql/src/Likely Bugs/Statements/EmptyBlock.ql @@ -9,47 +9,52 @@ * @tags reliability * readability */ + import semmle.code.java.Statement /** A block without statements or comments. */ -private -Block emptyBlock() { +private Block emptyBlock() { result.getNumStmt() = 0 and result.getLocation().getNumberOfCommentLines() = 0 } /** Auxiliary predicate: file and line of a comment. */ -private -predicate commentedLine(File file, int line) { +private predicate commentedLine(File file, int line) { exists(JavadocText text, Location loc | loc = text.getLocation() and loc.getFile() = file and loc.getStartLine() = line and - loc.getEndLine() = line) + loc.getEndLine() = line + ) } /** An uncommented empty statement */ -private -EmptyStmt emptyStmt() { +private EmptyStmt emptyStmt() { not commentedLine(result.getFile(), result.getLocation().getStartLine()) } /** An empty statement or an empty block. */ -Stmt emptyBody() { - result = emptyBlock() or result = emptyStmt() -} +Stmt emptyBody() { result = emptyBlock() or result = emptyStmt() } /** * Empty blocks or empty statements should not occur as immediate children of if-statements or loops. * Empty blocks should not occur within other blocks. */ -predicate blockParent(Stmt empty, string msg) -{ +predicate blockParent(Stmt empty, string msg) { empty = emptyBody() and ( - (empty.getParent() instanceof IfStmt and msg = "The body of an if statement should not be empty.") or - (empty.getParent() instanceof LoopStmt and msg = "The body of a loop should not be empty.") or - (empty.getParent() instanceof Block and empty instanceof Block and msg = "This block should not be empty.") + ( + empty.getParent() instanceof IfStmt and + msg = "The body of an if statement should not be empty." + ) + or + (empty.getParent() instanceof LoopStmt and msg = "The body of a loop should not be empty.") + or + ( + empty.getParent() instanceof Block and + empty instanceof Block and + msg = "This block should not be empty." + ) ) } diff --git a/java/ql/src/Likely Bugs/Statements/EmptySynchronizedBlock.ql b/java/ql/src/Likely Bugs/Statements/EmptySynchronizedBlock.ql index a6245e0296a..98fed474b1f 100644 --- a/java/ql/src/Likely Bugs/Statements/EmptySynchronizedBlock.ql +++ b/java/ql/src/Likely Bugs/Statements/EmptySynchronizedBlock.ql @@ -12,6 +12,7 @@ * language-features * external/cwe/cwe-585 */ + import java from SynchronizedStmt sync diff --git a/java/ql/src/Likely Bugs/Statements/ImpossibleCast.ql b/java/ql/src/Likely Bugs/Statements/ImpossibleCast.ql index 099e1d88b55..81c47a7e97f 100644 --- a/java/ql/src/Likely Bugs/Statements/ImpossibleCast.ql +++ b/java/ql/src/Likely Bugs/Statements/ImpossibleCast.ql @@ -11,6 +11,7 @@ * logic * external/cwe/cwe-704 */ + import java /** @@ -23,22 +24,14 @@ class ArrayCast extends CastExpr { } /** The type of the operand expression of this cast. */ - Array getSourceType() { - result = getExpr().getType() - } + Array getSourceType() { result = getExpr().getType() } /** The result type of this cast. */ - Array getTargetType() { - result = getType() - } + Array getTargetType() { result = getType() } - Type getSourceComponentType() { - result = getSourceType().getComponentType() - } + Type getSourceComponentType() { result = getSourceType().getComponentType() } - Type getTargetComponentType() { - result = getTargetType().getComponentType() - } + Type getTargetComponentType() { result = getTargetType().getComponentType() } } predicate uncheckedCastType(RefType t) { @@ -46,14 +39,14 @@ predicate uncheckedCastType(RefType t) { } predicate castFlow(ArrayCast ce, Variable v) { - ce = v.getAnAssignedValue() or + ce = v.getAnAssignedValue() + or exists(Variable mid | castFlow(ce, mid) and mid.getAnAccess() = v.getAnAssignedValue()) } predicate returnedFrom(ArrayCast ce, Method m) { - exists(ReturnStmt ret | ret.getEnclosingCallable() = m | - ret.getResult() = ce - ) or + exists(ReturnStmt ret | ret.getEnclosingCallable() = m | ret.getResult() = ce) + or exists(Variable v | castFlow(ce, v) | returnedVariableFrom(v, m)) } @@ -76,37 +69,36 @@ where ( not uncheckedCastType(target) and message = "Impossible downcast: the cast from " + source.getName() + "[] to " + - target.getName() + "[] will always fail with a ClassCastException." + target.getName() + "[] will always fail with a ClassCastException." ) or - /* - * For unchecked operations, the crash would not occur at the cast site, - * but only if/when the value is assigned to a variable of different array type. - * This would require tracking the flow of values, but we focus on finding problematic - * APIs. We keep two cases: - * - An array that is actually returned from the (non-private) method, or - * - an array that is assigned to a field returned from another (non-private) method. - */ + // For unchecked operations, the crash would not occur at the cast site, + // but only if/when the value is assigned to a variable of different array type. + // This would require tracking the flow of values, but we focus on finding problematic + // APIs. We keep two cases: + // - An array that is actually returned from the (non-private) method, or + // - an array that is assigned to a field returned from another (non-private) method. ( uncheckedCastType(target) and returnedFrom(ce, ce.getEnclosingCallable()) and ce.getEnclosingCallable().getReturnType().(Array).getElementType() = target and not ce.getEnclosingCallable().isPrivate() and - message = - "Impossible downcast: this is returned by " + ce.getEnclosingCallable().getName() + - " as a value of type " + target.getName() + "[], but the array has type " + source.getName() + - "[]. Callers of " + ce.getEnclosingCallable().getName() + " may fail with a ClassCastException." + message = "Impossible downcast: this is returned by " + ce.getEnclosingCallable().getName() + + " as a value of type " + target.getName() + "[], but the array has type " + + source.getName() + "[]. Callers of " + ce.getEnclosingCallable().getName() + + " may fail with a ClassCastException." ) or exists(Method m, Variable v | uncheckedCastType(target) and - castFlow(ce, v) and returnedVariableFrom(v, m) and + castFlow(ce, v) and + returnedVariableFrom(v, m) and m.getReturnType().(Array).getElementType() = target and not m.isPrivate() and - message = - "Impossible downcast: this is assigned to " + v.getName() + " which is returned by " + m + - " as a value of type " + target.getName() + "[], but the array has type " + source.getName() + - "[]. Callers of " + m.getName() + " may fail with a ClassCastException." + message = "Impossible downcast: this is assigned to " + v.getName() + " which is returned by " + + m + " as a value of type " + target.getName() + "[], but the array has type " + + source.getName() + "[]. Callers of " + m.getName() + + " may fail with a ClassCastException." ) ) select ce, message diff --git a/java/ql/src/Likely Bugs/Statements/InconsistentCallOnResult.ql b/java/ql/src/Likely Bugs/Statements/InconsistentCallOnResult.ql index 53d15212868..6526a24cc5f 100644 --- a/java/ql/src/Likely Bugs/Statements/InconsistentCallOnResult.ql +++ b/java/ql/src/Likely Bugs/Statements/InconsistentCallOnResult.ql @@ -13,6 +13,7 @@ * statistical * non-attributable */ + import java import Chaining @@ -37,7 +38,10 @@ predicate checkExpr(MethodAccess callToCheck, MethodAccess otherCall, string ope v.getAnAssignedValue() = callToCheck and otherCall != callToCheck and otherCall.getMethod().getName() = operation and - (otherCall.getAnArgument() = getChainedAccess(v) or otherCall.getQualifier() = getChainedAccess(v)) + ( + otherCall.getAnArgument() = getChainedAccess(v) or + otherCall.getQualifier() = getChainedAccess(v) + ) } /** @@ -56,11 +60,11 @@ predicate implicitCheckExpr(MethodAccess callToCheck, string operation, Variable * Get all accesses to a variable, either directly or by a chain of method calls. */ Expr getChainedAccess(Variable v) { - result = v.getAnAccess() or - exists(MethodAccess chainedAccess | - chainedAccess.getQualifier() = getChainedAccess(v) - | - designedForChaining(chainedAccess.getMethod()) and result = chainedAccess) + result = v.getAnAccess() + or + exists(MethodAccess chainedAccess | chainedAccess.getQualifier() = getChainedAccess(v) | + designedForChaining(chainedAccess.getMethod()) and result = chainedAccess + ) } /** @@ -83,9 +87,7 @@ predicate relevantFunctionCall(MethodAccess ma, Method m) { not okToIgnore(ma) } -predicate okToIgnore(MethodAccess ma) { - not ma.getCompilationUnit().fromSource() -} +predicate okToIgnore(MethodAccess ma) { not ma.getCompilationUnit().fromSource() } predicate functionStats(Method m, string operation, int used, int total, int percentage) { m.getReturnType() instanceof RefType and @@ -104,6 +106,6 @@ where percent >= 90 and not m.getName() = operation and not unchecked.getEnclosingStmt().(ExprStmt).isFieldDecl() -select unchecked, "After " + percent.toString() + "% of calls to " + m.getName() - + " there is a call to " + operation - + " on the return value. The call may be missing in this case." +select unchecked, + "After " + percent.toString() + "% of calls to " + m.getName() + " there is a call to " + + operation + " on the return value. The call may be missing in this case." diff --git a/java/ql/src/Likely Bugs/Statements/PartiallyMaskedCatch.ql b/java/ql/src/Likely Bugs/Statements/PartiallyMaskedCatch.ql index 795a5c6f957..e0f1496de68 100644 --- a/java/ql/src/Likely Bugs/Statements/PartiallyMaskedCatch.ql +++ b/java/ql/src/Likely Bugs/Statements/PartiallyMaskedCatch.ql @@ -18,8 +18,7 @@ import java * Exceptions of type `rt` thrown from within statement `s` are caught by an inner try block * and are therefore not propagated to the outer try block `t`. */ -private -predicate caughtInside(TryStmt t, Stmt s, RefType rt) { +private predicate caughtInside(TryStmt t, Stmt s, RefType rt) { exists(TryStmt innerTry | innerTry.getParent+() = t.getBlock() | s.getParent+() = innerTry.getBlock() and caughtType(innerTry, _).hasSubtype*(rt) @@ -31,8 +30,7 @@ predicate caughtInside(TryStmt t, Stmt s, RefType rt) { * that is relevant to the catch clauses of `t` (i.e. not already * caught by an inner try-catch). */ -private -RefType getAThrownExceptionType(TryStmt t) { +private RefType getAThrownExceptionType(TryStmt t) { exists(Method m, Exception e | ( m = t.getAResourceDecl().getAVariable().getType().(RefType).getAMethod() or @@ -42,18 +40,20 @@ RefType getAThrownExceptionType(TryStmt t) { m.hasNoParameters() and m.getAnException() = e and result = e.getType() - ) or + ) + or exists(Call call, Exception e | t.getBlock() = call.getEnclosingStmt().getParent*() or t.getAResourceDecl() = call.getEnclosingStmt() - | + | ( call.getCallee().getAnException() = e or call.(GenericCall).getATypeArgument(call.getCallee().getAnException().getType()) = e.getType() ) and not caughtInside(t, call.getEnclosingStmt(), e.getType()) and result = e.getType() - ) or + ) + or exists(ThrowStmt ts | t.getBlock() = ts.getParent*() and not caughtInside(t, ts, ts.getExpr().getType()) and @@ -61,8 +61,7 @@ RefType getAThrownExceptionType(TryStmt t) { ) } -private -RefType caughtType(TryStmt try, int index) { +private RefType caughtType(TryStmt try, int index) { exists(CatchClause cc | cc = try.getCatchClause(index) | if cc.isMultiCatch() then result = cc.getVariable().getTypeAccess().(UnionTypeAccess).getAnAlternative().getType() @@ -70,8 +69,7 @@ RefType caughtType(TryStmt try, int index) { ) } -private -predicate maybeUnchecked(RefType t) { +private predicate maybeUnchecked(RefType t) { t.getASupertype*().hasQualifiedName("java.lang", "RuntimeException") or t.getASupertype*().hasQualifiedName("java.lang", "Error") or t.hasQualifiedName("java.lang", "Exception") or @@ -95,7 +93,7 @@ where thrownType = getAThrownExceptionType(try) and // If there's any overlap in the types, this catch block may be relevant. overlappingExceptions(thrownType, masked) - | + | exists(RefType priorCaughtType, int priorIdx | priorIdx < second and priorCaughtType = caughtType(try, priorIdx) and @@ -106,8 +104,6 @@ where if try.getCatchClause(second).isMultiCatch() then multiCatchMsg = " for type " + masked.getName() else multiCatchMsg = "" -select - try.getCatchClause(second), +select try.getCatchClause(second), "This catch-clause is unreachable" + multiCatchMsg + "; it is masked $@.", - try.getCatchClause(first), - "here for exceptions of type '" + masking.getName() + "'" + try.getCatchClause(first), "here for exceptions of type '" + masking.getName() + "'" diff --git a/java/ql/src/Likely Bugs/Statements/ReturnValueIgnored.ql b/java/ql/src/Likely Bugs/Statements/ReturnValueIgnored.ql index 90dd034cc9c..e68ca1528f1 100644 --- a/java/ql/src/Likely Bugs/Statements/ReturnValueIgnored.ql +++ b/java/ql/src/Likely Bugs/Statements/ReturnValueIgnored.ql @@ -12,6 +12,7 @@ * statistical * non-attributable */ + import java import Chaining @@ -32,14 +33,12 @@ predicate isMockingMethod(Method m) { isReceiverClauseMethod(m) } -predicate isReceiverClauseMethod(Method m){ +predicate isReceiverClauseMethod(Method m) { m.getDeclaringType().getASupertype*().hasQualifiedName("org.jmock.syntax", "ReceiverClause") and - ( - m.hasName("of") - ) + (m.hasName("of")) } -predicate isCardinalityClauseMethod(Method m){ +predicate isCardinalityClauseMethod(Method m) { m.getDeclaringType().getASupertype*().hasQualifiedName("org.jmock.syntax", "CardinalityClause") and ( m.hasName("allowing") or @@ -54,7 +53,7 @@ predicate isCardinalityClauseMethod(Method m){ ) } -predicate isStubberMethod(Method m){ +predicate isStubberMethod(Method m) { m.getDeclaringType().getASupertype*().hasQualifiedName("org.mockito.stubbing", "Stubber") and ( m.hasName("when") or @@ -69,11 +68,9 @@ predicate isStubberMethod(Method m){ /** * Some mocking methods must _always_ be used as a qualifier. */ -predicate isMustBeQualifierMockingMethod(Method m){ +predicate isMustBeQualifierMockingMethod(Method m) { m.getDeclaringType().getASupertype*().hasQualifiedName("org.mockito", "Mockito") and - ( - m.hasName("verify") - ) + (m.hasName("verify")) } predicate relevantMethodCall(MethodAccess ma, Method m) { @@ -92,13 +89,12 @@ predicate methodStats(Method m, int used, int total, int percentage) { int chainedUses(Method m) { result = count(MethodAccess ma, MethodAccess qual | - ma.getMethod() = m and - ma.getQualifier() = qual and - qual.getMethod() = m - ) + ma.getMethod() = m and + ma.getQualifier() = qual and + qual.getMethod() = m + ) } - from MethodAccess unchecked, Method m, int percent, int total where relevantMethodCall(unchecked, m) and @@ -107,5 +103,6 @@ where percent >= 90 and not designedForChaining(m) and chainedUses(m) * 100 / total <= 45 // no more than 45% of calls to this method are chained -select unchecked, "The result of the call is ignored, but " + percent.toString() - + "% of calls to " + m.getName() + " use the return value." +select unchecked, + "The result of the call is ignored, but " + percent.toString() + "% of calls to " + m.getName() + + " use the return value." diff --git a/java/ql/src/Likely Bugs/Statements/StaticFieldWrittenByInstance.ql b/java/ql/src/Likely Bugs/Statements/StaticFieldWrittenByInstance.ql index fd82ddb5597..0c53a45df11 100644 --- a/java/ql/src/Likely Bugs/Statements/StaticFieldWrittenByInstance.ql +++ b/java/ql/src/Likely Bugs/Statements/StaticFieldWrittenByInstance.ql @@ -10,6 +10,7 @@ * @tags reliability * maintainability */ + import java from FieldWrite fw, Field f, Callable c, string kind diff --git a/java/ql/src/Likely Bugs/Statements/UseBraces.ql b/java/ql/src/Likely Bugs/Statements/UseBraces.ql index 38289c516e5..a9900556ccf 100644 --- a/java/ql/src/Likely Bugs/Statements/UseBraces.ql +++ b/java/ql/src/Likely Bugs/Statements/UseBraces.ql @@ -10,6 +10,7 @@ * correctness * logic */ + import java /** @@ -21,13 +22,12 @@ predicate unbracedTrailingBody(Stmt ctrlStructure, Stmt trailingBody) { not trailingBody instanceof Block and ( exists(IfStmt c | c = ctrlStructure | - trailingBody = c.getElse() and not trailingBody instanceof IfStmt or + trailingBody = c.getElse() and not trailingBody instanceof IfStmt + or trailingBody = c.getThen() and not exists(c.getElse()) ) or - exists(LoopStmt c | c = ctrlStructure | - not c instanceof DoStmt and trailingBody = c.getBody() - ) + exists(LoopStmt c | c = ctrlStructure | not c instanceof DoStmt and trailingBody = c.getBody()) ) } @@ -43,12 +43,12 @@ predicate unbracedTrailingBody(Stmt ctrlStructure, Stmt trailingBody) { Stmt nextInBlock(Stmt s) { exists(Block b, int i | b.getStmt(i) = s and - b.getStmt(i+1) = result + b.getStmt(i + 1) = result ) or exists(SwitchStmt b, int i | b.getStmt(i) = s and - b.getStmt(i+1) = result + b.getStmt(i + 1) = result ) } @@ -60,15 +60,15 @@ Stmt nonBlockParent(Stmt s) { } /** An else-if construction. */ -predicate ifElseIf(IfStmt s, IfStmt elseif) { - s.getElse() = elseif -} +predicate ifElseIf(IfStmt s, IfStmt elseif) { s.getElse() = elseif } /** * The statement `body` is an unbraced trailing body of a control structure and * `succ` is the next statement in the surrounding `Block` (or `SwitchStmt`). */ -predicate shouldOutdent(Stmt ctrl, Stmt body, Stmt succ, int bodycol, int succcol, int bodyline, int succline) { +predicate shouldOutdent( + Stmt ctrl, Stmt body, Stmt succ, int bodycol, int succcol, int bodyline, int succline +) { unbracedTrailingBody(ctrl, body) and succ = nextInBlock(nonBlockParent*(body)) and bodycol = body.getLocation().getStartColumn() and @@ -101,7 +101,8 @@ predicate suspectIndentation(Stmt ctrl, Stmt body, Stmt succ) { // Disregard cases when `ctrl`, `body`, and `succ` are all equally indented. (ctrlcol < bodycol or bodycol < succcol) and ( - ctrlcol = ctrl.getLocation().getStartColumn() or + ctrlcol = ctrl.getLocation().getStartColumn() + or exists(IfStmt s | ifElseIf+(s, ctrl) and ctrlcol = s.getLocation().getStartColumn()) ) ) @@ -123,6 +124,6 @@ where not t instanceof EmptyStmt and // `LocalClassDeclStmt`s yield false positives since their `Location` doesn't include the `class` keyword. not t instanceof LocalClassDeclStmt -select - s, "Indentation suggests that $@ belongs to $@, but this is not the case; consider adding braces or adjusting indentation.", +select s, + "Indentation suggests that $@ belongs to $@, but this is not the case; consider adding braces or adjusting indentation.", t, "the next statement", c, "the control structure" diff --git a/java/ql/src/Likely Bugs/Termination/ConstantLoopCondition.ql b/java/ql/src/Likely Bugs/Termination/ConstantLoopCondition.ql index 2dad736db5d..4ff1fb4e38b 100644 --- a/java/ql/src/Likely Bugs/Termination/ConstantLoopCondition.ql +++ b/java/ql/src/Likely Bugs/Termination/ConstantLoopCondition.ql @@ -16,7 +16,8 @@ import semmle.code.java.controlflow.Guards import semmle.code.java.dataflow.SSA predicate loopWhileTrue(LoopStmt loop) { - loop instanceof ForStmt and not exists(loop.getCondition()) or + loop instanceof ForStmt and not exists(loop.getCondition()) + or loop.getCondition().(BooleanLiteral).getBooleanValue() = true } @@ -43,9 +44,7 @@ predicate loopExitGuard(LoopStmt loop, Expr cond) { exists(ConditionBlock cb, boolean branch | cond = cb.getCondition() and cond.getEnclosingStmt().getParent*() = loop.getBody() and - forex(Stmt exit | loopExit(loop, exit) | - cb.controls(exit.getBasicBlock(), branch) - ) + forex(Stmt exit | loopExit(loop, exit) | cb.controls(exit.getBasicBlock(), branch)) ) } @@ -57,11 +56,10 @@ predicate loopExitGuard(LoopStmt loop, Expr cond) { predicate mainLoopCondition(LoopStmt loop, Expr cond) { loop.getCondition() = cond and exists(Expr loopReentry, ControlFlowNode last | - if exists(loop.(ForStmt).getAnUpdate()) then - loopReentry = loop.(ForStmt).getUpdate(0) - else - loopReentry = cond - | + if exists(loop.(ForStmt).getAnUpdate()) + then loopReentry = loop.(ForStmt).getUpdate(0) + else loopReentry = cond + | last.getEnclosingStmt().getParent*() = loop.getBody() and last.getASuccessor().(Expr).getParent*() = loopReentry ) @@ -69,7 +67,11 @@ predicate mainLoopCondition(LoopStmt loop, Expr cond) { from LoopStmt loop, Expr cond where - (mainLoopCondition(loop, cond) or loopWhileTrue(loop) and loopExitGuard(loop, cond)) and + ( + mainLoopCondition(loop, cond) + or + loopWhileTrue(loop) and loopExitGuard(loop, cond) + ) and // None of the ssa variables in `cond` are updated inside the loop. forex(SsaVariable ssa, RValue use | ssa.getAUse() = use and use.getParent*() = cond | not ssa.getCFGNode().getEnclosingStmt().getParent*() = loop or @@ -79,4 +81,5 @@ where not exists(MethodAccess ma | ma.getParent*() = cond) and not exists(FieldRead fa | fa.getParent*() = cond) and not exists(ArrayAccess aa | aa.getParent*() = cond) -select loop, "Loop might not terminate, as this $@ is constant within the loop.", cond, "loop condition" +select loop, "Loop might not terminate, as this $@ is constant within the loop.", cond, + "loop condition" diff --git a/java/ql/src/Likely Bugs/Termination/SpinOnField.ql b/java/ql/src/Likely Bugs/Termination/SpinOnField.ql index bb9082b1f8c..a32f237234c 100644 --- a/java/ql/src/Likely Bugs/Termination/SpinOnField.ql +++ b/java/ql/src/Likely Bugs/Termination/SpinOnField.ql @@ -10,6 +10,7 @@ * correctness * concurrency */ + import java /** A numerical comparison or an equality test. */ @@ -35,8 +36,10 @@ class EmptyLoop extends Stmt { count(stmt.getAnInit()) = 0 and count(stmt.getAnUpdate()) = 0 and stmt.getStmt() instanceof Empty - ) or - this.(WhileStmt).getStmt() instanceof Empty or + ) + or + this.(WhileStmt).getStmt() instanceof Empty + or this.(DoStmt).getStmt() instanceof Empty } @@ -64,5 +67,5 @@ where not field.isFinal() and not field.isVolatile() and field.getType() instanceof RefType -select access, "Spinning on " + field.getName() + " in " - + loop.getEnclosingCallable().getName() + "." +select access, + "Spinning on " + field.getName() + " in " + loop.getEnclosingCallable().getName() + "." diff --git a/java/ql/src/Metrics/Authors/AuthorsPerFile.ql b/java/ql/src/Metrics/Authors/AuthorsPerFile.ql index 2579c16a53d..b4378f017b2 100644 --- a/java/ql/src/Metrics/Authors/AuthorsPerFile.ql +++ b/java/ql/src/Metrics/Authors/AuthorsPerFile.ql @@ -8,12 +8,12 @@ * @id java/authors-per-file * @tags maintainability */ - + import java from CompilationUnit u, int num where num = strictcount(string s | - exists(Documentable d | d.getAuthor() = s and d.getCompilationUnit() = u) - ) + exists(Documentable d | d.getAuthor() = s and d.getCompilationUnit() = u) + ) select u, num diff --git a/java/ql/src/Metrics/Callables/CCyclomaticComplexity.ql b/java/ql/src/Metrics/Callables/CCyclomaticComplexity.ql index eda6de3fc78..14117b97c6a 100644 --- a/java/ql/src/Metrics/Callables/CCyclomaticComplexity.ql +++ b/java/ql/src/Metrics/Callables/CCyclomaticComplexity.ql @@ -10,9 +10,9 @@ * complexity * maintainability */ + import java from Callable c where c.fromSource() -select c, c.getMetrics().getCyclomaticComplexity() as n -order by n desc +select c, c.getMetrics().getCyclomaticComplexity() as n order by n desc diff --git a/java/ql/src/Metrics/Callables/CLinesOfCode.ql b/java/ql/src/Metrics/Callables/CLinesOfCode.ql index 3d8a8fa23a3..f1b22c5bf30 100644 --- a/java/ql/src/Metrics/Callables/CLinesOfCode.ql +++ b/java/ql/src/Metrics/Callables/CLinesOfCode.ql @@ -9,9 +9,9 @@ * @tags maintainability * complexity */ + import java from Callable c where c.fromSource() -select c, c.getMetrics().getNumberOfLinesOfCode() as n -order by n desc +select c, c.getMetrics().getNumberOfLinesOfCode() as n order by n desc diff --git a/java/ql/src/Metrics/Callables/CLinesOfComment.ql b/java/ql/src/Metrics/Callables/CLinesOfComment.ql index 637baa56795..15fe71b549e 100644 --- a/java/ql/src/Metrics/Callables/CLinesOfComment.ql +++ b/java/ql/src/Metrics/Callables/CLinesOfComment.ql @@ -9,9 +9,9 @@ * @tags maintainability * documentation */ + import java from Callable c where c.fromSource() -select c, c.getMetrics().getNumberOfCommentLines() as n -order by n desc +select c, c.getMetrics().getNumberOfCommentLines() as n order by n desc diff --git a/java/ql/src/Metrics/Callables/CNumberOfCalls.ql b/java/ql/src/Metrics/Callables/CNumberOfCalls.ql index a5b3565445c..e62df3f3262 100644 --- a/java/ql/src/Metrics/Callables/CNumberOfCalls.ql +++ b/java/ql/src/Metrics/Callables/CNumberOfCalls.ql @@ -10,10 +10,11 @@ * complexity * maintainability */ + import java from Callable c, int n -where c.fromSource() and - n = count(Call call | call.getEnclosingCallable() = c) -select c, n -order by n desc +where + c.fromSource() and + n = count(Call call | call.getEnclosingCallable() = c) +select c, n order by n desc diff --git a/java/ql/src/Metrics/Callables/CNumberOfParameters.ql b/java/ql/src/Metrics/Callables/CNumberOfParameters.ql index f2db1f9b752..3033adc174f 100644 --- a/java/ql/src/Metrics/Callables/CNumberOfParameters.ql +++ b/java/ql/src/Metrics/Callables/CNumberOfParameters.ql @@ -10,9 +10,9 @@ * complexity * maintainability */ + import java from Callable c where c.fromSource() -select c, c.getMetrics().getNumberOfParameters() as n -order by n desc +select c, c.getMetrics().getNumberOfParameters() as n order by n desc diff --git a/java/ql/src/Metrics/Callables/CNumberOfStatements.ql b/java/ql/src/Metrics/Callables/CNumberOfStatements.ql index 8dbe28af52b..459ed435110 100644 --- a/java/ql/src/Metrics/Callables/CNumberOfStatements.ql +++ b/java/ql/src/Metrics/Callables/CNumberOfStatements.ql @@ -8,10 +8,11 @@ * @id java/statements-per-function * @tags maintainability */ + import java from Callable c, int n -where c.fromSource() and - n = count(Stmt s | s.getEnclosingCallable() = c) -select c, n -order by n desc +where + c.fromSource() and + n = count(Stmt s | s.getEnclosingCallable() = c) +select c, n order by n desc diff --git a/java/ql/src/Metrics/Callables/StatementNestingDepth.ql b/java/ql/src/Metrics/Callables/StatementNestingDepth.ql index c2def7a1dc7..85366eabd80 100644 --- a/java/ql/src/Metrics/Callables/StatementNestingDepth.ql +++ b/java/ql/src/Metrics/Callables/StatementNestingDepth.ql @@ -10,6 +10,7 @@ * @tags maintainability * complexity */ + import java /** @@ -18,10 +19,7 @@ import java * consider the second `if` nested. Blocks are also skipped. */ predicate realParent(Stmt inner, Stmt outer) { - if skipParent(inner) then - realParent(inner.getParent(), outer) - else - outer = inner.getParent() + if skipParent(inner) then realParent(inner.getParent(), outer) else outer = inner.getParent() } predicate skipParent(Stmt s) { @@ -37,6 +35,6 @@ predicate nestingDepth(Stmt s, int depth) { } from Method m, int depth -where depth = max(Stmt s, int aDepth | s.getEnclosingCallable() = m and nestingDepth(s, aDepth) | aDepth) -select m, depth -order by depth +where + depth = max(Stmt s, int aDepth | s.getEnclosingCallable() = m and nestingDepth(s, aDepth) | aDepth) +select m, depth order by depth diff --git a/java/ql/src/Metrics/Dependencies/ExternalDependencies.ql b/java/ql/src/Metrics/Dependencies/ExternalDependencies.ql index 70dd46e4752..b4fc18b8fe2 100644 --- a/java/ql/src/Metrics/Dependencies/ExternalDependencies.ql +++ b/java/ql/src/Metrics/Dependencies/ExternalDependencies.ql @@ -28,7 +28,7 @@ import semmle.code.java.DependencyCounts * dashboard database, which is implicitly relative to the source * archive location. */ + from File sourceFile, int total, string entity where fileJarDependencyCount(sourceFile, total, entity) -select entity, total -order by total desc +select entity, total order by total desc diff --git a/java/ql/src/Metrics/Dependencies/ExternalDependenciesSourceLinks.ql b/java/ql/src/Metrics/Dependencies/ExternalDependenciesSourceLinks.ql index e710e4b3e19..f8761c874c2 100644 --- a/java/ql/src/Metrics/Dependencies/ExternalDependenciesSourceLinks.ql +++ b/java/ql/src/Metrics/Dependencies/ExternalDependenciesSourceLinks.ql @@ -16,6 +16,7 @@ import semmle.code.java.DependencyCounts * recover that information once we are in the dashboard database, using the * ExternalEntity.getASourceLink() method. */ + from File sourceFile, string entity where fileJarDependencyCount(sourceFile, _, entity) select entity, sourceFile diff --git a/java/ql/src/Metrics/Files/FAfferentCoupling.ql b/java/ql/src/Metrics/Files/FAfferentCoupling.ql index b344153476f..f1fe4b8eda4 100644 --- a/java/ql/src/Metrics/Files/FAfferentCoupling.ql +++ b/java/ql/src/Metrics/Files/FAfferentCoupling.ql @@ -9,14 +9,14 @@ * @tags changeability * modularity */ + import java from CompilationUnit f, int n where n = count(File g | - exists(Class c | c.fromSource() and c.getCompilationUnit() = f | - exists(Class d | d.fromSource() and d.getCompilationUnit() = g | depends(d,c)) + exists(Class c | c.fromSource() and c.getCompilationUnit() = f | + exists(Class d | d.fromSource() and d.getCompilationUnit() = g | depends(d, c)) + ) ) - ) -select f, n -order by n desc +select f, n order by n desc diff --git a/java/ql/src/Metrics/Files/FCommentRatio.ql b/java/ql/src/Metrics/Files/FCommentRatio.ql index 87791704b13..0c29ac39f1e 100644 --- a/java/ql/src/Metrics/Files/FCommentRatio.ql +++ b/java/ql/src/Metrics/Files/FCommentRatio.ql @@ -9,12 +9,13 @@ * @tags maintainability * documentation */ + import java from CompilationUnit f, float comments, float loc, float ratio -where f.getTotalNumberOfLines() > 0 - and comments = f.getNumberOfCommentLines() - and loc = f.getTotalNumberOfLines() - and ratio = 100.0 * comments / loc -select f, ratio -order by ratio desc \ No newline at end of file +where + f.getTotalNumberOfLines() > 0 and + comments = f.getNumberOfCommentLines() and + loc = f.getTotalNumberOfLines() and + ratio = 100.0 * comments / loc +select f, ratio order by ratio desc diff --git a/java/ql/src/Metrics/Files/FCyclomaticComplexity.ql b/java/ql/src/Metrics/Files/FCyclomaticComplexity.ql index 080807fcdd0..70017d51d2a 100644 --- a/java/ql/src/Metrics/Files/FCyclomaticComplexity.ql +++ b/java/ql/src/Metrics/Files/FCyclomaticComplexity.ql @@ -9,11 +9,14 @@ * @tags testability * complexity */ + import java -from CompilationUnit f, float n -where n = avg(Callable c, int toAvg | - c.getCompilationUnit() = f and toAvg = c.getMetrics().getCyclomaticComplexity() | - toAvg - ) +from CompilationUnit f, float n +where + n = avg(Callable c, int toAvg | + c.getCompilationUnit() = f and toAvg = c.getMetrics().getCyclomaticComplexity() + | + toAvg + ) select f, n diff --git a/java/ql/src/Metrics/Files/FEfferentCoupling.ql b/java/ql/src/Metrics/Files/FEfferentCoupling.ql index f92753b4f69..8fce744a577 100644 --- a/java/ql/src/Metrics/Files/FEfferentCoupling.ql +++ b/java/ql/src/Metrics/Files/FEfferentCoupling.ql @@ -10,13 +10,14 @@ * modularity * maintainability */ + import java from CompilationUnit f, int n -where n = count(File g | - exists(Class c | c.fromSource() and c.getCompilationUnit() = g | - exists(Class d | d.fromSource() and d.getCompilationUnit() = f | depends(d,c)) - ) +where + n = count(File g | + exists(Class c | c.fromSource() and c.getCompilationUnit() = g | + exists(Class d | d.fromSource() and d.getCompilationUnit() = f | depends(d, c)) ) -select f, n -order by n desc + ) +select f, n order by n desc diff --git a/java/ql/src/Metrics/Files/FLines.ql b/java/ql/src/Metrics/Files/FLines.ql index 94288e0946b..907da71b407 100644 --- a/java/ql/src/Metrics/Files/FLines.ql +++ b/java/ql/src/Metrics/Files/FLines.ql @@ -7,9 +7,9 @@ * @metricType file * @metricAggregate avg sum max */ + import java from File f, int n where n = f.getTotalNumberOfLines() -select f, n -order by n desc +select f, n order by n desc diff --git a/java/ql/src/Metrics/Files/FLinesOfCode.ql b/java/ql/src/Metrics/Files/FLinesOfCode.ql index 689ea6e0376..45bea0faf4c 100644 --- a/java/ql/src/Metrics/Files/FLinesOfCode.ql +++ b/java/ql/src/Metrics/Files/FLinesOfCode.ql @@ -10,9 +10,9 @@ * @tags maintainability * complexity */ + import java from File f, int n where n = f.getNumberOfLinesOfCode() -select f, n -order by n desc +select f, n order by n desc diff --git a/java/ql/src/Metrics/Files/FLinesOfComment.ql b/java/ql/src/Metrics/Files/FLinesOfComment.ql index 151e32f8ea4..ee2c21f0d9f 100644 --- a/java/ql/src/Metrics/Files/FLinesOfComment.ql +++ b/java/ql/src/Metrics/Files/FLinesOfComment.ql @@ -10,9 +10,9 @@ * @tags maintainability * documentation */ + import java from File f, int n where n = f.getNumberOfCommentLines() -select f, n -order by n desc +select f, n order by n desc diff --git a/java/ql/src/Metrics/Files/FLinesOfCommentedCode.ql b/java/ql/src/Metrics/Files/FLinesOfCommentedCode.ql index c5f4edf1c14..d6fd316a2d9 100644 --- a/java/ql/src/Metrics/Files/FLinesOfCommentedCode.ql +++ b/java/ql/src/Metrics/Files/FLinesOfCommentedCode.ql @@ -10,10 +10,9 @@ * @tags maintainability * documentation */ - + import Violations_of_Best_Practice.Comments.CommentedCode from File f, int n where n = sum(CommentedOutCode comment | comment.getFile() = f | comment.getCodeLines()) -select f, n -order by n desc +select f, n order by n desc diff --git a/java/ql/src/Metrics/Files/FLinesOfDuplicatedCode.ql b/java/ql/src/Metrics/Files/FLinesOfDuplicatedCode.ql index 0d3c44a9052..d443e3a6741 100644 --- a/java/ql/src/Metrics/Files/FLinesOfDuplicatedCode.ql +++ b/java/ql/src/Metrics/Files/FLinesOfDuplicatedCode.ql @@ -11,15 +11,15 @@ * @tags testability * modularity */ + import external.CodeDuplication from File f, int n where n = count(int line | - exists(DuplicateBlock d | d.sourceFile() = f | - line in [d.sourceStartLine()..d.sourceEndLine()] and - not whitelistedLineForDuplication(f, line) + exists(DuplicateBlock d | d.sourceFile() = f | + line in [d.sourceStartLine() .. d.sourceEndLine()] and + not whitelistedLineForDuplication(f, line) + ) ) - ) -select f, n -order by n desc +select f, n order by n desc diff --git a/java/ql/src/Metrics/Files/FLinesOfSimilarCode.ql b/java/ql/src/Metrics/Files/FLinesOfSimilarCode.ql index da953436c9a..3ef0b03cd59 100644 --- a/java/ql/src/Metrics/Files/FLinesOfSimilarCode.ql +++ b/java/ql/src/Metrics/Files/FLinesOfSimilarCode.ql @@ -9,14 +9,15 @@ * @id java/similar-lines-per-file * @tags testability */ + import external.CodeDuplication from File f, int n -where n = count(int line | - exists(SimilarBlock d | d.sourceFile() = f | - line in [d.sourceStartLine()..d.sourceEndLine()] and - not whitelistedLineForDuplication(f, line) +where + n = count(int line | + exists(SimilarBlock d | d.sourceFile() = f | + line in [d.sourceStartLine() .. d.sourceEndLine()] and + not whitelistedLineForDuplication(f, line) + ) ) - ) -select f, n -order by n desc \ No newline at end of file +select f, n order by n desc diff --git a/java/ql/src/Metrics/Files/FNumberOfClasses.ql b/java/ql/src/Metrics/Files/FNumberOfClasses.ql index dcb7186e956..b950ad5ae57 100644 --- a/java/ql/src/Metrics/Files/FNumberOfClasses.ql +++ b/java/ql/src/Metrics/Files/FNumberOfClasses.ql @@ -8,9 +8,9 @@ * @id java/classes-per-file * @tags maintainability */ + import java from CompilationUnit f, int n where n = count(Class c | c.fromSource() and c.getCompilationUnit() = f) -select f, n -order by n desc +select f, n order by n desc diff --git a/java/ql/src/Metrics/Files/FNumberOfInterfaces.ql b/java/ql/src/Metrics/Files/FNumberOfInterfaces.ql index 1dab5bc745a..5f5ebcd9ddb 100644 --- a/java/ql/src/Metrics/Files/FNumberOfInterfaces.ql +++ b/java/ql/src/Metrics/Files/FNumberOfInterfaces.ql @@ -8,9 +8,9 @@ * @id java/interfaces-per-file * @tags maintainability */ + import java from CompilationUnit f, int n where n = count(Interface i | i.fromSource() and i.getCompilationUnit() = f) -select f, n -order by n desc +select f, n order by n desc diff --git a/java/ql/src/Metrics/Files/FNumberOfTests.ql b/java/ql/src/Metrics/Files/FNumberOfTests.ql index f52a27adf74..dc9ed989ef8 100644 --- a/java/ql/src/Metrics/Files/FNumberOfTests.ql +++ b/java/ql/src/Metrics/Files/FNumberOfTests.ql @@ -9,9 +9,9 @@ * @id java/tests-in-files * @tags maintainability */ + import java from CompilationUnit f, int n where n = strictcount(TestMethod test | test.fromSource() and test.getCompilationUnit() = f) -select f, n -order by n desc +select f, n order by n desc diff --git a/java/ql/src/Metrics/Files/FSelfContainedness.ql b/java/ql/src/Metrics/Files/FSelfContainedness.ql index 55a5aa5e3f1..49b04589d4d 100644 --- a/java/ql/src/Metrics/Files/FSelfContainedness.ql +++ b/java/ql/src/Metrics/Files/FSelfContainedness.ql @@ -9,21 +9,22 @@ * @tags portability * modularity */ + import java from CompilationUnit f, float selfContaindness, int efferentSourceCoupling, int efferentCoupling -where efferentSourceCoupling = count(CompilationUnit g | - exists(RefType c | c.fromSource() and c.getCompilationUnit() = g | - exists(RefType d | d.fromSource() and d.getCompilationUnit()= f | depends(d,c)) - ) +where + efferentSourceCoupling = count(CompilationUnit g | + exists(RefType c | c.fromSource() and c.getCompilationUnit() = g | + exists(RefType d | d.fromSource() and d.getCompilationUnit() = f | depends(d, c)) ) - and efferentCoupling = count(CompilationUnit g | - exists(RefType c | c.getCompilationUnit() = g | - exists(RefType d | d.fromSource() and d.getCompilationUnit() = f | depends(d,c)) - ) + ) and + efferentCoupling = count(CompilationUnit g | + exists(RefType c | c.getCompilationUnit() = g | + exists(RefType d | d.fromSource() and d.getCompilationUnit() = f | depends(d, c)) ) - and if efferentCoupling = 0 - then selfContaindness = 100 - else selfContaindness = 100*(float)efferentSourceCoupling/efferentCoupling -select f, selfContaindness -order by selfContaindness desc + ) and + if efferentCoupling = 0 + then selfContaindness = 100 + else selfContaindness = 100 * efferentSourceCoupling.(float) / efferentCoupling +select f, selfContaindness order by selfContaindness desc diff --git a/java/ql/src/Metrics/History/HChurn.ql b/java/ql/src/Metrics/History/HChurn.ql index be210606eb5..59cc7c8e634 100644 --- a/java/ql/src/Metrics/History/HChurn.ql +++ b/java/ql/src/Metrics/History/HChurn.ql @@ -7,13 +7,15 @@ * @metricAggregate avg sum max * @id java/vcs/churn-per-file */ + import java import external.VCS from File f, int n -where n = sum(Commit entry, int churn | - churn = entry.getRecentChurnForFile(f) and not artificialChange(entry) | - churn - ) -select f, n -order by n desc +where + n = sum(Commit entry, int churn | + churn = entry.getRecentChurnForFile(f) and not artificialChange(entry) + | + churn + ) +select f, n order by n desc diff --git a/java/ql/src/Metrics/History/HLinesAdded.ql b/java/ql/src/Metrics/History/HLinesAdded.ql index b43f7a5ddf0..4aa6adc74bd 100644 --- a/java/ql/src/Metrics/History/HLinesAdded.ql +++ b/java/ql/src/Metrics/History/HLinesAdded.ql @@ -7,10 +7,15 @@ * @metricAggregate avg sum max * @id java/vcs/added-lines-per-file */ + import java import external.VCS from File f, int n -where n = sum(Commit entry, int churn | churn = entry.getRecentAdditionsForFile(f) and not artificialChange(entry) | churn) -select f, n -order by n desc +where + n = sum(Commit entry, int churn | + churn = entry.getRecentAdditionsForFile(f) and not artificialChange(entry) + | + churn + ) +select f, n order by n desc diff --git a/java/ql/src/Metrics/History/HLinesDeleted.ql b/java/ql/src/Metrics/History/HLinesDeleted.ql index 10d40d44bde..4e476da307c 100644 --- a/java/ql/src/Metrics/History/HLinesDeleted.ql +++ b/java/ql/src/Metrics/History/HLinesDeleted.ql @@ -7,10 +7,15 @@ * @metricAggregate avg sum max * @id java/vcs/deleted-lines-per-file */ + import java import external.VCS from File f, int n -where n = sum(Commit entry, int churn | churn = entry.getRecentDeletionsForFile(f) and not artificialChange(entry) | churn) -select f, n -order by n desc +where + n = sum(Commit entry, int churn | + churn = entry.getRecentDeletionsForFile(f) and not artificialChange(entry) + | + churn + ) +select f, n order by n desc diff --git a/java/ql/src/Metrics/History/HNumberOfAuthors.ql b/java/ql/src/Metrics/History/HNumberOfAuthors.ql index 35915981b8f..fef9bc3cfdf 100644 --- a/java/ql/src/Metrics/History/HNumberOfAuthors.ql +++ b/java/ql/src/Metrics/History/HNumberOfAuthors.ql @@ -7,6 +7,7 @@ * @metricAggregate avg min max * @id java/vcs/authors-per-file */ + import java import external.VCS diff --git a/java/ql/src/Metrics/History/HNumberOfChanges.ql b/java/ql/src/Metrics/History/HNumberOfChanges.ql index 427d5356d13..5209ebd7af7 100644 --- a/java/ql/src/Metrics/History/HNumberOfChanges.ql +++ b/java/ql/src/Metrics/History/HNumberOfChanges.ql @@ -7,6 +7,7 @@ * @metricAggregate avg min max sum * @id java/vcs/commits-per-file */ + import java import external.VCS diff --git a/java/ql/src/Metrics/History/HNumberOfRecentChanges.ql b/java/ql/src/Metrics/History/HNumberOfRecentChanges.ql index 4de946f033a..e5006895faf 100644 --- a/java/ql/src/Metrics/History/HNumberOfRecentChanges.ql +++ b/java/ql/src/Metrics/History/HNumberOfRecentChanges.ql @@ -7,14 +7,15 @@ * @metricAggregate avg min max sum * @id java/vcs/recent-commits-per-file */ + import java import external.VCS from File f, int n -where n = count(Commit e | - e.getAnAffectedFile() = f and - e.daysToNow() <= 180 and - not artificialChange(e) - ) -select f, n -order by n desc +where + n = count(Commit e | + e.getAnAffectedFile() = f and + e.daysToNow() <= 180 and + not artificialChange(e) + ) +select f, n order by n desc diff --git a/java/ql/src/Metrics/Internal/CallableDisplayStrings.ql b/java/ql/src/Metrics/Internal/CallableDisplayStrings.ql index 053cee84ead..006de2354f9 100644 --- a/java/ql/src/Metrics/Internal/CallableDisplayStrings.ql +++ b/java/ql/src/Metrics/Internal/CallableDisplayStrings.ql @@ -4,6 +4,7 @@ * @metricType callable * @id java/callable-display-strings */ + import java private string prefix(Callable c) { diff --git a/java/ql/src/Metrics/Internal/CallableExtents.ql b/java/ql/src/Metrics/Internal/CallableExtents.ql index 245a62f9f79..def86a82f3d 100644 --- a/java/ql/src/Metrics/Internal/CallableExtents.ql +++ b/java/ql/src/Metrics/Internal/CallableExtents.ql @@ -4,6 +4,7 @@ * @metricType callable * @id java/callable-extents */ + import java import Extents diff --git a/java/ql/src/Metrics/Internal/CallableSourceLinks.ql b/java/ql/src/Metrics/Internal/CallableSourceLinks.ql index 4794a0dd174..94c8b8108c1 100644 --- a/java/ql/src/Metrics/Internal/CallableSourceLinks.ql +++ b/java/ql/src/Metrics/Internal/CallableSourceLinks.ql @@ -4,6 +4,7 @@ * @metricType callable * @id java/callable-source-links */ + import java from Callable c diff --git a/java/ql/src/Metrics/Internal/ReftypeDisplayStrings.ql b/java/ql/src/Metrics/Internal/ReftypeDisplayStrings.ql index 181893259bd..6351b207bfa 100644 --- a/java/ql/src/Metrics/Internal/ReftypeDisplayStrings.ql +++ b/java/ql/src/Metrics/Internal/ReftypeDisplayStrings.ql @@ -4,12 +4,11 @@ * @metricType reftype * @id java/reference-type-display-strings */ + import java private string suffix(RefType t) { - if t instanceof AnonymousClass - then result = "" - else result = "" + if t instanceof AnonymousClass then result = "" else result = "" } from RefType t diff --git a/java/ql/src/Metrics/Internal/ReftypeExtents.ql b/java/ql/src/Metrics/Internal/ReftypeExtents.ql index 41cfc039ff8..8a1151fa51a 100644 --- a/java/ql/src/Metrics/Internal/ReftypeExtents.ql +++ b/java/ql/src/Metrics/Internal/ReftypeExtents.ql @@ -4,6 +4,7 @@ * @metricType reftype * @id java/reference-type-extents */ + import java import Extents diff --git a/java/ql/src/Metrics/Internal/ReftypeSourceLinks.ql b/java/ql/src/Metrics/Internal/ReftypeSourceLinks.ql index 38db0d64679..693fad7f1df 100644 --- a/java/ql/src/Metrics/Internal/ReftypeSourceLinks.ql +++ b/java/ql/src/Metrics/Internal/ReftypeSourceLinks.ql @@ -4,6 +4,7 @@ * @metricType reftype * @id java/reference-type-source-links */ + import java from RefType t diff --git a/java/ql/src/Metrics/RefTypes/TAfferentCoupling.ql b/java/ql/src/Metrics/RefTypes/TAfferentCoupling.ql index 408b3944c29..4d930beb492 100644 --- a/java/ql/src/Metrics/RefTypes/TAfferentCoupling.ql +++ b/java/ql/src/Metrics/RefTypes/TAfferentCoupling.ql @@ -9,9 +9,9 @@ * @tags changeability * modularity */ + import java from RefType t where t.fromSource() -select t, t.getMetrics().getAfferentCoupling() as n -order by n desc +select t, t.getMetrics().getAfferentCoupling() as n order by n desc diff --git a/java/ql/src/Metrics/RefTypes/TEfferentCoupling.ql b/java/ql/src/Metrics/RefTypes/TEfferentCoupling.ql index e34e80cd12e..32782c84d8a 100644 --- a/java/ql/src/Metrics/RefTypes/TEfferentCoupling.ql +++ b/java/ql/src/Metrics/RefTypes/TEfferentCoupling.ql @@ -10,9 +10,9 @@ * modularity * maintainability */ + import java from RefType t where t.fromSource() -select t, t.getMetrics().getEfferentCoupling() as n -order by n desc +select t, t.getMetrics().getEfferentCoupling() as n order by n desc diff --git a/java/ql/src/Metrics/RefTypes/TEfferentSourceCoupling.ql b/java/ql/src/Metrics/RefTypes/TEfferentSourceCoupling.ql index 91cfcaaff9c..4bed4b97e3c 100644 --- a/java/ql/src/Metrics/RefTypes/TEfferentSourceCoupling.ql +++ b/java/ql/src/Metrics/RefTypes/TEfferentSourceCoupling.ql @@ -10,9 +10,9 @@ * maintainability * modularity */ + import java from RefType t where t.fromSource() -select t, t.getMetrics().getEfferentSourceCoupling() as n -order by n desc +select t, t.getMetrics().getEfferentSourceCoupling() as n order by n desc diff --git a/java/ql/src/Metrics/RefTypes/TInheritanceDepth.ql b/java/ql/src/Metrics/RefTypes/TInheritanceDepth.ql index d1e8309c159..a449ea37c99 100644 --- a/java/ql/src/Metrics/RefTypes/TInheritanceDepth.ql +++ b/java/ql/src/Metrics/RefTypes/TInheritanceDepth.ql @@ -9,9 +9,9 @@ * @tags changeability * modularity */ + import java from RefType t where t.fromSource() -select t, t.getMetrics().getInheritanceDepth() as n -order by n desc +select t, t.getMetrics().getInheritanceDepth() as n order by n desc diff --git a/java/ql/src/Metrics/RefTypes/TLackOfCohesionCK.ql b/java/ql/src/Metrics/RefTypes/TLackOfCohesionCK.ql index 33e1b973a19..8f11f4ec7ac 100644 --- a/java/ql/src/Metrics/RefTypes/TLackOfCohesionCK.ql +++ b/java/ql/src/Metrics/RefTypes/TLackOfCohesionCK.ql @@ -9,9 +9,9 @@ * @tags modularity * maintainability */ + import java from RefType t where t.fromSource() -select t, t.getMetrics().getLackOfCohesionCK() as n -order by n desc +select t, t.getMetrics().getLackOfCohesionCK() as n order by n desc diff --git a/java/ql/src/Metrics/RefTypes/TLackOfCohesionHS.ql b/java/ql/src/Metrics/RefTypes/TLackOfCohesionHS.ql index 667f100c410..c818af9a832 100644 --- a/java/ql/src/Metrics/RefTypes/TLackOfCohesionHS.ql +++ b/java/ql/src/Metrics/RefTypes/TLackOfCohesionHS.ql @@ -8,9 +8,9 @@ * @id java/lack-of-cohesion-hs * @tags modularity */ + import java from RefType t where t.fromSource() -select t, t.getMetrics().getLackOfCohesionHS() as n -order by n desc +select t, t.getMetrics().getLackOfCohesionHS() as n order by n desc diff --git a/java/ql/src/Metrics/RefTypes/TLinesOfCode.ql b/java/ql/src/Metrics/RefTypes/TLinesOfCode.ql index 44205268778..05b1406cfd2 100644 --- a/java/ql/src/Metrics/RefTypes/TLinesOfCode.ql +++ b/java/ql/src/Metrics/RefTypes/TLinesOfCode.ql @@ -8,9 +8,9 @@ * @id java/lines-of-code-per-type * @tags maintainability */ + import java from RefType t where t.fromSource() -select t, t.getMetrics().getNumberOfLinesOfCode() as n -order by n desc +select t, t.getMetrics().getNumberOfLinesOfCode() as n order by n desc diff --git a/java/ql/src/Metrics/RefTypes/TLinesOfComment.ql b/java/ql/src/Metrics/RefTypes/TLinesOfComment.ql index 1bf1da4dc8d..24fa2a81ac1 100644 --- a/java/ql/src/Metrics/RefTypes/TLinesOfComment.ql +++ b/java/ql/src/Metrics/RefTypes/TLinesOfComment.ql @@ -9,9 +9,9 @@ * @tags maintainability * documentation */ + import java from RefType t where t.fromSource() -select t, t.getMetrics().getNumberOfCommentLines() as n -order by n desc +select t, t.getMetrics().getNumberOfCommentLines() as n order by n desc diff --git a/java/ql/src/Metrics/RefTypes/TNumberOfCallables.ql b/java/ql/src/Metrics/RefTypes/TNumberOfCallables.ql index 87500cd8d6f..7cdac73b543 100644 --- a/java/ql/src/Metrics/RefTypes/TNumberOfCallables.ql +++ b/java/ql/src/Metrics/RefTypes/TNumberOfCallables.ql @@ -8,9 +8,9 @@ * @id java/functions-per-type * @tags maintainability */ + import java from RefType t where t.fromSource() -select t, t.getMetrics().getNumberOfCallables() as n -order by n desc +select t, t.getMetrics().getNumberOfCallables() as n order by n desc diff --git a/java/ql/src/Metrics/RefTypes/TNumberOfFields.ql b/java/ql/src/Metrics/RefTypes/TNumberOfFields.ql index 50dd6c54511..05bfbc623ef 100644 --- a/java/ql/src/Metrics/RefTypes/TNumberOfFields.ql +++ b/java/ql/src/Metrics/RefTypes/TNumberOfFields.ql @@ -9,9 +9,9 @@ * @tags maintainability * complexity */ + import java from RefType t where t.fromSource() -select t, t.getMetrics().getNumberOfExplicitFields() as n -order by n desc +select t, t.getMetrics().getNumberOfExplicitFields() as n order by n desc diff --git a/java/ql/src/Metrics/RefTypes/TNumberOfStatements.ql b/java/ql/src/Metrics/RefTypes/TNumberOfStatements.ql index fb46b85a6d8..709ea75109e 100644 --- a/java/ql/src/Metrics/RefTypes/TNumberOfStatements.ql +++ b/java/ql/src/Metrics/RefTypes/TNumberOfStatements.ql @@ -8,10 +8,11 @@ * @id java/statements-per-type * @tags maintainability */ + import java from RefType t, int n -where t.fromSource() and - n = count(Stmt s | s.getEnclosingCallable() = t.getACallable()) -select t, n -order by n desc +where + t.fromSource() and + n = count(Stmt s | s.getEnclosingCallable() = t.getACallable()) +select t, n order by n desc diff --git a/java/ql/src/Metrics/RefTypes/TPercentageOfComments.ql b/java/ql/src/Metrics/RefTypes/TPercentageOfComments.ql index e18f56e0412..f2258282c99 100644 --- a/java/ql/src/Metrics/RefTypes/TPercentageOfComments.ql +++ b/java/ql/src/Metrics/RefTypes/TPercentageOfComments.ql @@ -9,11 +9,12 @@ * @tags maintainability * documentation */ + import java from RefType t, int n -where t.fromSource() - and n = (100 * t.getMetrics().getNumberOfCommentLines()) / - (t.getMetrics().getNumberOfCommentLines() + t.getMetrics().getNumberOfLinesOfCode()) -select t, n -order by n desc +where + t.fromSource() and + n = (100 * t.getMetrics().getNumberOfCommentLines()) / + (t.getMetrics().getNumberOfCommentLines() + t.getMetrics().getNumberOfLinesOfCode()) +select t, n order by n desc diff --git a/java/ql/src/Metrics/RefTypes/TPercentageOfComplexCode.ql b/java/ql/src/Metrics/RefTypes/TPercentageOfComplexCode.ql index 0a8d5fe392d..4ec8bbe4734 100644 --- a/java/ql/src/Metrics/RefTypes/TPercentageOfComplexCode.ql +++ b/java/ql/src/Metrics/RefTypes/TPercentageOfComplexCode.ql @@ -9,6 +9,7 @@ * @tags testability * complexity */ + import java pragma[noopt] @@ -19,10 +20,10 @@ int complexCallableLines(MetricCallable c, RefType owner) { } from MetricRefType t, int ccLoc, int loc -where t.fromSource() and - not (t instanceof GeneratedClass) and - ccLoc = sum(Callable c, int cLoc | cLoc = complexCallableLines(c, t) | cLoc) and - loc = t.getNumberOfLinesOfCode() and - loc != 0 -select t, ((float)ccLoc*100)/loc as n -order by n desc +where + t.fromSource() and + not (t instanceof GeneratedClass) and + ccLoc = sum(Callable c, int cLoc | cLoc = complexCallableLines(c, t) | cLoc) and + loc = t.getNumberOfLinesOfCode() and + loc != 0 +select t, (ccLoc.(float) * 100) / loc as n order by n desc diff --git a/java/ql/src/Metrics/RefTypes/TResponse.ql b/java/ql/src/Metrics/RefTypes/TResponse.ql index b9bf128194d..ab88bf17459 100644 --- a/java/ql/src/Metrics/RefTypes/TResponse.ql +++ b/java/ql/src/Metrics/RefTypes/TResponse.ql @@ -10,9 +10,9 @@ * @tags maintainability * complexity */ + import java from RefType t where t.fromSource() -select t, t.getMetrics().getResponse() as n -order by n desc +select t, t.getMetrics().getResponse() as n order by n desc diff --git a/java/ql/src/Metrics/RefTypes/TSelfContainedness.ql b/java/ql/src/Metrics/RefTypes/TSelfContainedness.ql index 672177aa345..5185b78ae9e 100644 --- a/java/ql/src/Metrics/RefTypes/TSelfContainedness.ql +++ b/java/ql/src/Metrics/RefTypes/TSelfContainedness.ql @@ -9,9 +9,11 @@ * @tags portability * modularity */ + import java from RefType t, float n -where t.fromSource() - and n = 100 * t.getMetrics().getEfferentSourceCoupling() / t.getMetrics().getEfferentCoupling() +where + t.fromSource() and + n = 100 * t.getMetrics().getEfferentSourceCoupling() / t.getMetrics().getEfferentCoupling() select t, n diff --git a/java/ql/src/Metrics/RefTypes/TSizeOfAPI.ql b/java/ql/src/Metrics/RefTypes/TSizeOfAPI.ql index fbc9130cbf1..79de372ed7a 100644 --- a/java/ql/src/Metrics/RefTypes/TSizeOfAPI.ql +++ b/java/ql/src/Metrics/RefTypes/TSizeOfAPI.ql @@ -9,11 +9,12 @@ * @tags testability * modularity */ + import java from Class c, int n -where c.fromSource() and - c.isPublic() and - n = count(Method m | c.getAMethod() = m and m.isPublic()) -select c, n -order by n desc +where + c.fromSource() and + c.isPublic() and + n = count(Method m | c.getAMethod() = m and m.isPublic()) +select c, n order by n desc diff --git a/java/ql/src/Metrics/RefTypes/TSpecialisationIndex.ql b/java/ql/src/Metrics/RefTypes/TSpecialisationIndex.ql index f5c6916d492..3b5e9ad648f 100644 --- a/java/ql/src/Metrics/RefTypes/TSpecialisationIndex.ql +++ b/java/ql/src/Metrics/RefTypes/TSpecialisationIndex.ql @@ -9,11 +9,12 @@ * @tags modularity * maintainability */ + import java from RefType t -where t.fromSource() and - (t instanceof ParameterizedType implies t instanceof GenericType) and - not t instanceof AnonymousClass -select t, t.getMetrics().getSpecialisationIndex() as n -order by n desc +where + t.fromSource() and + (t instanceof ParameterizedType implies t instanceof GenericType) and + not t instanceof AnonymousClass +select t, t.getMetrics().getSpecialisationIndex() as n order by n desc diff --git a/java/ql/src/Performance/ConcatenationInLoops.ql b/java/ql/src/Performance/ConcatenationInLoops.ql index a1151892a14..e6339a8782a 100644 --- a/java/ql/src/Performance/ConcatenationInLoops.ql +++ b/java/ql/src/Performance/ConcatenationInLoops.ql @@ -9,17 +9,14 @@ * @tags efficiency * maintainability */ + import semmle.code.java.Type import semmle.code.java.Expr import semmle.code.java.Statement import semmle.code.java.JDK /** A use of `+` that has type `String`. */ -class StringCat extends AddExpr { - StringCat() { - this.getType() instanceof TypeString - } -} +class StringCat extends AddExpr { StringCat() { this.getType() instanceof TypeString } } /** * An assignment of the form @@ -42,9 +39,7 @@ predicate useAndDef(Assignment a, Variable v) { a instanceof AssignAddExpr or ( - exists(VarAccess use | use.getVariable() = v | - use.getParent*() = a.getSource() - ) and + exists(VarAccess use | use.getVariable() = v | use.getParent*() = a.getSource()) and a.getSource() instanceof AddExpr ) ) @@ -54,16 +49,13 @@ predicate declaredInLoop(LocalVariableDecl v, LoopStmt loop) { exists(LocalVariableDeclExpr e | e.getVariable() = v and e.getEnclosingStmt().getParent*() = loop.getBody() - ) or - exists(EnhancedForStmt for | for = loop | - for.getVariable().getVariable() = v ) + or + exists(EnhancedForStmt for | for = loop | for.getVariable().getVariable() = v) } from Assignment a, Variable v where useAndDef(a, v) and - exists(LoopStmt loop | a.getEnclosingStmt().getParent*() = loop | - not declaredInLoop(v, loop) - ) + exists(LoopStmt loop | a.getEnclosingStmt().getParent*() = loop | not declaredInLoop(v, loop)) select a, "The string " + v.getName() + " is built-up in a loop: use string buffer." diff --git a/java/ql/src/Performance/InefficientEmptyStringTest.ql b/java/ql/src/Performance/InefficientEmptyStringTest.ql index 57787900218..2cf9abc08ef 100644 --- a/java/ql/src/Performance/InefficientEmptyStringTest.ql +++ b/java/ql/src/Performance/InefficientEmptyStringTest.ql @@ -8,6 +8,7 @@ * @tags efficiency * maintainability */ + import java from MethodAccess mc diff --git a/java/ql/src/Performance/InefficientKeySetIterator.ql b/java/ql/src/Performance/InefficientKeySetIterator.ql index 1e7e5ace7bb..73e1dd3aa72 100644 --- a/java/ql/src/Performance/InefficientKeySetIterator.ql +++ b/java/ql/src/Performance/InefficientKeySetIterator.ql @@ -8,6 +8,7 @@ * @tags efficiency * maintainability */ + import java /** A local variable that is initialized using a key-set iterator. */ @@ -34,7 +35,8 @@ predicate isKeyNext(Expr e, KeySetIterator it) { exists(MethodAccess ma | ma = e | ma.getMethod().hasName("next") and ma.getQualifier().(VarAccess).getVariable() = it - ) or + ) + or isKeyNext(e.(CastExpr).getExpr(), it) } @@ -58,6 +60,8 @@ from MethodAccess ma, Method get where ma.getMethod() = get and get.hasName("get") and - ma.getAnArgument().(VarAccess).getVariable().(Key).getBase().getBase() - = ma.getQualifier().(VarAccess).getVariable() + ma.getAnArgument().(VarAccess).getVariable().(Key).getBase().getBase() = ma + .getQualifier() + .(VarAccess) + .getVariable() select ma, "Inefficient use of key set iterator instead of entry set iterator." diff --git a/java/ql/src/Performance/InefficientOutputStream.ql b/java/ql/src/Performance/InefficientOutputStream.ql index 9b6b70e5e64..3eb7ef18bf5 100644 --- a/java/ql/src/Performance/InefficientOutputStream.ql +++ b/java/ql/src/Performance/InefficientOutputStream.ql @@ -18,7 +18,6 @@ class InefficientWriteBytes extends Class { } } - from Class c, Method m where not c.isAbstract() and @@ -36,4 +35,6 @@ where // If that method doesn't call write itself, then we don't have a problem. // This is the case is some dummy implementations. exists(MethodAccess ma | ma.getEnclosingCallable() = m | ma.getMethod().getName() = "write") -select c, "This class extends java.io.OutputStream and implements $@, but does not override write(byte[],int,int)", m, m.getName() +select c, + "This class extends java.io.OutputStream and implements $@, but does not override write(byte[],int,int)", + m, m.getName() diff --git a/java/ql/src/Performance/InefficientPrimConstructor.ql b/java/ql/src/Performance/InefficientPrimConstructor.ql index 773abe39e1a..e8992b017f9 100644 --- a/java/ql/src/Performance/InefficientPrimConstructor.ql +++ b/java/ql/src/Performance/InefficientPrimConstructor.ql @@ -8,11 +8,13 @@ * @tags efficiency * maintainability */ + import java from ClassInstanceExpr call, BoxedType type where type = call.getType() and not call.getEnclosingCallable().getDeclaringType() = type -select call, "Inefficient constructor for " + type.getPrimitiveType().getName() + - " value, use " + type.getName() + ".valueOf(...) instead." +select call, + "Inefficient constructor for " + type.getPrimitiveType().getName() + " value, use " + + type.getName() + ".valueOf(...) instead." diff --git a/java/ql/src/Performance/InefficientToArray.ql b/java/ql/src/Performance/InefficientToArray.ql index 2ae453f674b..957b7b01e2f 100644 --- a/java/ql/src/Performance/InefficientToArray.ql +++ b/java/ql/src/Performance/InefficientToArray.ql @@ -7,9 +7,11 @@ * @id java/inefficient-to-array * @deprecated */ + import java -/* This method uses the toArray() method of a collection derived class, and passes in a +/* + * This method uses the toArray() method of a collection derived class, and passes in a * zero-length prototype array argument. * * It is more efficient to use myCollection.toArray(new Foo[myCollection.size()]). @@ -37,11 +39,7 @@ predicate emptyArrayLiteral(Expr e) { ) } -class EmptyArrayLiteral extends Expr { - EmptyArrayLiteral() { - emptyArrayLiteral(this) - } -} +class EmptyArrayLiteral extends Expr { EmptyArrayLiteral() { emptyArrayLiteral(this) } } from EmptyArrayLiteral l, MethodAccess ma, Method m, GenericInterface coll where diff --git a/java/ql/src/Performance/InnerClassCouldBeStatic.ql b/java/ql/src/Performance/InnerClassCouldBeStatic.ql index 29728cd4fdd..7a138ae31b3 100644 --- a/java/ql/src/Performance/InnerClassCouldBeStatic.ql +++ b/java/ql/src/Performance/InnerClassCouldBeStatic.ql @@ -18,7 +18,8 @@ import java * packages, but it's enough for the purposes of this check. */ predicate inherits(Class c, Field f) { - f = c.getAField() or + f = c.getAField() + or (not f.isPrivate() and c.getASupertype+().getAField() = f) } @@ -27,12 +28,9 @@ predicate inherits(Class c, Field f) { * of the type containing it. */ class EnclosingInstanceAccess extends Expr { - EnclosingInstanceAccess() { - exists(enclosingInstanceAccess(this)) - } - RefType getAnAccessedType() { - result = enclosingInstanceAccess(this) - } + EnclosingInstanceAccess() { exists(enclosingInstanceAccess(this)) } + + RefType getAnAccessedType() { result = enclosingInstanceAccess(this) } } RefType enclosingInstanceAccess(Expr expr) { @@ -48,11 +46,12 @@ RefType enclosingInstanceAccess(Expr expr) { // non-static type that needs an enclosing instance. exists(ClassInstanceExpr new, InnerClass t | new = expr and t = new.getType().(RefType).getSourceDeclaration() - | + | result = t and not exists(new.getQualifier()) and not t.getEnclosingType*() = enclosing - ) or + ) + or // An unqualified method or field access to a member that isn't inherited // must refer to an enclosing instance. exists(FieldAccess fa | fa = expr | @@ -60,7 +59,8 @@ RefType enclosingInstanceAccess(Expr expr) { not exists(fa.getQualifier()) and not fa.getVariable().(Field).isStatic() and not inherits(enclosing, fa.getVariable()) - ) or + ) + or exists(MethodAccess ma | ma = expr | result = ma.getMethod().getDeclaringType() and not exists(ma.getQualifier()) and @@ -90,12 +90,15 @@ predicate potentiallyStatic(InnerClass c) { ) and not c instanceof AnonymousClass and not c instanceof LocalClass and - forall(InnerClass other | // If nested and non-static, ... + forall( + InnerClass other // If nested and non-static, ... + | // ... all supertypes (which are from source), ... - (other = c.getASourceSupertype() and other.fromSource()) or + (other = c.getASourceSupertype() and other.fromSource()) + or // ... and the enclosing type, ... other = c.getEnclosingType() - | + | // ... must be (potentially) static. potentiallyStatic(other) ) and @@ -104,7 +107,7 @@ predicate potentiallyStatic(InnerClass c) { forall(EnclosingInstanceAccess a, Method m | // ... that occur in a method of a nested class of `c` ... m = a.getEnclosingCallable() and m.getDeclaringType().getEnclosingType+() = c - | + | // ... the access must be to a member of a type enclosed in `c` or `c` itself. a.getAnAccessedType().getEnclosingType*() = c ) and @@ -120,26 +123,21 @@ predicate potentiallyStatic(InnerClass c) { * A problematic class, meaning a class that could be static but isn't. */ class ProblematicClass extends InnerClass { - ProblematicClass() { - potentiallyStatic(this) - } + ProblematicClass() { potentiallyStatic(this) } /** * Check for accesses to the enclosing instance in a constructor or field * initializer. */ predicate usesEnclosingInstanceInConstructor() { - exists(EnclosingInstanceAccess a | - a.getEnclosingCallable() = this.getAConstructor() - ) + exists(EnclosingInstanceAccess a | a.getEnclosingCallable() = this.getAConstructor()) } } from ProblematicClass c, string msg where c.fromSource() and - if c.usesEnclosingInstanceInConstructor() then - msg = " could be made static, since the enclosing instance is used only in its constructor." - else - msg = " should be made static, since the enclosing instance is not used." + if c.usesEnclosingInstanceInConstructor() + then msg = " could be made static, since the enclosing instance is used only in its constructor." + else msg = " should be made static, since the enclosing instance is not used." select c, c.getName() + msg diff --git a/java/ql/src/Performance/NewStringString.ql b/java/ql/src/Performance/NewStringString.ql index 365a6cf886a..b2f26069ea2 100644 --- a/java/ql/src/Performance/NewStringString.ql +++ b/java/ql/src/Performance/NewStringString.ql @@ -9,6 +9,7 @@ * @tags efficiency * maintainability */ + import java from ClassInstanceExpr e diff --git a/java/ql/src/Security/CWE/CWE-022/TaintedPath.ql b/java/ql/src/Security/CWE/CWE-022/TaintedPath.ql index 0b13c8c00ec..fef3fa65e85 100644 --- a/java/ql/src/Security/CWE/CWE-022/TaintedPath.ql +++ b/java/ql/src/Security/CWE/CWE-022/TaintedPath.ql @@ -11,16 +11,20 @@ * external/cwe/cwe-036 * external/cwe/cwe-073 */ + import java import semmle.code.java.dataflow.FlowSources import PathsCommon class TaintedPathConfig extends TaintTracking::Configuration { TaintedPathConfig() { this = "TaintedPathConfig" } + override predicate isSource(DataFlow::Node source) { source instanceof RemoteUserInput } + override predicate isSink(DataFlow::Node sink) { exists(Expr e | e = sink.asExpr() | e = any(PathCreation p).getInput() and not guarded(e)) } + override predicate isSanitizer(DataFlow::Node node) { exists(Type t | t = node.getType() | t instanceof BoxedType or t instanceof PrimitiveType) } diff --git a/java/ql/src/Security/CWE/CWE-022/TaintedPathLocal.ql b/java/ql/src/Security/CWE/CWE-022/TaintedPathLocal.ql index 5d145fe1ed1..e1e6b3e53fc 100644 --- a/java/ql/src/Security/CWE/CWE-022/TaintedPathLocal.ql +++ b/java/ql/src/Security/CWE/CWE-022/TaintedPathLocal.ql @@ -11,13 +11,16 @@ * external/cwe/cwe-036 * external/cwe/cwe-073 */ + import java import semmle.code.java.dataflow.FlowSources import PathsCommon class TaintedPathLocalConfig extends TaintTracking::Configuration { TaintedPathLocalConfig() { this = "TaintedPathLocalConfig" } + override predicate isSource(DataFlow::Node source) { source instanceof LocalUserInput } + override predicate isSink(DataFlow::Node sink) { sink.asExpr() = any(PathCreation p).getInput() } } diff --git a/java/ql/src/Security/CWE/CWE-078/ExecRelative.ql b/java/ql/src/Security/CWE/CWE-078/ExecRelative.ql index 8c5305b8ee4..80cd9c0dee3 100644 --- a/java/ql/src/Security/CWE/CWE-078/ExecRelative.ql +++ b/java/ql/src/Security/CWE/CWE-078/ExecRelative.ql @@ -15,7 +15,6 @@ import semmle.code.java.Expr import semmle.code.java.security.RelativePaths import semmle.code.java.security.ExternalProcess - from ArgumentToExec argument, string command where ( diff --git a/java/ql/src/Security/CWE/CWE-078/ExecTaintedLocal.ql b/java/ql/src/Security/CWE/CWE-078/ExecTaintedLocal.ql index d8b72c698b7..bff0956b9da 100644 --- a/java/ql/src/Security/CWE/CWE-078/ExecTaintedLocal.ql +++ b/java/ql/src/Security/CWE/CWE-078/ExecTaintedLocal.ql @@ -17,11 +17,17 @@ import semmle.code.java.security.ExternalProcess class LocalUserInputToArgumentToExecFlowConfig extends TaintTracking::Configuration { LocalUserInputToArgumentToExecFlowConfig() { this = "LocalUserInputToArgumentToExecFlowConfig" } + override predicate isSource(DataFlow::Node src) { src instanceof LocalUserInput } + override predicate isSink(DataFlow::Node sink) { sink.asExpr() instanceof ArgumentToExec } - override predicate isSanitizer(DataFlow::Node node) { node.getType() instanceof PrimitiveType or node.getType() instanceof BoxedType } + + override predicate isSanitizer(DataFlow::Node node) { + node.getType() instanceof PrimitiveType or node.getType() instanceof BoxedType + } } -from StringArgumentToExec execArg, LocalUserInput origin, LocalUserInputToArgumentToExecFlowConfig conf +from + StringArgumentToExec execArg, LocalUserInput origin, LocalUserInputToArgumentToExecFlowConfig conf where conf.hasFlow(origin, DataFlow::exprNode(execArg)) select execArg, "$@ flows to here and is used in a command.", origin, "User-provided value" diff --git a/java/ql/src/Security/CWE/CWE-078/ExecUnescaped.ql b/java/ql/src/Security/CWE/CWE-078/ExecUnescaped.ql index d507ccdcc10..afc4fafe4dc 100644 --- a/java/ql/src/Security/CWE/CWE-078/ExecUnescaped.ql +++ b/java/ql/src/Security/CWE/CWE-078/ExecUnescaped.ql @@ -21,8 +21,10 @@ import ExecCommon * has in it. */ predicate saneString(Expr expr) { - expr instanceof StringLiteral or - expr instanceof NullLiteral or + expr instanceof StringLiteral + or + expr instanceof NullLiteral + or exists(Variable var | var.getAnAccess() = expr and exists(var.getAnAssignedValue()) | forall(Expr other | var.getAnAssignedValue() = other | saneString(other)) ) @@ -31,16 +33,17 @@ predicate saneString(Expr expr) { predicate builtFromUncontrolledConcat(Expr expr) { exists(AddExpr concatExpr | concatExpr = expr | builtFromUncontrolledConcat(concatExpr.getAnOperand()) - ) or + ) + or exists(AddExpr concatExpr | concatExpr = expr | exists(Expr arg | arg = concatExpr.getAnOperand() | not saneString(arg)) - ) or + ) + or exists(Expr other | builtFromUncontrolledConcat(other) | exists(Variable var | var.getAnAssignedValue() = other and var.getAnAccess() = expr) ) } - from StringArgumentToExec argument where builtFromUncontrolledConcat(argument) and diff --git a/java/ql/src/Security/CWE/CWE-079/XSS.ql b/java/ql/src/Security/CWE/CWE-079/XSS.ql index 73a30147b0d..75eaa38cb32 100644 --- a/java/ql/src/Security/CWE/CWE-079/XSS.ql +++ b/java/ql/src/Security/CWE/CWE-079/XSS.ql @@ -9,18 +9,23 @@ * @tags security * external/cwe/cwe-079 */ + import java import semmle.code.java.dataflow.FlowSources import semmle.code.java.security.XSS class XSSConfig extends TaintTracking::Configuration2 { XSSConfig() { this = "XSSConfig" } + override predicate isSource(DataFlow::Node source) { source instanceof RemoteUserInput } + override predicate isSink(DataFlow::Node sink) { sink instanceof XssSink } - override predicate isSanitizer(DataFlow::Node node) { node.getType() instanceof NumericType or node.getType() instanceof BooleanType } + + override predicate isSanitizer(DataFlow::Node node) { + node.getType() instanceof NumericType or node.getType() instanceof BooleanType + } } from XssSink sink, RemoteUserInput source, XSSConfig conf where conf.hasFlow(source, sink) -select sink, "Cross-site scripting vulnerability due to $@.", - source, "user-provided value" +select sink, "Cross-site scripting vulnerability due to $@.", source, "user-provided value" diff --git a/java/ql/src/Security/CWE/CWE-079/XSSLocal.ql b/java/ql/src/Security/CWE/CWE-079/XSSLocal.ql index f8607c710a0..58ac779bea8 100644 --- a/java/ql/src/Security/CWE/CWE-079/XSSLocal.ql +++ b/java/ql/src/Security/CWE/CWE-079/XSSLocal.ql @@ -9,17 +9,19 @@ * @tags security * external/cwe/cwe-079 */ + import java import semmle.code.java.dataflow.FlowSources import semmle.code.java.security.XSS class XSSLocalConfig extends TaintTracking::Configuration2 { XSSLocalConfig() { this = "XSSLocalConfig" } + override predicate isSource(DataFlow::Node source) { source instanceof LocalUserInput } + override predicate isSink(DataFlow::Node sink) { sink instanceof XssSink } } from XssSink sink, LocalUserInput source, XSSLocalConfig conf where conf.hasFlow(source, sink) -select sink, "Cross-site scripting vulnerability due to $@.", - source, "user-provided value" +select sink, "Cross-site scripting vulnerability due to $@.", source, "user-provided value" diff --git a/java/ql/src/Security/CWE/CWE-089/SqlTainted.ql b/java/ql/src/Security/CWE/CWE-089/SqlTainted.ql index 91b2489b1da..8ae4b466db8 100644 --- a/java/ql/src/Security/CWE/CWE-089/SqlTainted.ql +++ b/java/ql/src/Security/CWE/CWE-089/SqlTainted.ql @@ -14,8 +14,6 @@ import semmle.code.java.Expr import semmle.code.java.dataflow.FlowSources import SqlInjectionLib - from QueryInjectionSink query, RemoteUserInput source where queryTaintedBy(query, source) -select query, "Query might include code from $@.", - source, "this user input" +select query, "Query might include code from $@.", source, "this user input" diff --git a/java/ql/src/Security/CWE/CWE-089/SqlTaintedLocal.ql b/java/ql/src/Security/CWE/CWE-089/SqlTaintedLocal.ql index b0b9aaf1c7c..5a69e48d9a9 100644 --- a/java/ql/src/Security/CWE/CWE-089/SqlTaintedLocal.ql +++ b/java/ql/src/Security/CWE/CWE-089/SqlTaintedLocal.ql @@ -16,12 +16,16 @@ import SqlInjectionLib class LocalUserInputToQueryInjectionFlowConfig extends TaintTracking::Configuration { LocalUserInputToQueryInjectionFlowConfig() { this = "LocalUserInputToQueryInjectionFlowConfig" } + override predicate isSource(DataFlow::Node src) { src instanceof LocalUserInput } + override predicate isSink(DataFlow::Node sink) { sink instanceof QueryInjectionSink } - override predicate isSanitizer(DataFlow::Node node) { node.getType() instanceof PrimitiveType or node.getType() instanceof BoxedType } + + override predicate isSanitizer(DataFlow::Node node) { + node.getType() instanceof PrimitiveType or node.getType() instanceof BoxedType + } } from QueryInjectionSink query, LocalUserInput source, LocalUserInputToQueryInjectionFlowConfig conf where conf.hasFlow(source, query) -select query, "Query might include code from $@.", - source, "this user input" +select query, "Query might include code from $@.", source, "this user input" diff --git a/java/ql/src/Security/CWE/CWE-089/SqlUnescaped.ql b/java/ql/src/Security/CWE/CWE-089/SqlUnescaped.ql index 590ad365dff..a974725a2fb 100644 --- a/java/ql/src/Security/CWE/CWE-089/SqlUnescaped.ql +++ b/java/ql/src/Security/CWE/CWE-089/SqlUnescaped.ql @@ -23,22 +23,29 @@ class UncontrolledStringBuilderSource extends DataFlow::ExprNode { } class UncontrolledStringBuilderSourceFlowConfig extends TaintTracking::Configuration { - UncontrolledStringBuilderSourceFlowConfig() { this = "SqlUnescaped::UncontrolledStringBuilderSourceFlowConfig" } + UncontrolledStringBuilderSourceFlowConfig() { + this = "SqlUnescaped::UncontrolledStringBuilderSourceFlowConfig" + } + override predicate isSource(DataFlow::Node src) { src instanceof UncontrolledStringBuilderSource } + override predicate isSink(DataFlow::Node sink) { sink instanceof QueryInjectionSink } - override predicate isSanitizer(DataFlow::Node node) { node.getType() instanceof PrimitiveType or node.getType() instanceof BoxedType } + + override predicate isSanitizer(DataFlow::Node node) { + node.getType() instanceof PrimitiveType or node.getType() instanceof BoxedType + } } from QueryInjectionSink query, Expr uncontrolled where ( - builtFromUncontrolledConcat(query.getExpr(), uncontrolled) or + builtFromUncontrolledConcat(query.getExpr(), uncontrolled) + or exists(StringBuilderVar sbv, UncontrolledStringBuilderSourceFlowConfig conf | uncontrolledStringBuilderQuery(sbv, uncontrolled) and conf.hasFlow(DataFlow::exprNode(sbv.getToStringCall()), query) ) ) and not queryTaintedBy(query, _) -select - query, "Query might not neutralize special characters in $@.", - uncontrolled, "this expression" +select query, "Query might not neutralize special characters in $@.", uncontrolled, + "this expression" diff --git a/java/ql/src/Security/CWE/CWE-113/ResponseSplitting.ql b/java/ql/src/Security/CWE/CWE-113/ResponseSplitting.ql index 9d4a51f1f3a..d6a6f74dcbf 100644 --- a/java/ql/src/Security/CWE/CWE-113/ResponseSplitting.ql +++ b/java/ql/src/Security/CWE/CWE-113/ResponseSplitting.ql @@ -9,19 +9,21 @@ * @tags security * external/cwe/cwe-113 */ + import java import ResponseSplitting class ResponseSplittingConfig extends TaintTracking::Configuration { ResponseSplittingConfig() { this = "ResponseSplittingConfig" } + override predicate isSource(DataFlow::Node source) { source instanceof RemoteUserInput and not source instanceof WhitelistedSource } + override predicate isSink(DataFlow::Node sink) { sink instanceof HeaderSplittingSink } } from HeaderSplittingSink sink, RemoteUserInput source, ResponseSplittingConfig conf where conf.hasFlow(source, sink) -select sink, "Response-splitting vulnerability due to this $@.", - source, "user-provided value" +select sink, "Response-splitting vulnerability due to this $@.", source, "user-provided value" diff --git a/java/ql/src/Security/CWE/CWE-113/ResponseSplittingLocal.ql b/java/ql/src/Security/CWE/CWE-113/ResponseSplittingLocal.ql index 55ee289afbe..a3205298190 100644 --- a/java/ql/src/Security/CWE/CWE-113/ResponseSplittingLocal.ql +++ b/java/ql/src/Security/CWE/CWE-113/ResponseSplittingLocal.ql @@ -9,17 +9,19 @@ * @tags security * external/cwe/cwe-113 */ + import java import semmle.code.java.dataflow.FlowSources import ResponseSplitting class ResponseSplittingLocalConfig extends TaintTracking::Configuration { ResponseSplittingLocalConfig() { this = "ResponseSplittingLocalConfig" } + override predicate isSource(DataFlow::Node source) { source instanceof LocalUserInput } + override predicate isSink(DataFlow::Node sink) { sink instanceof HeaderSplittingSink } } from HeaderSplittingSink sink, LocalUserInput source, ResponseSplittingLocalConfig conf where conf.hasFlow(source, sink) -select sink, "Response-splitting vulnerability due to this $@.", - source, "user-provided value" +select sink, "Response-splitting vulnerability due to this $@.", source, "user-provided value" diff --git a/java/ql/src/Security/CWE/CWE-129/ImproperValidationOfArrayConstruction.ql b/java/ql/src/Security/CWE/CWE-129/ImproperValidationOfArrayConstruction.ql index 90879bcfb1c..6589d4e60db 100644 --- a/java/ql/src/Security/CWE/CWE-129/ImproperValidationOfArrayConstruction.ql +++ b/java/ql/src/Security/CWE/CWE-129/ImproperValidationOfArrayConstruction.ql @@ -15,17 +15,20 @@ import semmle.code.java.dataflow.FlowSources class Conf extends TaintTracking::Configuration { Conf() { this = "RemoteUserInputTocanThrowOutOfBoundsDueToEmptyArrayConfig" } + override predicate isSource(DataFlow::Node source) { source instanceof RemoteUserInput } + override predicate isSink(DataFlow::Node sink) { any(CheckableArrayAccess caa).canThrowOutOfBoundsDueToEmptyArray(sink.asExpr(), _) } } -from RemoteUserInput source, Expr sizeExpr, ArrayCreationExpr arrayCreation, CheckableArrayAccess arrayAccess +from + RemoteUserInput source, Expr sizeExpr, ArrayCreationExpr arrayCreation, + CheckableArrayAccess arrayAccess where arrayAccess.canThrowOutOfBoundsDueToEmptyArray(sizeExpr, arrayCreation) and any(Conf conf).hasFlow(source, DataFlow::exprNode(sizeExpr)) select arrayAccess.getIndexExpr(), "The $@ is accessed here, but the array is initialized using $@ which may be zero.", - arrayCreation, "array", - source, "User-provided value" + arrayCreation, "array", source, "User-provided value" diff --git a/java/ql/src/Security/CWE/CWE-129/ImproperValidationOfArrayConstructionCodeSpecified.ql b/java/ql/src/Security/CWE/CWE-129/ImproperValidationOfArrayConstructionCodeSpecified.ql index 45f058e4af2..8eee3e41c3b 100644 --- a/java/ql/src/Security/CWE/CWE-129/ImproperValidationOfArrayConstructionCodeSpecified.ql +++ b/java/ql/src/Security/CWE/CWE-129/ImproperValidationOfArrayConstructionCodeSpecified.ql @@ -15,21 +15,24 @@ import ArraySizing class BoundedFlowSourceConf extends DataFlow::Configuration { BoundedFlowSourceConf() { this = "BoundedFlowSource" } + override predicate isSource(DataFlow::Node source) { source instanceof BoundedFlowSource and // There is not a fixed lower bound which is greater than zero. not source.(BoundedFlowSource).lowerBound() > 0 } + override predicate isSink(DataFlow::Node sink) { any(CheckableArrayAccess caa).canThrowOutOfBoundsDueToEmptyArray(sink.asExpr(), _) } } -from BoundedFlowSource source, Expr sizeExpr, ArrayCreationExpr arrayCreation, CheckableArrayAccess arrayAccess +from + BoundedFlowSource source, Expr sizeExpr, ArrayCreationExpr arrayCreation, + CheckableArrayAccess arrayAccess where arrayAccess.canThrowOutOfBoundsDueToEmptyArray(sizeExpr, arrayCreation) and any(BoundedFlowSourceConf conf).hasFlow(source, DataFlow::exprNode(sizeExpr)) select arrayAccess.getIndexExpr(), "The $@ is accessed here, but the array is initialized using $@ which may be zero.", - arrayCreation, "array", - source, source.getDescription().toLowerCase() + arrayCreation, "array", source, source.getDescription().toLowerCase() diff --git a/java/ql/src/Security/CWE/CWE-129/ImproperValidationOfArrayConstructionLocal.ql b/java/ql/src/Security/CWE/CWE-129/ImproperValidationOfArrayConstructionLocal.ql index 9477ab0738c..c182ca0eeeb 100644 --- a/java/ql/src/Security/CWE/CWE-129/ImproperValidationOfArrayConstructionLocal.ql +++ b/java/ql/src/Security/CWE/CWE-129/ImproperValidationOfArrayConstructionLocal.ql @@ -16,17 +16,20 @@ import semmle.code.java.dataflow.FlowSources class Conf extends TaintTracking::Configuration { Conf() { this = "LocalUserInputTocanThrowOutOfBoundsDueToEmptyArrayConfig" } + override predicate isSource(DataFlow::Node source) { source instanceof LocalUserInput } + override predicate isSink(DataFlow::Node sink) { any(CheckableArrayAccess caa).canThrowOutOfBoundsDueToEmptyArray(sink.asExpr(), _) } } -from LocalUserInput source, Expr sizeExpr, ArrayCreationExpr arrayCreation, CheckableArrayAccess arrayAccess +from + LocalUserInput source, Expr sizeExpr, ArrayCreationExpr arrayCreation, + CheckableArrayAccess arrayAccess where arrayAccess.canThrowOutOfBoundsDueToEmptyArray(sizeExpr, arrayCreation) and any(Conf conf).hasFlow(source, DataFlow::exprNode(sizeExpr)) select arrayAccess.getIndexExpr(), "The $@ is accessed here, but the array is initialized using $@ which may be zero.", - arrayCreation, "array", - source, "User-provided value" + arrayCreation, "array", source, "User-provided value" diff --git a/java/ql/src/Security/CWE/CWE-129/ImproperValidationOfArrayIndex.ql b/java/ql/src/Security/CWE/CWE-129/ImproperValidationOfArrayIndex.ql index da9c0a243ff..e81181d8c4f 100644 --- a/java/ql/src/Security/CWE/CWE-129/ImproperValidationOfArrayIndex.ql +++ b/java/ql/src/Security/CWE/CWE-129/ImproperValidationOfArrayIndex.ql @@ -15,10 +15,13 @@ import semmle.code.java.dataflow.FlowSources class Conf extends TaintTracking::Configuration { Conf() { this = "RemoteUserInputTocanThrowOutOfBoundsDueToEmptyArrayConfig" } + override predicate isSource(DataFlow::Node source) { source instanceof RemoteUserInput } + override predicate isSink(DataFlow::Node sink) { any(CheckableArrayAccess caa).canThrowOutOfBounds(sink.asExpr()) } + override predicate isSanitizer(DataFlow::Node node) { node.getType() instanceof BooleanType } } @@ -27,5 +30,5 @@ where arrayAccess.canThrowOutOfBounds(index) and any(Conf conf).hasFlow(source, DataFlow::exprNode(index)) select arrayAccess.getIndexExpr(), - "$@ flows to here and is used as an index causing an ArrayIndexOutOfBoundsException.", - source, "User-provided value" + "$@ flows to here and is used as an index causing an ArrayIndexOutOfBoundsException.", source, + "User-provided value" diff --git a/java/ql/src/Security/CWE/CWE-129/ImproperValidationOfArrayIndexCodeSpecified.ql b/java/ql/src/Security/CWE/CWE-129/ImproperValidationOfArrayIndexCodeSpecified.ql index e079aef2413..5df7b61cc8a 100644 --- a/java/ql/src/Security/CWE/CWE-129/ImproperValidationOfArrayIndexCodeSpecified.ql +++ b/java/ql/src/Security/CWE/CWE-129/ImproperValidationOfArrayIndexCodeSpecified.ql @@ -16,13 +16,11 @@ import BoundingChecks class BoundedFlowSourceConf extends DataFlow::Configuration { BoundedFlowSourceConf() { this = "BoundedFlowSource" } - override predicate isSource(DataFlow::Node source) { - source instanceof BoundedFlowSource - } + + override predicate isSource(DataFlow::Node source) { source instanceof BoundedFlowSource } + override predicate isSink(DataFlow::Node sink) { - exists(CheckableArrayAccess arrayAccess | - arrayAccess.canThrowOutOfBounds(sink.asExpr()) - ) + exists(CheckableArrayAccess arrayAccess | arrayAccess.canThrowOutOfBounds(sink.asExpr())) } } @@ -31,27 +29,26 @@ where arrayAccess.canThrowOutOfBounds(index) and any(BoundedFlowSourceConf conf).hasFlow(source, DataFlow::exprNode(index)) and source != DataFlow::exprNode(index) and - not ( - ( - // The input has a lower bound. - source.lowerBound() >= 0 or - // There is a condition dominating this expression ensuring that the index is >= 0. - lowerBound(arrayAccess.getIndexExpr()) >= 0 - ) - and - ( - // The input has an upper bound, and the array has a fixed size, and that fixed size is less. - source.upperBound() < fixedArraySize(arrayAccess) or - // There is a condition dominating this expression that ensures the index is less than the length. - lessthanLength(arrayAccess) - ) + not ( + ( + // The input has a lower bound. + source.lowerBound() >= 0 or + // There is a condition dominating this expression ensuring that the index is >= 0. + lowerBound(arrayAccess.getIndexExpr()) >= 0 + ) and + ( + // The input has an upper bound, and the array has a fixed size, and that fixed size is less. + source.upperBound() < fixedArraySize(arrayAccess) or + // There is a condition dominating this expression that ensures the index is less than the length. + lessthanLength(arrayAccess) ) - and + ) and /* * Exclude cases where the array is assigned multiple times. The checks for bounded flow sources * can use fixed sizes for arrays, but this doesn't work well when the array is initialized to zero * and subsequently reassigned or grown. */ + count(arrayAccess.getArray().(VarAccess).getVariable().getAnAssignedValue()) = 1 select arrayAccess.getIndexExpr(), "$@ flows to the index used in this array access, and may cause the operation to throw an ArrayIndexOutOfBoundsException.", diff --git a/java/ql/src/Security/CWE/CWE-129/ImproperValidationOfArrayIndexLocal.ql b/java/ql/src/Security/CWE/CWE-129/ImproperValidationOfArrayIndexLocal.ql index 00a04b930e6..df597703191 100644 --- a/java/ql/src/Security/CWE/CWE-129/ImproperValidationOfArrayIndexLocal.ql +++ b/java/ql/src/Security/CWE/CWE-129/ImproperValidationOfArrayIndexLocal.ql @@ -16,7 +16,9 @@ import semmle.code.java.dataflow.FlowSources class Conf extends TaintTracking::Configuration { Conf() { this = "LocalUserInputTocanThrowOutOfBoundsDueToEmptyArrayConfig" } + override predicate isSource(DataFlow::Node source) { source instanceof LocalUserInput } + override predicate isSink(DataFlow::Node sink) { any(CheckableArrayAccess caa).canThrowOutOfBounds(sink.asExpr()) } @@ -27,5 +29,5 @@ where arrayAccess.canThrowOutOfBounds(index) and any(Conf conf).hasFlow(source, DataFlow::exprNode(index)) select arrayAccess.getIndexExpr(), - "$@ flows to here and is used as an index causing an ArrayIndexOutOfBoundsException.", - source, "User-provided value" + "$@ flows to here and is used as an index causing an ArrayIndexOutOfBoundsException.", source, + "User-provided value" diff --git a/java/ql/src/Security/CWE/CWE-134/ExternallyControlledFormatString.ql b/java/ql/src/Security/CWE/CWE-134/ExternallyControlledFormatString.ql index e4999133413..06d680854af 100644 --- a/java/ql/src/Security/CWE/CWE-134/ExternallyControlledFormatString.ql +++ b/java/ql/src/Security/CWE/CWE-134/ExternallyControlledFormatString.ql @@ -15,14 +15,19 @@ import semmle.code.java.StringFormat class ExternallyControlledFormatStringConfig extends TaintTracking::Configuration { ExternallyControlledFormatStringConfig() { this = "ExternallyControlledFormatStringConfig" } + override predicate isSource(DataFlow::Node source) { source instanceof RemoteUserInput } - override predicate isSink(DataFlow::Node sink) { sink.asExpr() = any(StringFormat formatCall).getFormatArgument() } - override predicate isSanitizer(DataFlow::Node node) { node.getType() instanceof NumericType or node.getType() instanceof BooleanType } + + override predicate isSink(DataFlow::Node sink) { + sink.asExpr() = any(StringFormat formatCall).getFormatArgument() + } + + override predicate isSanitizer(DataFlow::Node node) { + node.getType() instanceof NumericType or node.getType() instanceof BooleanType + } } from RemoteUserInput source, StringFormat formatCall, ExternallyControlledFormatStringConfig conf -where - conf.hasFlow(source, DataFlow::exprNode(formatCall.getFormatArgument())) -select formatCall.getFormatArgument(), - "$@ flows to here and is used in a format string.", - source, "User-provided value" +where conf.hasFlow(source, DataFlow::exprNode(formatCall.getFormatArgument())) +select formatCall.getFormatArgument(), "$@ flows to here and is used in a format string.", source, + "User-provided value" diff --git a/java/ql/src/Security/CWE/CWE-134/ExternallyControlledFormatStringLocal.ql b/java/ql/src/Security/CWE/CWE-134/ExternallyControlledFormatStringLocal.ql index 7e5d8704526..72f2c4e4bd7 100644 --- a/java/ql/src/Security/CWE/CWE-134/ExternallyControlledFormatStringLocal.ql +++ b/java/ql/src/Security/CWE/CWE-134/ExternallyControlledFormatStringLocal.ql @@ -12,16 +12,23 @@ import java import semmle.code.java.dataflow.FlowSources import semmle.code.java.StringFormat - import DataFlow::PathGraph class ExternallyControlledFormatStringLocalConfig extends TaintTracking::Configuration { - ExternallyControlledFormatStringLocalConfig() { this = "ExternallyControlledFormatStringLocalConfig" } + ExternallyControlledFormatStringLocalConfig() { + this = "ExternallyControlledFormatStringLocalConfig" + } + override predicate isSource(DataFlow::Node source) { source instanceof LocalUserInput } - override predicate isSink(DataFlow::Node sink) { sink.asExpr() = any(StringFormat formatCall).getFormatArgument() } + + override predicate isSink(DataFlow::Node sink) { + sink.asExpr() = any(StringFormat formatCall).getFormatArgument() + } } -from DataFlow::PathNode source, DataFlow::PathNode sink, StringFormat formatCall, ExternallyControlledFormatStringLocalConfig conf +from + DataFlow::PathNode source, DataFlow::PathNode sink, StringFormat formatCall, + ExternallyControlledFormatStringLocalConfig conf where conf.hasFlowPath(source, sink) and sink.getNode().asExpr() = formatCall.getFormatArgument() -select formatCall.getFormatArgument(), source, sink, "$@ flows to here and is used in a format string.", - source.getNode(), "User-provided value" +select formatCall.getFormatArgument(), source, sink, + "$@ flows to here and is used in a format string.", source.getNode(), "User-provided value" diff --git a/java/ql/src/Security/CWE/CWE-190/ArithmeticTainted.ql b/java/ql/src/Security/CWE/CWE-190/ArithmeticTainted.ql index bf65cf9c3f2..4fa8cc9e6b0 100644 --- a/java/ql/src/Security/CWE/CWE-190/ArithmeticTainted.ql +++ b/java/ql/src/Security/CWE/CWE-190/ArithmeticTainted.ql @@ -10,6 +10,7 @@ * external/cwe/cwe-190 * external/cwe/cwe-191 */ + import java import semmle.code.java.dataflow.FlowSources import ArithmeticCommon @@ -17,7 +18,8 @@ import ArithmeticCommon predicate sink(ArithExpr exp, VarAccess tainted, string effect) { exp.getAnOperand() = tainted and ( - not guardedAgainstUnderflow(exp, tainted) and effect = "underflow" or + not guardedAgainstUnderflow(exp, tainted) and effect = "underflow" + or not guardedAgainstOverflow(exp, tainted) and effect = "overflow" ) and // Exclude widening conversions of tainted values due to binary numeric promotion (JLS 5.6.2) @@ -28,12 +30,17 @@ predicate sink(ArithExpr exp, VarAccess tainted, string effect) { class RemoteUserInputConfig extends TaintTracking::Configuration { RemoteUserInputConfig() { this = "ArithmeticTainted.ql:RemoteUserInputConfig" } + override predicate isSource(DataFlow::Node source) { source instanceof RemoteUserInput } + override predicate isSink(DataFlow::Node sink) { sink(_, sink.asExpr(), _) } + override predicate isSanitizer(DataFlow::Node n) { n.getType() instanceof BooleanType } } -from ArithExpr exp, VarAccess tainted, RemoteUserInput origin, string effect, RemoteUserInputConfig conf +from + ArithExpr exp, VarAccess tainted, RemoteUserInput origin, string effect, + RemoteUserInputConfig conf where conf.hasFlow(origin, DataFlow::exprNode(tainted)) and sink(exp, tainted, effect) diff --git a/java/ql/src/Security/CWE/CWE-190/ArithmeticTaintedLocal.ql b/java/ql/src/Security/CWE/CWE-190/ArithmeticTaintedLocal.ql index fc4ab7c7f27..f4658b9ed14 100644 --- a/java/ql/src/Security/CWE/CWE-190/ArithmeticTaintedLocal.ql +++ b/java/ql/src/Security/CWE/CWE-190/ArithmeticTaintedLocal.ql @@ -10,6 +10,7 @@ * external/cwe/cwe-190 * external/cwe/cwe-191 */ + import java import semmle.code.java.dataflow.FlowSources import ArithmeticCommon @@ -17,7 +18,8 @@ import ArithmeticCommon predicate sink(ArithExpr exp, VarAccess tainted, string effect) { exp.getAnOperand() = tainted and ( - not guardedAgainstUnderflow(exp, tainted) and effect = "underflow" or + not guardedAgainstUnderflow(exp, tainted) and effect = "underflow" + or not guardedAgainstOverflow(exp, tainted) and effect = "overflow" ) and // Exclude widening conversions of tainted values due to binary numeric promotion (JLS 5.6.2) @@ -28,8 +30,11 @@ predicate sink(ArithExpr exp, VarAccess tainted, string effect) { class ArithmeticTaintedLocalFlowConfig extends TaintTracking::Configuration { ArithmeticTaintedLocalFlowConfig() { this = "ArithmeticTaintedLocalFlowConfig" } + override predicate isSource(DataFlow::Node source) { source instanceof LocalUserInput } + override predicate isSink(DataFlow::Node sink) { sink(_, sink.asExpr(), _) } + override predicate isSanitizer(DataFlow::Node n) { n.getType() instanceof BooleanType } } diff --git a/java/ql/src/Security/CWE/CWE-190/ArithmeticUncontrolled.ql b/java/ql/src/Security/CWE/CWE-190/ArithmeticUncontrolled.ql index da6f0ae1bec..b91bc892134 100644 --- a/java/ql/src/Security/CWE/CWE-190/ArithmeticUncontrolled.ql +++ b/java/ql/src/Security/CWE/CWE-190/ArithmeticUncontrolled.ql @@ -10,6 +10,7 @@ * external/cwe/cwe-190 * external/cwe/cwe-191 */ + import java import semmle.code.java.dataflow.TaintTracking import semmle.code.java.security.SecurityTests @@ -29,7 +30,8 @@ class TaintSource extends DataFlow::ExprNode { ) and def.getNumberOfParameters() = 0 and def.getDeclaringType().hasQualifiedName("java.util", "Random") - ) or + ) + or // ... or this is the array parameter of `nextBytes`, which is filled with random bytes. exists(MethodAccess m, Method def | m.getAnArgument() = this.getExpr() and @@ -44,7 +46,8 @@ class TaintSource extends DataFlow::ExprNode { predicate sink(ArithExpr exp, VarAccess tainted, string effect) { exp.getAnOperand() = tainted and ( - not guardedAgainstUnderflow(exp, tainted) and effect = "underflow" or + not guardedAgainstUnderflow(exp, tainted) and effect = "underflow" + or not guardedAgainstOverflow(exp, tainted) and effect = "overflow" ) and // Exclude widening conversions of tainted values due to binary numeric promotion (JLS 5.6.2) @@ -56,12 +59,17 @@ predicate sink(ArithExpr exp, VarAccess tainted, string effect) { class ArithmeticUncontrolledFlowConfig extends TaintTracking::Configuration { ArithmeticUncontrolledFlowConfig() { this = "ArithmeticUncontrolledFlowConfig" } + override predicate isSource(DataFlow::Node source) { source instanceof TaintSource } + override predicate isSink(DataFlow::Node sink) { sink(_, sink.asExpr(), _) } + override predicate isSanitizer(DataFlow::Node n) { n.getType() instanceof BooleanType } } -from ArithExpr exp, VarAccess tainted, TaintSource origin, string effect, ArithmeticUncontrolledFlowConfig conf +from + ArithExpr exp, VarAccess tainted, TaintSource origin, string effect, + ArithmeticUncontrolledFlowConfig conf where conf.hasFlow(origin, DataFlow::exprNode(tainted)) and sink(exp, tainted, effect) diff --git a/java/ql/src/Security/CWE/CWE-190/ArithmeticWithExtremeValues.ql b/java/ql/src/Security/CWE/CWE-190/ArithmeticWithExtremeValues.ql index d643bfdabc8..e418b107918 100644 --- a/java/ql/src/Security/CWE/CWE-190/ArithmeticWithExtremeValues.ql +++ b/java/ql/src/Security/CWE/CWE-190/ArithmeticWithExtremeValues.ql @@ -11,41 +11,34 @@ * external/cwe/cwe-190 * external/cwe/cwe-191 */ + import java import semmle.code.java.dataflow.DataFlow import ArithmeticCommon abstract class ExtremeValueField extends Field { - ExtremeValueField() { - getType() instanceof IntegralType - } + ExtremeValueField() { getType() instanceof IntegralType } } -class MinValueField extends ExtremeValueField { - MinValueField() { - this.getName() = "MIN_VALUE" - } -} +class MinValueField extends ExtremeValueField { MinValueField() { this.getName() = "MIN_VALUE" } } -class MaxValueField extends ExtremeValueField { - MaxValueField() { - this.getName() = "MAX_VALUE" - } -} +class MaxValueField extends ExtremeValueField { MaxValueField() { this.getName() = "MAX_VALUE" } } class ExtremeSource extends VarAccess { - ExtremeSource() { - this.getVariable() instanceof ExtremeValueField - } + ExtremeSource() { this.getVariable() instanceof ExtremeValueField } } class ExtremeSourceFlowConfig extends DataFlow::Configuration { ExtremeSourceFlowConfig() { this = "ExtremeSourceFlowConfig" } + override predicate isSource(DataFlow::Node source) { source.asExpr() instanceof ExtremeSource } + override predicate isSink(DataFlow::Node sink) { sink(_, sink.asExpr()) } + override predicate isBarrierEdge(DataFlow::Node node1, DataFlow::Node node2) { isSource(node1) and isSource(node2) } + override predicate isBarrier(DataFlow::Node n) { n.getType() instanceof BooleanType } } @@ -59,7 +52,9 @@ predicate sink(ArithExpr exp, VarAccess use) { not exp instanceof DivExpr } -predicate query(ArithExpr exp, Variable v, ExtremeValueField f, VarAccess use, ExtremeSource s, Type t) { +predicate query( + ArithExpr exp, Variable v, ExtremeValueField f, VarAccess use, ExtremeSource s, Type t +) { // `use` is the use of `v` in `exp`. use = exp.getAnOperand() and use = v.getAnAccess() and @@ -71,17 +66,21 @@ predicate query(ArithExpr exp, Variable v, ExtremeValueField f, VarAccess use, E not exp instanceof DivExpr } -from ArithExpr exp, Variable v, ExtremeValueField f, VarAccess use, ExtremeSource s, string effect, Type t +from + ArithExpr exp, Variable v, ExtremeValueField f, VarAccess use, ExtremeSource s, string effect, + Type t where query(exp, v, f, use, s, t) and // We're not guarded against the appropriate kind of flow error. ( - f instanceof MinValueField and not guardedAgainstUnderflow(exp, use) and effect = "underflow" or + f instanceof MinValueField and not guardedAgainstUnderflow(exp, use) and effect = "underflow" + or f instanceof MaxValueField and not guardedAgainstOverflow(exp, use) and effect = "overflow" ) and // Exclude widening conversions of extreme values due to binary numeric promotion (JLS 5.6.2) // unless there is an enclosing cast down to a narrower type. narrowerThanOrEqualTo(exp, t) and not overflowIrrelevant(exp) -select exp, "Variable " + v.getName() + " is assigned an extreme value $@, and may cause an " + effect + ".", +select exp, + "Variable " + v.getName() + " is assigned an extreme value $@, and may cause an " + effect + ".", s, f.getName() diff --git a/java/ql/src/Security/CWE/CWE-190/ComparisonWithWiderType.ql b/java/ql/src/Security/CWE/CWE-190/ComparisonWithWiderType.ql index 1dc9e5a7a84..03138948178 100644 --- a/java/ql/src/Security/CWE/CWE-190/ComparisonWithWiderType.ql +++ b/java/ql/src/Security/CWE/CWE-190/ComparisonWithWiderType.ql @@ -11,22 +11,19 @@ * external/cwe/cwe-190 * external/cwe/cwe-197 */ + import java import semmle.code.java.arithmetic.Overflow -int leftWidth(ComparisonExpr e) { - result = e.getLeftOperand().getType().(NumType).getWidthRank() -} +int leftWidth(ComparisonExpr e) { result = e.getLeftOperand().getType().(NumType).getWidthRank() } -int rightWidth(ComparisonExpr e) { - result = e.getRightOperand().getType().(NumType).getWidthRank() -} +int rightWidth(ComparisonExpr e) { result = e.getRightOperand().getType().(NumType).getWidthRank() } abstract class WideningComparison extends BinaryExpr { - WideningComparison() { - this instanceof ComparisonExpr - } + WideningComparison() { this instanceof ComparisonExpr } + abstract Expr getNarrower(); + abstract Expr getWider(); } @@ -36,13 +33,9 @@ class LTWideningComparison extends WideningComparison { leftWidth(this) < rightWidth(this) } - override Expr getNarrower() { - result = getLeftOperand() - } + override Expr getNarrower() { result = getLeftOperand() } - override Expr getWider() { - result = getRightOperand() - } + override Expr getWider() { result = getRightOperand() } } class GTWideningComparison extends WideningComparison { @@ -51,20 +44,16 @@ class GTWideningComparison extends WideningComparison { leftWidth(this) > rightWidth(this) } - override Expr getNarrower() { - result = getRightOperand() - } + override Expr getNarrower() { result = getRightOperand() } - override Expr getWider() { - result = getLeftOperand() - } + override Expr getWider() { result = getLeftOperand() } } from WideningComparison c, LoopStmt l where not c.getAnOperand().isCompileTimeConstant() and l.getCondition().getAChildExpr*() = c -select c, "Comparison between $@ of type " + c.getNarrower().getType().getName() + - " and $@ of wider type " + c.getWider().getType().getName() + ".", - c.getNarrower(), "expression", - c.getWider(), "expression" +select c, + "Comparison between $@ of type " + c.getNarrower().getType().getName() + " and $@ of wider type " + + c.getWider().getType().getName() + ".", c.getNarrower(), "expression", c.getWider(), + "expression" diff --git a/java/ql/src/Security/CWE/CWE-209/StackTraceExposure.ql b/java/ql/src/Security/CWE/CWE-209/StackTraceExposure.ql index 81a47072da5..87153e48244 100644 --- a/java/ql/src/Security/CWE/CWE-209/StackTraceExposure.ql +++ b/java/ql/src/Security/CWE/CWE-209/StackTraceExposure.ql @@ -27,9 +27,17 @@ class PrintStackTraceMethod extends Method { } class ServletWriterSourceToPrintStackTraceMethodFlowConfig extends TaintTracking::Configuration { - ServletWriterSourceToPrintStackTraceMethodFlowConfig() { this = "StackTraceExposure::ServletWriterSourceToPrintStackTraceMethodFlowConfig" } + ServletWriterSourceToPrintStackTraceMethodFlowConfig() { + this = "StackTraceExposure::ServletWriterSourceToPrintStackTraceMethodFlowConfig" + } + override predicate isSource(DataFlow::Node src) { src.asExpr() instanceof ServletWriterSource } - override predicate isSink(DataFlow::Node sink) { exists(MethodAccess ma | sink.asExpr() = ma.getAnArgument() and ma.getMethod() instanceof PrintStackTraceMethod) } + + override predicate isSink(DataFlow::Node sink) { + exists(MethodAccess ma | + sink.asExpr() = ma.getAnArgument() and ma.getMethod() instanceof PrintStackTraceMethod + ) + } } /** @@ -37,7 +45,10 @@ class ServletWriterSourceToPrintStackTraceMethodFlowConfig extends TaintTracking * to external output. */ predicate printsStackToWriter(MethodAccess call) { - exists(ServletWriterSourceToPrintStackTraceMethodFlowConfig writerSource, PrintStackTraceMethod printStackTrace | + exists( + ServletWriterSourceToPrintStackTraceMethodFlowConfig writerSource, + PrintStackTraceMethod printStackTrace + | call.getMethod() = printStackTrace and writerSource.hasFlowToExpr(call.getAnArgument()) ) @@ -49,9 +60,11 @@ predicate printsStackToWriter(MethodAccess call) { */ predicate printWriterOnStringWriter(Expr printWriter, Variable stringWriterVar) { printWriter.getType().(Class).hasQualifiedName("java.io", "PrintWriter") and - stringWriterVar.getType().(Class).hasQualifiedName("java.io", "StringWriter") and ( + stringWriterVar.getType().(Class).hasQualifiedName("java.io", "StringWriter") and + ( printWriter.(ClassInstanceExpr).getAnArgument() = stringWriterVar.getAnAccess() or - printWriterOnStringWriter(printWriter.(VarAccess).getVariable().getInitializer(), stringWriterVar) + printWriterOnStringWriter(printWriter.(VarAccess).getVariable().getInitializer(), + stringWriterVar) ) } @@ -68,8 +81,12 @@ predicate stackTraceExpr(Expr exception, MethodAccess stackTraceString) { } class StackTraceStringToXssSinkFlowConfig extends TaintTracking::Configuration2 { - StackTraceStringToXssSinkFlowConfig() { this = "StackTraceExposure::StackTraceStringToXssSinkFlowConfig" } + StackTraceStringToXssSinkFlowConfig() { + this = "StackTraceExposure::StackTraceStringToXssSinkFlowConfig" + } + override predicate isSource(DataFlow::Node src) { stackTraceExpr(_, src.asExpr()) } + override predicate isSink(DataFlow::Node sink) { sink instanceof XssSink } } @@ -103,8 +120,12 @@ class GetMessageFlowSource extends MethodAccess { } class GetMessageFlowSourceToXssSinkFlowConfig extends TaintTracking::Configuration2 { - GetMessageFlowSourceToXssSinkFlowConfig() { this = "StackTraceExposure::GetMessageFlowSourceToXssSinkFlowConfig" } + GetMessageFlowSourceToXssSinkFlowConfig() { + this = "StackTraceExposure::GetMessageFlowSourceToXssSinkFlowConfig" + } + override predicate isSource(DataFlow::Node src) { src.asExpr() instanceof GetMessageFlowSource } + override predicate isSink(DataFlow::Node sink) { sink instanceof XssSink } } @@ -112,7 +133,8 @@ class GetMessageFlowSourceToXssSinkFlowConfig extends TaintTracking::Configurati * A call to `getMessage()` that then flows to a servlet response. */ predicate getMessageFlowsExternally(XssSink externalExpr, GetMessageFlowSource getMessage) { - any(GetMessageFlowSourceToXssSinkFlowConfig conf).hasFlow(DataFlow::exprNode(getMessage), externalExpr) + any(GetMessageFlowSourceToXssSinkFlowConfig conf) + .hasFlow(DataFlow::exprNode(getMessage), externalExpr) } from Expr externalExpr, Expr errorInformation @@ -120,6 +142,4 @@ where printsStackExternally(externalExpr, errorInformation) or stringifiedStackFlowsExternally(DataFlow::exprNode(externalExpr), errorInformation) or getMessageFlowsExternally(DataFlow::exprNode(externalExpr), errorInformation) -select - externalExpr, "$@ can be exposed to an external user.", - errorInformation, "Error information" +select externalExpr, "$@ can be exposed to an external user.", errorInformation, "Error information" diff --git a/java/ql/src/Security/CWE/CWE-312/CleartextStorageClass.ql b/java/ql/src/Security/CWE/CWE-312/CleartextStorageClass.ql index fc5180e6000..41919152c6a 100644 --- a/java/ql/src/Security/CWE/CWE-312/CleartextStorageClass.ql +++ b/java/ql/src/Security/CWE/CWE-312/CleartextStorageClass.ql @@ -9,6 +9,7 @@ * external/cwe/cwe-499 * external/cwe/cwe-312 */ + import java import SensitiveStorage @@ -20,7 +21,5 @@ where // Exclude results in test code. not testMethod(store.getEnclosingCallable()) and not testMethod(data.getEnclosingCallable()) -select store, "Storable class $@ containing $@ is stored here. Data was added $@.", - s, s.toString(), - data, "sensitive data", - input, "here" +select store, "Storable class $@ containing $@ is stored here. Data was added $@.", s, s.toString(), + data, "sensitive data", input, "here" diff --git a/java/ql/src/Security/CWE/CWE-312/CleartextStorageCookie.ql b/java/ql/src/Security/CWE/CWE-312/CleartextStorageCookie.ql index 7f5adfe8ca7..60d5a246979 100644 --- a/java/ql/src/Security/CWE/CWE-312/CleartextStorageCookie.ql +++ b/java/ql/src/Security/CWE/CWE-312/CleartextStorageCookie.ql @@ -8,6 +8,7 @@ * @tags security * external/cwe/cwe-315 */ + import java import SensitiveStorage @@ -19,7 +20,5 @@ where // Exclude results in test code. not testMethod(store.getEnclosingCallable()) and not testMethod(data.getEnclosingCallable()) -select store, "Cookie $@ containing $@ is stored here. Data was added $@.", - s, s.toString(), - data, "sensitive data", - input, "here" +select store, "Cookie $@ containing $@ is stored here. Data was added $@.", s, s.toString(), data, + "sensitive data", input, "here" diff --git a/java/ql/src/Security/CWE/CWE-312/CleartextStorageProperties.ql b/java/ql/src/Security/CWE/CWE-312/CleartextStorageProperties.ql index 1246ddbf7e7..7a9626f94dd 100644 --- a/java/ql/src/Security/CWE/CWE-312/CleartextStorageProperties.ql +++ b/java/ql/src/Security/CWE/CWE-312/CleartextStorageProperties.ql @@ -8,6 +8,7 @@ * @tags security * external/cwe/cwe-313 */ + import java import SensitiveStorage @@ -19,7 +20,5 @@ where // Exclude results in test code. not testMethod(store.getEnclosingCallable()) and not testMethod(data.getEnclosingCallable()) -select store, "'Properties' class $@ containing $@ is stored here. Data was added $@.", - s, s.toString(), - data, "sensitive data", - input, "here" +select store, "'Properties' class $@ containing $@ is stored here. Data was added $@.", s, + s.toString(), data, "sensitive data", input, "here" diff --git a/java/ql/src/Security/CWE/CWE-319/HttpsUrls.ql b/java/ql/src/Security/CWE/CWE-319/HttpsUrls.ql index 864bf9cb061..1c60c997026 100644 --- a/java/ql/src/Security/CWE/CWE-319/HttpsUrls.ql +++ b/java/ql/src/Security/CWE/CWE-319/HttpsUrls.ql @@ -8,6 +8,7 @@ * @tags security * external/cwe/cwe-319 */ + import java import semmle.code.java.dataflow.TaintTracking @@ -27,9 +28,7 @@ class HTTPString extends StringLiteral { } class URLConstructor extends ClassInstanceExpr { - URLConstructor() { - this.getConstructor().getDeclaringType().getQualifiedName() = "java.net.URL" - } + URLConstructor() { this.getConstructor().getDeclaringType().getQualifiedName() = "java.net.URL" } Expr protocolArg() { // In all cases except where the first parameter is a URL, the argument @@ -52,19 +51,29 @@ class URLOpenMethod extends Method { class HTTPStringToURLOpenMethodFlowConfig extends TaintTracking::Configuration { HTTPStringToURLOpenMethodFlowConfig() { this = "HttpsUrls::HTTPStringToURLOpenMethodFlowConfig" } + override predicate isSource(DataFlow::Node src) { src.asExpr() instanceof HTTPString } - override predicate isSink(DataFlow::Node sink) { exists(MethodAccess m | sink.asExpr() = m.getQualifier() and m.getMethod() instanceof URLOpenMethod) } + + override predicate isSink(DataFlow::Node sink) { + exists(MethodAccess m | + sink.asExpr() = m.getQualifier() and m.getMethod() instanceof URLOpenMethod + ) + } + override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { exists(URLConstructor u | node1.asExpr() = u.protocolArg() and node2.asExpr() = u ) } - override predicate isSanitizer(DataFlow::Node node) { node.getType() instanceof PrimitiveType or node.getType() instanceof BoxedType } + + override predicate isSanitizer(DataFlow::Node node) { + node.getType() instanceof PrimitiveType or node.getType() instanceof BoxedType + } } from MethodAccess m, HTTPString s where - any(HTTPStringToURLOpenMethodFlowConfig c).hasFlow(DataFlow::exprNode(s), DataFlow::exprNode(m.getQualifier())) -select m, "URL may have been constructed with HTTP protocol, using $@.", - s, "this source" + any(HTTPStringToURLOpenMethodFlowConfig c) + .hasFlow(DataFlow::exprNode(s), DataFlow::exprNode(m.getQualifier())) +select m, "URL may have been constructed with HTTP protocol, using $@.", s, "this source" diff --git a/java/ql/src/Security/CWE/CWE-319/UseSSL.ql b/java/ql/src/Security/CWE/CWE-319/UseSSL.ql index fa952d5b76d..b2e9f1586ef 100644 --- a/java/ql/src/Security/CWE/CWE-319/UseSSL.ql +++ b/java/ql/src/Security/CWE/CWE-319/UseSSL.ql @@ -8,6 +8,7 @@ * @tags security * external/cwe/cwe-319 */ + import java import semmle.code.java.security.Encryption @@ -19,16 +20,15 @@ class URLConnection extends RefType { } class Socket extends RefType { - Socket() { - this.getAnAncestor().hasQualifiedName("java.net", "Socket") - } + Socket() { this.getAnAncestor().hasQualifiedName("java.net", "Socket") } } from MethodAccess m, Class c, string type where m.getQualifier().getType() = c and ( - (c instanceof URLConnection and type = "connection") or + (c instanceof URLConnection and type = "connection") + or (c instanceof Socket and type = "socket") ) and not c instanceof SSLClass and diff --git a/java/ql/src/Security/CWE/CWE-319/UseSSLSocketFactories.ql b/java/ql/src/Security/CWE/CWE-319/UseSSLSocketFactories.ql index 7c304dc53e0..b594f9d8fc1 100644 --- a/java/ql/src/Security/CWE/CWE-319/UseSSLSocketFactories.ql +++ b/java/ql/src/Security/CWE/CWE-319/UseSSLSocketFactories.ql @@ -9,6 +9,7 @@ * @tags security * external/cwe/cwe-319 */ + import java import semmle.code.java.security.Encryption @@ -24,12 +25,11 @@ class SocketFactoryType extends RefType { SocketFactoryType() { this.getQualifiedName() = "java.rmi.server.RMIServerSocketFactory" or this.getQualifiedName() = "java.rmi.server.RMIClientSocketFactory" or - this.getQualifiedName()= "javax.net.SocketFactory" or + this.getQualifiedName() = "javax.net.SocketFactory" or this.getQualifiedName() = "java.net.SocketImplFactory" } } - /** Holds if the method `m` has a factory parameter at location `p`. */ cached predicate usesFactory(Method m, int p) { @@ -76,6 +76,5 @@ predicate query(MethodAccess m, Method def, int paramNo, string message, Element } from MethodAccess m, Method def, int param, string message, Element evidence -where - query(m,def,param,message,evidence) +where query(m, def, param, message, evidence) select m, "Method " + message + ": use an SSL factory." diff --git a/java/ql/src/Security/CWE/CWE-327/BrokenCryptoAlgorithm.ql b/java/ql/src/Security/CWE/CWE-327/BrokenCryptoAlgorithm.ql index 3106a21af13..53767eb8115 100644 --- a/java/ql/src/Security/CWE/CWE-327/BrokenCryptoAlgorithm.ql +++ b/java/ql/src/Security/CWE/CWE-327/BrokenCryptoAlgorithm.ql @@ -8,15 +8,14 @@ * @tags security * external/cwe/cwe-327 */ + import java import semmle.code.java.security.Encryption import semmle.code.java.dataflow.TaintTracking import DataFlow private class ShortStringLiteral extends StringLiteral { - ShortStringLiteral() { - getLiteral().length() < 100 - } + ShortStringLiteral() { getLiteral().length() < 100 } } class BrokenAlgoLiteral extends ShortStringLiteral { @@ -29,18 +28,18 @@ class BrokenAlgoLiteral extends ShortStringLiteral { class InsecureCryptoConfiguration extends TaintTracking::Configuration { InsecureCryptoConfiguration() { this = "BrokenCryptoAlgortihm::InsecureCryptoConfiguration" } - override predicate isSource(Node n) { - n.asExpr() instanceof BrokenAlgoLiteral + + override predicate isSource(Node n) { n.asExpr() instanceof BrokenAlgoLiteral } + + override predicate isSink(Node n) { exists(CryptoAlgoSpec c | n.asExpr() = c.getAlgoSpec()) } + + override predicate isSanitizer(DataFlow::Node node) { + node.getType() instanceof PrimitiveType or node.getType() instanceof BoxedType } - override predicate isSink(Node n) { - exists(CryptoAlgoSpec c | n.asExpr() = c.getAlgoSpec()) - } - override predicate isSanitizer(DataFlow::Node node) { node.getType() instanceof PrimitiveType or node.getType() instanceof BoxedType } } from CryptoAlgoSpec c, Expr a, BrokenAlgoLiteral s, InsecureCryptoConfiguration conf where a = c.getAlgoSpec() and conf.hasFlow(exprNode(s), exprNode(a)) -select c, "Cryptographic algorithm $@ is weak and should not be used.", - s, s.getLiteral() +select c, "Cryptographic algorithm $@ is weak and should not be used.", s, s.getLiteral() diff --git a/java/ql/src/Security/CWE/CWE-327/MaybeBrokenCryptoAlgorithm.ql b/java/ql/src/Security/CWE/CWE-327/MaybeBrokenCryptoAlgorithm.ql index 2de43017893..26289e801c2 100644 --- a/java/ql/src/Security/CWE/CWE-327/MaybeBrokenCryptoAlgorithm.ql +++ b/java/ql/src/Security/CWE/CWE-327/MaybeBrokenCryptoAlgorithm.ql @@ -8,6 +8,7 @@ * @tags security * external/cwe/cwe-327 */ + import java import semmle.code.java.security.Encryption import semmle.code.java.dataflow.TaintTracking @@ -15,9 +16,7 @@ import DataFlow import semmle.code.java.dispatch.VirtualDispatch private class ShortStringLiteral extends StringLiteral { - ShortStringLiteral() { - getLiteral().length() < 100 - } + ShortStringLiteral() { getLiteral().length() < 100 } } class InsecureAlgoLiteral extends ShortStringLiteral { @@ -53,12 +52,11 @@ class StringContainer extends RefType { class InsecureCryptoConfiguration extends TaintTracking::Configuration { InsecureCryptoConfiguration() { this = "InsecureCryptoConfiguration" } - override predicate isSource(Node n) { - n.asExpr() instanceof InsecureAlgoLiteral - } - override predicate isSink(Node n) { - exists(CryptoAlgoSpec c | n.asExpr() = c.getAlgoSpec()) - } + + override predicate isSource(Node n) { n.asExpr() instanceof InsecureAlgoLiteral } + + override predicate isSink(Node n) { exists(CryptoAlgoSpec c | n.asExpr() = c.getAlgoSpec()) } + override predicate isSanitizer(Node n) { objectToString(n.asExpr()) or not n.getType().getErasure() instanceof StringContainer @@ -69,5 +67,5 @@ from CryptoAlgoSpec c, Expr a, InsecureAlgoLiteral s, InsecureCryptoConfiguratio where a = c.getAlgoSpec() and conf.hasFlow(exprNode(s), exprNode(a)) -select c, "Cryptographic algorithm $@ may not be secure, consider using a different algorithm.", - s, s.getLiteral() +select c, "Cryptographic algorithm $@ may not be secure, consider using a different algorithm.", s, + s.getLiteral() diff --git a/java/ql/src/Security/CWE/CWE-335/PredictableSeed.ql b/java/ql/src/Security/CWE/CWE-335/PredictableSeed.ql index 4cd0ad9c7ee..e0a53b59977 100644 --- a/java/ql/src/Security/CWE/CWE-335/PredictableSeed.ql +++ b/java/ql/src/Security/CWE/CWE-335/PredictableSeed.ql @@ -7,6 +7,7 @@ * @id java/predictable-seed * @tags security */ + import java import semmle.code.java.security.Random @@ -14,5 +15,4 @@ from GetRandomData da, RValue use, PredictableSeedExpr source where da.getQualifier() = use and unsafelySeeded(use, source) -select da, "Usage of a SecureRandom number generator seeded with a $@.", - source, "predictable value" +select da, "Usage of a SecureRandom number generator seeded with a $@.", source, "predictable value" diff --git a/java/ql/src/Security/CWE/CWE-367/TOCTOURace.ql b/java/ql/src/Security/CWE/CWE-367/TOCTOURace.ql index a70a2e4deb2..d88b946e44d 100644 --- a/java/ql/src/Security/CWE/CWE-367/TOCTOURace.ql +++ b/java/ql/src/Security/CWE/CWE-367/TOCTOURace.ql @@ -9,6 +9,7 @@ * @tags security * external/cwe/cwe-367 */ + import java import semmle.code.java.Concurrency import semmle.code.java.controlflow.Guards @@ -44,7 +45,9 @@ class PossiblyConcurrentCallable extends Callable { or exists(FieldAccess f | f.getVariable().isVolatile() | f.getEnclosingCallable() = this) or - exists(VarAccess v | v.getVariable().getType().(RefType).hasQualifiedName("java.lang", "ThreadLocal") | + exists(VarAccess v | + v.getVariable().getType().(RefType).hasQualifiedName("java.lang", "ThreadLocal") + | v.getEnclosingCallable() = this ) } @@ -57,7 +60,7 @@ predicate alwaysLocked(Field f) { exists(Variable lock | forex(VarAccess access | access = f.getAnAccess() and not access.getEnclosingCallable() instanceof InitializerMethod - | + | locallySynchronizedOn(access, _, lock) ) ) @@ -65,7 +68,7 @@ predicate alwaysLocked(Field f) { exists(RefType thisType | forex(VarAccess access | access = f.getAnAccess() and not access.getEnclosingCallable() instanceof InitializerMethod - | + | locallySynchronizedOnThis(access, thisType) ) ) @@ -73,7 +76,7 @@ predicate alwaysLocked(Field f) { exists(RefType classType | forex(VarAccess access | access = f.getAnAccess() and not access.getEnclosingCallable() instanceof InitializerMethod - | + | locallySynchronizedOnClass(access, classType) ) ) @@ -84,14 +87,11 @@ predicate alwaysLocked(Field f) { */ predicate probablyNeverEscapes(LocalVariableDecl v) { // Not passed into another function. - not exists(Call c | c.getAnArgument() = v.getAnAccess()) - and + not exists(Call c | c.getAnArgument() = v.getAnAccess()) and // Not assigned directly to another variable. - not exists(Assignment a | a.getSource() = v.getAnAccess()) - and + not exists(Assignment a | a.getSource() = v.getAnAccess()) and // Not returned. - not exists(ReturnStmt r | r.getResult() = v.getAnAccess()) - and + not exists(ReturnStmt r | r.getResult() = v.getAnAccess()) and // All assignments are to new instances of a class. forex(Expr e | e = v.getAnAssignedValue() | e instanceof ClassInstanceExpr) } @@ -99,34 +99,26 @@ predicate probablyNeverEscapes(LocalVariableDecl v) { // Loop conditions tend to be uninteresting, so are not included. from IfStmt check, MethodAccess call1, MethodAccess call2, Variable r where - check.getCondition().getAChildExpr*() = call1 - and + check.getCondition().getAChildExpr*() = call1 and // This can happen if there are loops, etc. - not call1 = call2 - and + not call1 = call2 and // The use is controlled by one of the branches of the condition, i.e. whether it // is reached actually depends on that condition. - call1.getBasicBlock().(ConditionBlock).controls(call2.getBasicBlock(), _) - and + call1.getBasicBlock().(ConditionBlock).controls(call2.getBasicBlock(), _) and // Two calls to synchronized methods on the same variable. - synchCallOn(call1, r) and synchCallOn(call2, r) - and + synchCallOn(call1, r) and + synchCallOn(call2, r) and // Not jointly synchronized on that variable. // (If the caller synchronizes on `r` then it takes the same monitor as the `synchronized` callees do.) - not commonSynchronization(call1, call2, r) - and + not commonSynchronization(call1, call2, r) and // Only include cases that look like they may be intended for concurrent usage. - check.getEnclosingCallable() instanceof PossiblyConcurrentCallable - and + check.getEnclosingCallable() instanceof PossiblyConcurrentCallable and // Ignore fields that look like they're consistently guarded with some other lock. - not alwaysLocked(r) - and + not alwaysLocked(r) and // Ignore local variables whose value probably never escapes, as they can't be accessed concurrently. - not probablyNeverEscapes(r) - and + not probablyNeverEscapes(r) and // The synchronized methods on `Throwable` are not interesting. not call1.getCallee().getDeclaringType() instanceof TypeThrowable select call2, "The state of $@ is checked $@, and then it is used here. But these are not jointly synchronized.", - r, r.getName(), - call1, "here" + r, r.getName(), call1, "here" diff --git a/java/ql/src/Security/CWE/CWE-421/SocketAuthRace.ql b/java/ql/src/Security/CWE/CWE-421/SocketAuthRace.ql index 71c5f9adc4f..7b2870a1b28 100644 --- a/java/ql/src/Security/CWE/CWE-421/SocketAuthRace.ql +++ b/java/ql/src/Security/CWE/CWE-421/SocketAuthRace.ql @@ -14,7 +14,7 @@ import semmle.code.java.security.SensitiveActions import semmle.code.java.controlflow.Dominance import semmle.code.java.controlflow.Guards -abstract class ConnectionMethod extends Method {} +abstract class ConnectionMethod extends Method { } /* * Amongst the Java networking utilities, the `ServerSocket*` classes allow listening on a port. @@ -32,8 +32,7 @@ abstract class ConnectionMethod extends Method {} */ class ServerSocketAcceptMethod extends ConnectionMethod { ServerSocketAcceptMethod() { - this.getName() = "accept" - and + this.getName() = "accept" and this.getDeclaringType().hasQualifiedName("java.net", "ServerSocket") } } @@ -44,18 +43,15 @@ class ServerSocketAcceptMethod extends ConnectionMethod { */ class ServerSocketChannelAcceptMethod extends ConnectionMethod { ServerSocketChannelAcceptMethod() { - this.getName() = "accept" - and + this.getName() = "accept" and this.getDeclaringType().hasQualifiedName("java.nio.channels", "ServerSocketChannel") } } predicate controlledByAuth(Expr controlled, Expr condition) { exists(ConditionBlock b | - condition = b.getCondition() - and - b.controls(controlled.getBasicBlock(), _) - and + condition = b.getCondition() and + b.controls(controlled.getBasicBlock(), _) and condition.(MethodAccess).getMethod() instanceof AuthMethod ) } @@ -73,10 +69,10 @@ predicate controlledByAuth(Expr controlled, Expr condition) { * authenticated. If we checked every connection, we would have * no idea which ones were meant to be secure. */ + from MethodAccess connection, Expr condition where - connection.getMethod() instanceof ConnectionMethod - and + connection.getMethod() instanceof ConnectionMethod and controlledByAuth(connection, condition) select connection, "This connection occurs after the authentication in $@, rather than authentication over the new connection.", diff --git a/java/ql/src/Security/CWE/CWE-502/UnsafeDeserialization.ql b/java/ql/src/Security/CWE/CWE-502/UnsafeDeserialization.ql index 13e1e42d803..551bde36711 100644 --- a/java/ql/src/Security/CWE/CWE-502/UnsafeDeserialization.ql +++ b/java/ql/src/Security/CWE/CWE-502/UnsafeDeserialization.ql @@ -9,13 +9,16 @@ * @tags security * external/cwe/cwe-502 */ + import java import semmle.code.java.dataflow.FlowSources import UnsafeDeserialization class UnsafeDeserializationConfig extends TaintTracking::Configuration { UnsafeDeserializationConfig() { this = "UnsafeDeserializationConfig" } + override predicate isSource(DataFlow::Node source) { source instanceof RemoteUserInput } + override predicate isSink(DataFlow::Node sink) { sink instanceof UnsafeDeserializationSink } } diff --git a/java/ql/src/Security/CWE/CWE-601/UrlRedirect.ql b/java/ql/src/Security/CWE/CWE-601/UrlRedirect.ql index 263caebcfc3..b7c96e929ea 100644 --- a/java/ql/src/Security/CWE/CWE-601/UrlRedirect.ql +++ b/java/ql/src/Security/CWE/CWE-601/UrlRedirect.ql @@ -9,17 +9,19 @@ * @tags security * external/cwe/cwe-601 */ + import java import semmle.code.java.dataflow.FlowSources import UrlRedirect class UrlRedirectConfig extends TaintTracking::Configuration { UrlRedirectConfig() { this = "UrlRedirectConfig" } + override predicate isSource(DataFlow::Node source) { source instanceof RemoteUserInput } + override predicate isSink(DataFlow::Node sink) { sink instanceof UrlRedirectSink } } from UrlRedirectSink sink, RemoteUserInput source, UrlRedirectConfig conf where conf.hasFlow(source, sink) -select sink, "Potentially untrusted URL redirection due to $@.", - source, "user-provided value" +select sink, "Potentially untrusted URL redirection due to $@.", source, "user-provided value" diff --git a/java/ql/src/Security/CWE/CWE-601/UrlRedirectLocal.ql b/java/ql/src/Security/CWE/CWE-601/UrlRedirectLocal.ql index ad408836ceb..8a8c7803966 100644 --- a/java/ql/src/Security/CWE/CWE-601/UrlRedirectLocal.ql +++ b/java/ql/src/Security/CWE/CWE-601/UrlRedirectLocal.ql @@ -9,17 +9,19 @@ * @tags security * external/cwe/cwe-601 */ + import java import semmle.code.java.dataflow.FlowSources import UrlRedirect class UrlRedirectLocalConfig extends TaintTracking::Configuration { UrlRedirectLocalConfig() { this = "UrlRedirectLocalConfig" } + override predicate isSource(DataFlow::Node source) { source instanceof LocalUserInput } + override predicate isSink(DataFlow::Node sink) { sink instanceof UrlRedirectSink } } from UrlRedirectSink sink, LocalUserInput source, UrlRedirectLocalConfig conf where conf.hasFlow(source, sink) -select sink, "Potentially untrusted URL redirection due to $@.", - source, "user-provided value" +select sink, "Potentially untrusted URL redirection due to $@.", source, "user-provided value" diff --git a/java/ql/src/Security/CWE/CWE-611/XXE.ql b/java/ql/src/Security/CWE/CWE-611/XXE.ql index 8582a15cc84..deb0c510804 100644 --- a/java/ql/src/Security/CWE/CWE-611/XXE.ql +++ b/java/ql/src/Security/CWE/CWE-611/XXE.ql @@ -16,8 +16,13 @@ import semmle.code.java.dataflow.FlowSources class SafeSAXSourceFlowConfig extends TaintTracking::Configuration2 { SafeSAXSourceFlowConfig() { this = "XmlParsers::SafeSAXSourceFlowConfig" } + override predicate isSource(DataFlow::Node src) { src.asExpr() instanceof SafeSAXSource } - override predicate isSink(DataFlow::Node sink) { sink.asExpr() = any(XmlParserCall parse).getSink() } + + override predicate isSink(DataFlow::Node sink) { + sink.asExpr() = any(XmlParserCall parse).getSink() + } + override int fieldFlowBranchLimit() { result = 0 } } @@ -33,7 +38,9 @@ class UnsafeXxeSink extends DataFlow::ExprNode { class XxeConfig extends TaintTracking::Configuration { XxeConfig() { this = "XXE.ql::XxeConfig" } + override predicate isSource(DataFlow::Node src) { src instanceof RemoteUserInput } + override predicate isSink(DataFlow::Node sink) { sink instanceof UnsafeXxeSink } } diff --git a/java/ql/src/Security/CWE/CWE-614/InsecureCookie.ql b/java/ql/src/Security/CWE/CWE-614/InsecureCookie.ql index 67ec8e02221..c35e49359bd 100644 --- a/java/ql/src/Security/CWE/CWE-614/InsecureCookie.ql +++ b/java/ql/src/Security/CWE/CWE-614/InsecureCookie.ql @@ -9,6 +9,7 @@ * @tags security * external/cwe/cwe-614 */ + import java import semmle.code.java.frameworks.Servlets diff --git a/java/ql/src/Security/CWE/CWE-676/PotentiallyDangerousFunction.ql b/java/ql/src/Security/CWE/CWE-676/PotentiallyDangerousFunction.ql index fd61327b9c3..f1449012363 100644 --- a/java/ql/src/Security/CWE/CWE-676/PotentiallyDangerousFunction.ql +++ b/java/ql/src/Security/CWE/CWE-676/PotentiallyDangerousFunction.ql @@ -9,11 +9,10 @@ * security * external/cwe/cwe-676 */ + import java -predicate dangerousMethod(string descriptor) { - descriptor = "java.lang.Thread.stop" -} +predicate dangerousMethod(string descriptor) { descriptor = "java.lang.Thread.stop" } from MethodAccess call, Method target, string descriptor where diff --git a/java/ql/src/Security/CWE/CWE-681/NumericCastTainted.ql b/java/ql/src/Security/CWE/CWE-681/NumericCastTainted.ql index 1f363dccba3..d22b8f6bfa7 100644 --- a/java/ql/src/Security/CWE/CWE-681/NumericCastTainted.ql +++ b/java/ql/src/Security/CWE/CWE-681/NumericCastTainted.ql @@ -10,14 +10,20 @@ * external/cwe/cwe-197 * external/cwe/cwe-681 */ + import java import semmle.code.java.dataflow.FlowSources import NumericCastCommon private class NumericCastFlowConfig extends TaintTracking::Configuration { NumericCastFlowConfig() { this = "NumericCastTainted::RemoteUserInputToNumericNarrowingCastExpr" } + override predicate isSource(DataFlow::Node src) { src instanceof RemoteUserInput } - override predicate isSink(DataFlow::Node sink) { sink.asExpr() = any(NumericNarrowingCastExpr cast).getExpr() } + + override predicate isSink(DataFlow::Node sink) { + sink.asExpr() = any(NumericNarrowingCastExpr cast).getExpr() + } + override predicate isSanitizer(DataFlow::Node node) { boundedRead(node.asExpr()) or castCheck(node.asExpr()) or @@ -27,7 +33,9 @@ private class NumericCastFlowConfig extends TaintTracking::Configuration { } } -from NumericNarrowingCastExpr exp, VarAccess tainted, RemoteUserInput origin, NumericCastFlowConfig conf +from + NumericNarrowingCastExpr exp, VarAccess tainted, RemoteUserInput origin, + NumericCastFlowConfig conf where exp.getExpr() = tainted and conf.hasFlow(origin, DataFlow::exprNode(tainted)) and diff --git a/java/ql/src/Security/CWE/CWE-681/NumericCastTaintedLocal.ql b/java/ql/src/Security/CWE/CWE-681/NumericCastTaintedLocal.ql index b9e2eff2b3a..23ac0cb1184 100644 --- a/java/ql/src/Security/CWE/CWE-681/NumericCastTaintedLocal.ql +++ b/java/ql/src/Security/CWE/CWE-681/NumericCastTaintedLocal.ql @@ -10,14 +10,22 @@ * external/cwe/cwe-197 * external/cwe/cwe-681 */ + import java import semmle.code.java.dataflow.FlowSources import NumericCastCommon private class NumericCastFlowConfig extends TaintTracking::Configuration { - NumericCastFlowConfig() { this = "NumericCastTaintedLocal::LocalUserInputToNumericNarrowingCastExpr" } + NumericCastFlowConfig() { + this = "NumericCastTaintedLocal::LocalUserInputToNumericNarrowingCastExpr" + } + override predicate isSource(DataFlow::Node src) { src instanceof LocalUserInput } - override predicate isSink(DataFlow::Node sink) { sink.asExpr() = any(NumericNarrowingCastExpr cast).getExpr() } + + override predicate isSink(DataFlow::Node sink) { + sink.asExpr() = any(NumericNarrowingCastExpr cast).getExpr() + } + override predicate isSanitizer(DataFlow::Node node) { boundedRead(node.asExpr()) or castCheck(node.asExpr()) or @@ -27,7 +35,8 @@ private class NumericCastFlowConfig extends TaintTracking::Configuration { } } -from NumericNarrowingCastExpr exp, VarAccess tainted, LocalUserInput origin, NumericCastFlowConfig conf +from + NumericNarrowingCastExpr exp, VarAccess tainted, LocalUserInput origin, NumericCastFlowConfig conf where exp.getExpr() = tainted and conf.hasFlow(origin, DataFlow::exprNode(tainted)) and diff --git a/java/ql/src/Security/CWE/CWE-732/ReadingFromWorldWritableFile.ql b/java/ql/src/Security/CWE/CWE-732/ReadingFromWorldWritableFile.ql index ad8dbb764da..f87733f0e9f 100644 --- a/java/ql/src/Security/CWE/CWE-732/ReadingFromWorldWritableFile.ql +++ b/java/ql/src/Security/CWE/CWE-732/ReadingFromWorldWritableFile.ql @@ -21,5 +21,5 @@ where fileVariable.getAnAccess() = setWorldWritable.getFileVarAccess() and // If the file variable is a parameter, the result should be reported in the caller. not fileVariable instanceof Parameter -select setWorldWritable, "A file is set to be world writable here, but is read from $@.", - readFrom, "statement" +select setWorldWritable, "A file is set to be world writable here, but is read from $@.", readFrom, + "statement" diff --git a/java/ql/src/Security/CWE/CWE-798/HardcodedCredentialsApiCall.ql b/java/ql/src/Security/CWE/CWE-798/HardcodedCredentialsApiCall.ql index 5fd7a87725f..478ee937576 100644 --- a/java/ql/src/Security/CWE/CWE-798/HardcodedCredentialsApiCall.ql +++ b/java/ql/src/Security/CWE/CWE-798/HardcodedCredentialsApiCall.ql @@ -8,19 +8,21 @@ * @tags security * external/cwe/cwe-798 */ + import java import semmle.code.java.dataflow.DataFlow import HardcodedCredentials class HardcodedCredentialApiCallConfiguration extends DataFlow::Configuration { HardcodedCredentialApiCallConfiguration() { this = "HardcodedCredentialApiCallConfiguration" } + override predicate isSource(DataFlow::Node n) { n.asExpr() instanceof HardcodedExpr and not n.asExpr().getEnclosingCallable().getName() = "toString" } - override predicate isSink(DataFlow::Node n) { - n.asExpr() instanceof CredentialsApiSink - } + + override predicate isSink(DataFlow::Node n) { n.asExpr() instanceof CredentialsApiSink } + override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { node1.asExpr().getType() instanceof TypeString and exists(MethodAccess ma | ma.getMethod().getName().regexpMatch("getBytes|toCharArray") | @@ -32,5 +34,4 @@ class HardcodedCredentialApiCallConfiguration extends DataFlow::Configuration { from CredentialsApiSink sink, HardcodedExpr source, HardcodedCredentialApiCallConfiguration conf where conf.hasFlow(DataFlow::exprNode(source), DataFlow::exprNode(sink)) -select source, "Hard-coded value flows to $@.", - sink, "sensitive API call" +select source, "Hard-coded value flows to $@.", sink, "sensitive API call" diff --git a/java/ql/src/Security/CWE/CWE-798/HardcodedCredentialsComparison.ql b/java/ql/src/Security/CWE/CWE-798/HardcodedCredentialsComparison.ql index eb700903cbe..571a1566cca 100644 --- a/java/ql/src/Security/CWE/CWE-798/HardcodedCredentialsComparison.ql +++ b/java/ql/src/Security/CWE/CWE-798/HardcodedCredentialsComparison.ql @@ -8,22 +8,17 @@ * @tags security * external/cwe/cwe-798 */ + import java import HardcodedCredentials -class EqualsAccess extends MethodAccess { - EqualsAccess() { - getMethod() instanceof EqualsMethod - } -} +class EqualsAccess extends MethodAccess { EqualsAccess() { getMethod() instanceof EqualsMethod } } from EqualsAccess sink, HardcodedExpr source, PasswordVariable p where - source = sink.getQualifier() and - p.getAnAccess() = sink.getArgument(0) + source = sink.getQualifier() and + p.getAnAccess() = sink.getArgument(0) or - source = sink.getArgument(0) and - p.getAnAccess() = sink.getQualifier() -select source, "Hard-coded value is $@ with password variable $@.", - sink, "compared", - p, p.getName() + source = sink.getArgument(0) and + p.getAnAccess() = sink.getQualifier() +select source, "Hard-coded value is $@ with password variable $@.", sink, "compared", p, p.getName() diff --git a/java/ql/src/Security/CWE/CWE-798/HardcodedCredentialsSourceCall.ql b/java/ql/src/Security/CWE/CWE-798/HardcodedCredentialsSourceCall.ql index 34697b112d0..c2ec2a54dde 100644 --- a/java/ql/src/Security/CWE/CWE-798/HardcodedCredentialsSourceCall.ql +++ b/java/ql/src/Security/CWE/CWE-798/HardcodedCredentialsSourceCall.ql @@ -8,40 +8,44 @@ * @tags security * external/cwe/cwe-798 */ + import java import semmle.code.java.dataflow.DataFlow import semmle.code.java.dataflow.DataFlow2 import HardcodedCredentials class HardcodedCredentialSourceCallConfiguration extends DataFlow::Configuration { - HardcodedCredentialSourceCallConfiguration() { this = "HardcodedCredentialSourceCallConfiguration" } - override predicate isSource(DataFlow::Node n) { - n.asExpr() instanceof HardcodedExpr - } - override predicate isSink(DataFlow::Node n) { - n.asExpr() instanceof FinalCredentialsSourceSink + HardcodedCredentialSourceCallConfiguration() { + this = "HardcodedCredentialSourceCallConfiguration" } + + override predicate isSource(DataFlow::Node n) { n.asExpr() instanceof HardcodedExpr } + + override predicate isSink(DataFlow::Node n) { n.asExpr() instanceof FinalCredentialsSourceSink } } class HardcodedCredentialSourceCallConfiguration2 extends DataFlow2::Configuration { - HardcodedCredentialSourceCallConfiguration2() { this = "HardcodedCredentialSourceCallConfiguration2" } - override predicate isSource(DataFlow::Node n) { - n.asExpr() instanceof CredentialsSourceSink - } - override predicate isSink(DataFlow::Node n) { - n.asExpr() instanceof CredentialsSink + HardcodedCredentialSourceCallConfiguration2() { + this = "HardcodedCredentialSourceCallConfiguration2" } + + override predicate isSource(DataFlow::Node n) { n.asExpr() instanceof CredentialsSourceSink } + + override predicate isSink(DataFlow::Node n) { n.asExpr() instanceof CredentialsSink } } class FinalCredentialsSourceSink extends CredentialsSourceSink { FinalCredentialsSourceSink() { - not exists(HardcodedCredentialSourceCallConfiguration2 conf, CredentialsSink other | this != other | + not exists(HardcodedCredentialSourceCallConfiguration2 conf, CredentialsSink other | + this != other + | conf.hasFlow(DataFlow::exprNode(this), DataFlow::exprNode(other)) ) } } -from FinalCredentialsSourceSink sink, HardcodedExpr source, HardcodedCredentialSourceCallConfiguration conf +from + FinalCredentialsSourceSink sink, HardcodedExpr source, + HardcodedCredentialSourceCallConfiguration conf where conf.hasFlow(DataFlow::exprNode(source), DataFlow::exprNode(sink)) -select source, "Hard-coded value flows to $@.", - sink, "sensitive call" +select source, "Hard-coded value flows to $@.", sink, "sensitive call" diff --git a/java/ql/src/Security/CWE/CWE-798/HardcodedPasswordField.ql b/java/ql/src/Security/CWE/CWE-798/HardcodedPasswordField.ql index dc78ba7ee6b..7c0ca38263e 100644 --- a/java/ql/src/Security/CWE/CWE-798/HardcodedPasswordField.ql +++ b/java/ql/src/Security/CWE/CWE-798/HardcodedPasswordField.ql @@ -8,6 +8,7 @@ * @tags security * external/cwe/cwe-798 */ + import java import HardcodedCredentials @@ -16,5 +17,4 @@ where f instanceof Field and f.getAnAssignedValue() = e and not e.(StringLiteral).getValue() = "" -select f, "Sensitive field is assigned a hard-coded $@.", - e, "value" +select f, "Sensitive field is assigned a hard-coded $@.", e, "value" diff --git a/java/ql/src/Security/CWE/CWE-807/ConditionalBypass.ql b/java/ql/src/Security/CWE/CWE-807/ConditionalBypass.ql index d6a4594b8a1..5259bcc6bd8 100644 --- a/java/ql/src/Security/CWE/CWE-807/ConditionalBypass.ql +++ b/java/ql/src/Security/CWE/CWE-807/ConditionalBypass.ql @@ -10,6 +10,7 @@ * external/cwe/cwe-807 * external/cwe/cwe-290 */ + import java import semmle.code.java.dataflow.FlowSources import semmle.code.java.security.SensitiveActions @@ -31,7 +32,9 @@ predicate conditionControlsMethod(MethodAccess m, Expr e) { class ConditionalBypassFlowConfig extends TaintTracking::Configuration { ConditionalBypassFlowConfig() { this = "ConditionalBypassFlowConfig" } + override predicate isSource(DataFlow::Node source) { source instanceof UserInput } + override predicate isSink(DataFlow::Node sink) { conditionControlsMethod(_, sink.asExpr()) } } @@ -39,5 +42,5 @@ from UserInput u, MethodAccess m, Expr e, ConditionalBypassFlowConfig conf where conditionControlsMethod(m, e) and conf.hasFlow(u, DataFlow::exprNode(e)) -select m, "Sensitive method may not be executed depending on $@, which flows from $@.", - e, "this condition", u, "user input" +select m, "Sensitive method may not be executed depending on $@, which flows from $@.", e, + "this condition", u, "user input" diff --git a/java/ql/src/Security/CWE/CWE-807/TaintedPermissionsCheck.ql b/java/ql/src/Security/CWE/CWE-807/TaintedPermissionsCheck.ql index 14156ca0aef..aac0f1cc414 100644 --- a/java/ql/src/Security/CWE/CWE-807/TaintedPermissionsCheck.ql +++ b/java/ql/src/Security/CWE/CWE-807/TaintedPermissionsCheck.ql @@ -10,13 +10,12 @@ * external/cwe/cwe-807 * external/cwe/cwe-290 */ + import java import semmle.code.java.dataflow.FlowSources class TypeShiroSubject extends RefType { - TypeShiroSubject() { - this.getQualifiedName() = "org.apache.shiro.subject.Subject" - } + TypeShiroSubject() { this.getQualifiedName() = "org.apache.shiro.subject.Subject" } } class TypeShiroWCPermission extends RefType { @@ -25,9 +24,7 @@ class TypeShiroWCPermission extends RefType { } } -abstract class PermissionsConstruction extends Top { - abstract Expr getInput(); -} +abstract class PermissionsConstruction extends Top { abstract Expr getInput(); } class PermissionsCheckMethodAccess extends MethodAccess, PermissionsConstruction { PermissionsCheckMethodAccess() { @@ -40,9 +37,7 @@ class PermissionsCheckMethodAccess extends MethodAccess, PermissionsConstruction ) } - override Expr getInput() { - result = getArgument(0) - } + override Expr getInput() { result = getArgument(0) } } class WCPermissionConstruction extends ClassInstanceExpr, PermissionsConstruction { @@ -50,15 +45,17 @@ class WCPermissionConstruction extends ClassInstanceExpr, PermissionsConstructio this.getConstructor().getDeclaringType() instanceof TypeShiroWCPermission } - override Expr getInput() { - result = getArgument(0) - } + override Expr getInput() { result = getArgument(0) } } class TaintedPermissionsCheckFlowConfig extends TaintTracking::Configuration { TaintedPermissionsCheckFlowConfig() { this = "TaintedPermissionsCheckFlowConfig" } + override predicate isSource(DataFlow::Node source) { source instanceof UserInput } - override predicate isSink(DataFlow::Node sink) { sink.asExpr() = any(PermissionsConstruction p).getInput() } + + override predicate isSink(DataFlow::Node sink) { + sink.asExpr() = any(PermissionsConstruction p).getInput() + } } from UserInput u, PermissionsConstruction p, TaintedPermissionsCheckFlowConfig conf diff --git a/java/ql/src/Security/CWE/CWE-833/LockOrderInconsistency.ql b/java/ql/src/Security/CWE/CWE-833/LockOrderInconsistency.ql index a2c91957722..be73ae83eeb 100644 --- a/java/ql/src/Security/CWE/CWE-833/LockOrderInconsistency.ql +++ b/java/ql/src/Security/CWE/CWE-833/LockOrderInconsistency.ql @@ -8,6 +8,7 @@ * @tags security * external/cwe/cwe-833 */ + import java /** A variable of type `ReentrantLock`. */ @@ -28,17 +29,23 @@ class LockVariable extends Variable { /** A synchronized method or statement, or an expression statement containing an access to a synchronized method. */ class Synched extends Top { Synched() { - this instanceof SynchronizedStmt or + this instanceof SynchronizedStmt + or exists(Method m | m.isSynchronized() and not m.isStatic() | - m = this or - exists(MethodAccess ma, VarAccess qual | ma = this and qual = ma.getQualifier() | ma.getMethod() = m) + m = this + or + exists(MethodAccess ma, VarAccess qual | ma = this and qual = ma.getQualifier() | + ma.getMethod() = m + ) ) } /** A synchronizing statement nested within this element. */ Synched getInnerSynch() { - result = this.(Method).getBody().getAChild*() or - result = this.(SynchronizedStmt).getAChild+() or + result = this.(Method).getBody().getAChild*() + or + result = this.(SynchronizedStmt).getAChild+() + or exists(MethodAccess ma | ma = result | ma.getEnclosingStmt().getParent*() = this) } @@ -66,11 +73,13 @@ class Synched extends Top { */ predicate badReentrantLockOrder(MethodAccess first, MethodAccess second, MethodAccess otherFirst) { exists(LockVariable v1, LockVariable v2, MethodAccess otherSecond | - first = v1.getLockAction() and otherSecond = v1.getLockAction() and - second = v2.getLockAction() and otherFirst = v2.getLockAction() and + first = v1.getLockAction() and + otherSecond = v1.getLockAction() and + second = v2.getLockAction() and + otherFirst = v2.getLockAction() and first.(ControlFlowNode).getASuccessor+() = second and otherFirst.(ControlFlowNode).getASuccessor+() = otherSecond - | + | v1 != v2 ) } @@ -86,7 +95,9 @@ predicate badSynchronizedStmtLockOrder(Expr outerExpr, Expr innerExpr, Expr othe inner.(SynchronizedStmt).getExpr() = innerExpr and otherOuter.(SynchronizedStmt).getExpr() = otherOuterExpr and inner = outer.getInnerSynch() and - exists(Variable v1, Variable v2 | v1 = outer.getLockVar() and v2 = inner.getLockVar() and v1 != v2 | + exists(Variable v1, Variable v2 | + v1 = outer.getLockVar() and v2 = inner.getLockVar() and v1 != v2 + | exists(Synched otherInner | otherInner = otherOuter.getInnerSynch() | v2 = otherOuter.getLockVar() and v1 = otherInner.getLockVar() @@ -141,7 +152,9 @@ predicate inDifferentRunnables(MethodAccess ma1, MethodAccess ma2) { * in statement `inner` that is qualified by one of the parameters of `outer`, and there is * another access to `outer` that may cause locking to be performed in a different order. */ -predicate badMethodAccessLockOrder(MethodAccess outerAccess, MethodAccess innerAccess, MethodAccess other) { +predicate badMethodAccessLockOrder( + MethodAccess outerAccess, MethodAccess innerAccess, MethodAccess other +) { exists(Synched outer, Synched inner | inner.(MethodAccess) = innerAccess and inner = outer.getInnerSynch() and @@ -168,6 +181,6 @@ where badReentrantLockOrder(first, second, other) or badSynchronizedStmtLockOrder(first, second, other) or badMethodAccessLockOrder(first, second, other) -select first, "Synchronization here and $@ may be performed in reverse order starting $@ and result in deadlock.", - second, "here", - other, "here" +select first, + "Synchronization here and $@ may be performed in reverse order starting $@ and result in deadlock.", + second, "here", other, "here" diff --git a/java/ql/src/Security/CWE/CWE-835/InfiniteLoop.ql b/java/ql/src/Security/CWE/CWE-835/InfiniteLoop.ql index 10059b64ed6..22e6d0633d6 100644 --- a/java/ql/src/Security/CWE/CWE-835/InfiniteLoop.ql +++ b/java/ql/src/Security/CWE/CWE-835/InfiniteLoop.ql @@ -19,14 +19,18 @@ import Likely_Bugs.Comparison.UselessComparisonTest * by guarding a `break` or a `return` that can exit the loop. */ predicate loopCondition(LoopStmt loop, Expr cond, boolean polarity) { - polarity = true and cond = loop.getCondition() or + polarity = true and cond = loop.getCondition() + or exists(IfStmt ifstmt, Stmt exit | ifstmt.getParent*() = loop.getBody() and ifstmt.getCondition() = cond and - ( exit.(BreakStmt).(JumpStmt).getTarget() = loop or + ( + exit.(BreakStmt).(JumpStmt).getTarget() = loop or exit.(ReturnStmt).getParent*() = loop.getBody() ) and - ( polarity = false and exit.getParent*() = ifstmt.getThen() or + ( + polarity = false and exit.getParent*() = ifstmt.getThen() + or polarity = true and exit.getParent*() = ifstmt.getElse() ) ) @@ -38,20 +42,25 @@ predicate loopCondition(LoopStmt loop, Expr cond, boolean polarity) { * indicates whether an odd number of negations separates `cond` and `subcond`. */ predicate subCondition(Expr cond, Expr subcond, boolean negated) { - cond = subcond and negated = false or - subCondition(cond.(AndLogicalExpr).getAnOperand(), subcond, negated) or - subCondition(cond.(OrLogicalExpr).getAnOperand(), subcond, negated) or - subCondition(cond.(ParExpr).getExpr(), subcond, negated) or + cond = subcond and negated = false + or + subCondition(cond.(AndLogicalExpr).getAnOperand(), subcond, negated) + or + subCondition(cond.(OrLogicalExpr).getAnOperand(), subcond, negated) + or + subCondition(cond.(ParExpr).getExpr(), subcond, negated) + or subCondition(cond.(LogNotExpr).getExpr(), subcond, negated.booleanNot()) } -from LoopStmt loop, BinaryExpr test, boolean testIsTrue, Expr cond, boolean polarity, boolean negated +from + LoopStmt loop, BinaryExpr test, boolean testIsTrue, Expr cond, boolean polarity, boolean negated where loopCondition(loop, cond, polarity) and not loop instanceof EnhancedForStmt and subCondition(cond, test, negated) and uselessTest(_, test, testIsTrue) and testIsTrue = polarity.booleanXor(negated) -select - loop, "Loop might not terminate, as termination depends in part on $@ being " - + testIsTrue.booleanNot() + " but it is always " + testIsTrue + ".", test, "this test" +select loop, + "Loop might not terminate, as termination depends in part on $@ being " + testIsTrue.booleanNot() + + " but it is always " + testIsTrue + ".", test, "this test" diff --git a/java/ql/src/Violations of Best Practice/Boolean Logic/SimplifyBoolExpr.ql b/java/ql/src/Violations of Best Practice/Boolean Logic/SimplifyBoolExpr.ql index 30d88f7c4e5..db8fc26614e 100644 --- a/java/ql/src/Violations of Best Practice/Boolean Logic/SimplifyBoolExpr.ql +++ b/java/ql/src/Violations of Best Practice/Boolean Logic/SimplifyBoolExpr.ql @@ -11,15 +11,16 @@ import java class BoolCompare extends EqualityTest { - BoolCompare() { - this.getAnOperand() instanceof BooleanLiteral - } + BoolCompare() { this.getAnOperand() instanceof BooleanLiteral } predicate simplify(string pattern, string rewrite) { exists(boolean b | b = this.getAnOperand().(BooleanLiteral).getBooleanValue() | - this instanceof EQExpr and b = true and pattern = "A == true" and rewrite = "A" or - this instanceof NEExpr and b = false and pattern = "A != false" and rewrite = "A" or - this instanceof EQExpr and b = false and pattern = "A == false" and rewrite = "!A" or + this instanceof EQExpr and b = true and pattern = "A == true" and rewrite = "A" + or + this instanceof NEExpr and b = false and pattern = "A != false" and rewrite = "A" + or + this instanceof EQExpr and b = false and pattern = "A == false" and rewrite = "!A" + or this instanceof NEExpr and b = true and pattern = "A != true" and rewrite = "!A" ) } @@ -30,46 +31,62 @@ predicate conditionalWithBool(ConditionalExpr c, string pattern, string rewrite) c.getTrueExpr().(BooleanLiteral).getBooleanValue() = truebranch and not c.getFalseExpr() instanceof BooleanLiteral and not c.getFalseExpr().getType() instanceof NullType and - ( truebranch = true and pattern = "A ? true : B" and rewrite = "A || B" or + ( + truebranch = true and pattern = "A ? true : B" and rewrite = "A || B" + or truebranch = false and pattern = "A ? false : B" and rewrite = "!A && B" ) - ) or + ) + or exists(boolean falsebranch | not c.getTrueExpr() instanceof BooleanLiteral and not c.getTrueExpr().getType() instanceof NullType and c.getFalseExpr().(BooleanLiteral).getBooleanValue() = falsebranch and - ( falsebranch = true and pattern = "A ? B : true" and rewrite = "!A || B" or + ( + falsebranch = true and pattern = "A ? B : true" and rewrite = "!A || B" + or falsebranch = false and pattern = "A ? B : false" and rewrite = "A && B" ) - ) or + ) + or exists(boolean truebranch, boolean falsebranch | c.getTrueExpr().(BooleanLiteral).getBooleanValue() = truebranch and c.getFalseExpr().(BooleanLiteral).getBooleanValue() = falsebranch and - ( truebranch = true and falsebranch = false and pattern = "A ? true : false" and rewrite = "A" or + ( + truebranch = true and falsebranch = false and pattern = "A ? true : false" and rewrite = "A" + or truebranch = false and falsebranch = true and pattern = "A ? false : true" and rewrite = "!A" ) ) } class ComparisonOrEquality extends BinaryExpr { - ComparisonOrEquality() { - this instanceof ComparisonExpr or this instanceof EqualityTest - } + ComparisonOrEquality() { this instanceof ComparisonExpr or this instanceof EqualityTest } predicate negate(string pattern, string rewrite) { - this instanceof EQExpr and pattern = "!(A == B)" and rewrite = "A != B" or - this instanceof NEExpr and pattern = "!(A != B)" and rewrite = "A == B" or - this instanceof LTExpr and pattern = "!(A < B)" and rewrite = "A >= B" or - this instanceof GTExpr and pattern = "!(A > B)" and rewrite = "A <= B" or - this instanceof LEExpr and pattern = "!(A <= B)" and rewrite = "A > B" or + this instanceof EQExpr and pattern = "!(A == B)" and rewrite = "A != B" + or + this instanceof NEExpr and pattern = "!(A != B)" and rewrite = "A == B" + or + this instanceof LTExpr and pattern = "!(A < B)" and rewrite = "A >= B" + or + this instanceof GTExpr and pattern = "!(A > B)" and rewrite = "A <= B" + or + this instanceof LEExpr and pattern = "!(A <= B)" and rewrite = "A > B" + or this instanceof GEExpr and pattern = "!(A >= B)" and rewrite = "A < B" } } from Expr e, string pattern, string rewrite where - e.(BoolCompare).simplify(pattern, rewrite) or - conditionalWithBool(e, pattern, rewrite) or - e.(LogNotExpr).getExpr().getProperExpr().(ComparisonOrEquality).negate(pattern, rewrite) or - e.(LogNotExpr).getExpr().getProperExpr() instanceof LogNotExpr and pattern = "!!A" and rewrite = "A" + e.(BoolCompare).simplify(pattern, rewrite) + or + conditionalWithBool(e, pattern, rewrite) + or + e.(LogNotExpr).getExpr().getProperExpr().(ComparisonOrEquality).negate(pattern, rewrite) + or + e.(LogNotExpr).getExpr().getProperExpr() instanceof LogNotExpr and + pattern = "!!A" and + rewrite = "A" select e, "Expressions of the form \"" + pattern + "\" can be simplified to \"" + rewrite + "\"." diff --git a/java/ql/src/Violations of Best Practice/Boxed Types/BoxedVariable.ql b/java/ql/src/Violations of Best Practice/Boxed Types/BoxedVariable.ql index 58efbf84b9e..4f8ed49e010 100644 --- a/java/ql/src/Violations of Best Practice/Boxed Types/BoxedVariable.ql +++ b/java/ql/src/Violations of Best Practice/Boxed Types/BoxedVariable.ql @@ -9,16 +9,13 @@ * @tags readability * types */ + import java class LocalBoxedVar extends LocalVariableDecl { - LocalBoxedVar() { - this.getType() instanceof BoxedType - } + LocalBoxedVar() { this.getType() instanceof BoxedType } - PrimitiveType getPrimitiveType() { - this.getType().(BoxedType).getPrimitiveType() = result - } + PrimitiveType getPrimitiveType() { this.getType().(BoxedType).getPrimitiveType() = result } } /** @@ -33,7 +30,8 @@ predicate notDeliberatelyBoxed(LocalBoxedVar v) { exists(Call c, int i | c.getCallee().getParameterType(i) instanceof RefType and c.getArgument(i) = a - ) or + ) + or exists(ReturnStmt ret | ret.getResult() = a and ret.getEnclosingCallable().getReturnType() instanceof RefType @@ -61,11 +59,14 @@ predicate affectsOverload(LocalBoxedVar v) { from LocalBoxedVar v where forall(Expr e | e = v.getAnAssignedValue() | e.getType() = v.getPrimitiveType()) and - ( not v.getDeclExpr().getParent() instanceof EnhancedForStmt or - v.getDeclExpr().getParent().(EnhancedForStmt).getExpr().getType().(Array).getComponentType() = v.getPrimitiveType() + ( + not v.getDeclExpr().getParent() instanceof EnhancedForStmt or + v.getDeclExpr().getParent().(EnhancedForStmt).getExpr().getType().(Array).getComponentType() = v + .getPrimitiveType() ) and notDeliberatelyBoxed(v) and not affectsOverload(v) select v, - "The variable '" + v.getName() + "' is only assigned values of primitive type and is never 'null', but it is declared with the boxed type '" + - v.getType().toString() + "'." + "The variable '" + v.getName() + + "' is only assigned values of primitive type and is never 'null', but it is declared with the boxed type '" + + v.getType().toString() + "'." diff --git a/java/ql/src/Violations of Best Practice/Comments/TodoComments.ql b/java/ql/src/Violations of Best Practice/Comments/TodoComments.ql index 430d23cb4b6..37ec6695a51 100644 --- a/java/ql/src/Violations of Best Practice/Comments/TodoComments.ql +++ b/java/ql/src/Violations of Best Practice/Comments/TodoComments.ql @@ -10,6 +10,7 @@ * readability * external/cwe/cwe-546 */ + import java from JavadocText c diff --git a/java/ql/src/Violations of Best Practice/Dead Code/AssignmentInReturn.ql b/java/ql/src/Violations of Best Practice/Dead Code/AssignmentInReturn.ql index b0789b23816..b70d5c6cf8b 100644 --- a/java/ql/src/Violations of Best Practice/Dead Code/AssignmentInReturn.ql +++ b/java/ql/src/Violations of Best Practice/Dead Code/AssignmentInReturn.ql @@ -8,6 +8,7 @@ * @tags maintainability * readability */ + import java from AssignExpr e, LocalVariableDecl v diff --git a/java/ql/src/Violations of Best Practice/Dead Code/CreatesEmptyZip.ql b/java/ql/src/Violations of Best Practice/Dead Code/CreatesEmptyZip.ql index abeaae0a60a..50a778cbaff 100644 --- a/java/ql/src/Violations of Best Practice/Dead Code/CreatesEmptyZip.ql +++ b/java/ql/src/Violations of Best Practice/Dead Code/CreatesEmptyZip.ql @@ -9,6 +9,7 @@ * @tags reliability * readability */ + import java import semmle.code.java.dataflow.SSA @@ -40,8 +41,9 @@ class ZipOutputStream extends Class { } } -from ZipOutputStream jos, MethodAccess putNextEntry, MethodAccess closeEntry, - RValue putNextQualifier, RValue closeQualifier +from + ZipOutputStream jos, MethodAccess putNextEntry, MethodAccess closeEntry, RValue putNextQualifier, + RValue closeQualifier where putNextEntry.getMethod() = jos.putNextEntry() and closeEntry.getMethod() = jos.closeEntry() and diff --git a/java/ql/src/Violations of Best Practice/Dead Code/DeadRefTypes.ql b/java/ql/src/Violations of Best Practice/Dead Code/DeadRefTypes.ql index eb2103bbb83..3740b453d8c 100644 --- a/java/ql/src/Violations of Best Practice/Dead Code/DeadRefTypes.ql +++ b/java/ql/src/Violations of Best Practice/Dead Code/DeadRefTypes.ql @@ -10,6 +10,7 @@ * useless-code * external/cwe/cwe-561 */ + import java import semmle.code.java.Reflection @@ -17,40 +18,40 @@ import semmle.code.java.Reflection * A class or interface that is not used anywhere. */ predicate dead(RefType dead) { - dead.fromSource() and - // Nothing depends on this type. - not exists(RefType s | s.getMetrics().getADependency() = dead) and - - // Exclude Struts or JSP classes (marked with Javadoc tags). - not exists(JavadocTag tag, string x | - tag = dead.getDoc().getJavadoc().getATag(x) and - (x.matches("@struts%") or x.matches("@jsp%")) - ) and - // Exclude public types. - not dead.isPublic() and - // Exclude results that have a `main` method. - not dead.getAMethod().hasName("main") and - // Exclude results that are referenced in XML files. - not exists(XMLAttribute xla | xla.getValue() = dead.getQualifiedName()) and - // Exclude type variables. - not dead instanceof BoundedType and - // Exclude JUnit tests. - not dead.getASupertype*().hasName("TestCase") and - // Exclude enum types. - not dead instanceof EnumType and - // Exclude classes that look like they may be reflectively constructed. - not dead.getAnAnnotation() instanceof ReflectiveAccessAnnotation and - - // Insist all source ancestors are dead as well. - forall(RefType t | t.fromSource() and t = dead.getASupertype+() | dead(t)) + dead.fromSource() and + // Nothing depends on this type. + not exists(RefType s | s.getMetrics().getADependency() = dead) and + // Exclude Struts or JSP classes (marked with Javadoc tags). + not exists(JavadocTag tag, string x | + tag = dead.getDoc().getJavadoc().getATag(x) and + (x.matches("@struts%") or x.matches("@jsp%")) + ) and + // Exclude public types. + not dead.isPublic() and + // Exclude results that have a `main` method. + not dead.getAMethod().hasName("main") and + // Exclude results that are referenced in XML files. + not exists(XMLAttribute xla | xla.getValue() = dead.getQualifiedName()) and + // Exclude type variables. + not dead instanceof BoundedType and + // Exclude JUnit tests. + not dead.getASupertype*().hasName("TestCase") and + // Exclude enum types. + not dead instanceof EnumType and + // Exclude classes that look like they may be reflectively constructed. + not dead.getAnAnnotation() instanceof ReflectiveAccessAnnotation and + // Insist all source ancestors are dead as well. + forall(RefType t | t.fromSource() and t = dead.getASupertype+() | dead(t)) } from RefType t, string kind where dead(t) and ( - t instanceof Class and kind = "class" or + t instanceof Class and kind = "class" + or t instanceof Interface and kind = "interface" ) -select t, "Unused " + kind + ": " + t.getName() + " is not referenced within this codebase. " + - "If not used as an external API it should be removed." +select t, + "Unused " + kind + ": " + t.getName() + " is not referenced within this codebase. " + + "If not used as an external API it should be removed." diff --git a/java/ql/src/Violations of Best Practice/Dead Code/DeadStoreOfLocal.ql b/java/ql/src/Violations of Best Practice/Dead Code/DeadStoreOfLocal.ql index b010500a44b..c2dd74b5745 100644 --- a/java/ql/src/Violations of Best Practice/Dead Code/DeadStoreOfLocal.ql +++ b/java/ql/src/Violations of Best Practice/Dead Code/DeadStoreOfLocal.ql @@ -11,27 +11,30 @@ * readability * external/cwe/cwe-563 */ + import java import DeadLocals -predicate minusOne(MinusExpr e) { - e.getExpr().(Literal).getValue() = "1" -} +predicate minusOne(MinusExpr e) { e.getExpr().(Literal).getValue() = "1" } predicate flowStep(Expr decl, Expr init) { - decl = init or + decl = init + or exists(Field f | f.isFinal() and decl.(FieldAccess).getField() = f | init = f.getAnAssignedValue() - ) or + ) + or decl.(CastExpr).getExpr() = init } predicate excludedInit(Type t, Expr decl) { exists(Expr init | flowStep(decl, init) | // The `null` literal for reference types. - t instanceof RefType and init instanceof NullLiteral or + t instanceof RefType and init instanceof NullLiteral + or // The default value for primitive types. - init = t.(PrimitiveType).getADefaultValue() or + init = t.(PrimitiveType).getADefaultValue() + or // The expression `-1` for integral types. t instanceof IntegralType and minusOne(init) ) @@ -48,4 +51,5 @@ where excludedInit(decl.getVariable().getType(), decl.getInit()) ) select def, - "This assignment to " + v.getName() + " is useless: the value is always overwritten before it is read." + "This assignment to " + v.getName() + + " is useless: the value is always overwritten before it is read." diff --git a/java/ql/src/Violations of Best Practice/Dead Code/DeadStoreOfLocalUnread.ql b/java/ql/src/Violations of Best Practice/Dead Code/DeadStoreOfLocalUnread.ql index 46773ddbbd9..aabf70cda59 100644 --- a/java/ql/src/Violations of Best Practice/Dead Code/DeadStoreOfLocalUnread.ql +++ b/java/ql/src/Violations of Best Practice/Dead Code/DeadStoreOfLocalUnread.ql @@ -10,6 +10,7 @@ * @id java/useless-assignment-to-local * @tags external/cwe/cwe-561 */ + import java import DeadLocals @@ -23,5 +24,4 @@ where read(v) and not def.(AssignExpr).getSource() instanceof NullLiteral and (def instanceof Assignment or def.(UnaryAssignExpr).getParent() instanceof ExprStmt) -select - def, "This assignment to " + v.getName() + " is useless: the value is never read." +select def, "This assignment to " + v.getName() + " is useless: the value is never read." diff --git a/java/ql/src/Violations of Best Practice/Dead Code/EmptyFinalize.ql b/java/ql/src/Violations of Best Practice/Dead Code/EmptyFinalize.ql index c200e818af8..42018f9d4ef 100644 --- a/java/ql/src/Violations of Best Practice/Dead Code/EmptyFinalize.ql +++ b/java/ql/src/Violations of Best Practice/Dead Code/EmptyFinalize.ql @@ -10,12 +10,11 @@ * readability * external/cwe/cwe-568 */ + import java from FinalizeMethod finalize where finalize.fromSource() and - not exists(Stmt s | s.getEnclosingCallable() = finalize | - not s instanceof Block - ) + not exists(Stmt s | s.getEnclosingCallable() = finalize | not s instanceof Block) select finalize, "Empty finalize method." diff --git a/java/ql/src/Violations of Best Practice/Dead Code/FinalizerNullsFields.ql b/java/ql/src/Violations of Best Practice/Dead Code/FinalizerNullsFields.ql index 35a3b23ac14..9f0663b39ba 100644 --- a/java/ql/src/Violations of Best Practice/Dead Code/FinalizerNullsFields.ql +++ b/java/ql/src/Violations of Best Practice/Dead Code/FinalizerNullsFields.ql @@ -9,6 +9,7 @@ * @tags efficiency * maintainability */ + import java from FinalizeMethod m, Assignment assign, FieldAccess lhs, NullLiteral null diff --git a/java/ql/src/Violations of Best Practice/Dead Code/InterfaceCannotBeImplemented.ql b/java/ql/src/Violations of Best Practice/Dead Code/InterfaceCannotBeImplemented.ql index 8c1a1bf4741..adfc29e7a6e 100644 --- a/java/ql/src/Violations of Best Practice/Dead Code/InterfaceCannotBeImplemented.ql +++ b/java/ql/src/Violations of Best Practice/Dead Code/InterfaceCannotBeImplemented.ql @@ -24,6 +24,5 @@ where objMethod = protectedObjectMethod(method.getSignature()) and not hasSubtype*(objMethod.getReturnType(), method.getReturnType()) select method, - "This method's return type conflicts with Object." + method.getName() + " so $@ can never be implemented.", - impossible, - impossible.getName() + "This method's return type conflicts with Object." + method.getName() + + " so $@ can never be implemented.", impossible, impossible.getName() diff --git a/java/ql/src/Violations of Best Practice/Dead Code/LocalInitialisedButNotUsed.ql b/java/ql/src/Violations of Best Practice/Dead Code/LocalInitialisedButNotUsed.ql index e4989436d54..b0fefa93845 100644 --- a/java/ql/src/Violations of Best Practice/Dead Code/LocalInitialisedButNotUsed.ql +++ b/java/ql/src/Violations of Best Practice/Dead Code/LocalInitialisedButNotUsed.ql @@ -7,6 +7,7 @@ * @id java/unused-initialized-local * @tags external/cwe/cwe-563 */ + import java import DeadLocals @@ -18,4 +19,3 @@ where exists(ve.getInit()) and not exprHasNoEffect(ve.getInit()) select v, "Local variable " + v.getName() + " is never read or written to after it is initialised." - diff --git a/java/ql/src/Violations of Best Practice/Dead Code/LocalNotRead.ql b/java/ql/src/Violations of Best Practice/Dead Code/LocalNotRead.ql index 0ceff67dc6e..c1fb42e08d6 100644 --- a/java/ql/src/Violations of Best Practice/Dead Code/LocalNotRead.ql +++ b/java/ql/src/Violations of Best Practice/Dead Code/LocalNotRead.ql @@ -6,6 +6,7 @@ * @precision low * @id java/assigned-local-unread */ + import java import DeadLocals @@ -14,4 +15,3 @@ where assigned(v) and // Only assignments, not initialization not read(v) select v, "Local variable " + v.getName() + " is only assigned to, never read." - diff --git a/java/ql/src/Violations of Best Practice/Dead Code/NonAssignedFields.ql b/java/ql/src/Violations of Best Practice/Dead Code/NonAssignedFields.ql index 2b674d013f8..39b313fc78e 100644 --- a/java/ql/src/Violations of Best Practice/Dead Code/NonAssignedFields.ql +++ b/java/ql/src/Violations of Best Practice/Dead Code/NonAssignedFields.ql @@ -11,6 +11,7 @@ * useless-code * external/cwe/cwe-457 */ + import java import semmle.code.java.Reflection @@ -28,7 +29,8 @@ predicate isClassOf(ParameterizedClass c, RefType t) { predicate subjectToAtomicReferenceFieldUpdater(Field f) { exists(Class arfu, Method newUpdater, MethodAccess c | arfu.hasQualifiedName("java.util.concurrent.atomic", "AtomicReferenceFieldUpdater") and - newUpdater = arfu.getAMethod() and newUpdater.hasName("newUpdater") and + newUpdater = arfu.getAMethod() and + newUpdater.hasName("newUpdater") and c.getMethod().getSourceDeclaration() = newUpdater and isClassOf(c.getArgument(0).getType(), f.getDeclaringType()) and isClassOf(c.getArgument(1).getType(), f.getType()) and @@ -63,9 +65,7 @@ where f.fromSource() and fr.getField().getSourceDeclaration() = f and not f.getDeclaringType() instanceof EnumType and - forall(Assignment ae, Field g | - ae.getDest() = g.getAnAccess() and g.getSourceDeclaration() = f - | + forall(Assignment ae, Field g | ae.getDest() = g.getAnAccess() and g.getSourceDeclaration() = f | ae.getSource() instanceof NullLiteral ) and not exists(UnaryAssignExpr ua, Field g | @@ -86,5 +86,5 @@ where ) and // Exclude special VM classes. not isVMObserver(f.getDeclaringType()) -select f, "Field " + f.getName() + " never assigned non-null value, yet it is read at $@.", - fr, fr.getFile().getStem() + ".java:" + fr.getLocation().getStartLine() +select f, "Field " + f.getName() + " never assigned non-null value, yet it is read at $@.", fr, + fr.getFile().getStem() + ".java:" + fr.getLocation().getStartLine() diff --git a/java/ql/src/Violations of Best Practice/Dead Code/UnusedField.ql b/java/ql/src/Violations of Best Practice/Dead Code/UnusedField.ql index 114beaaabc8..b5cb9f1c3c1 100644 --- a/java/ql/src/Violations of Best Practice/Dead Code/UnusedField.ql +++ b/java/ql/src/Violations of Best Practice/Dead Code/UnusedField.ql @@ -9,6 +9,7 @@ * useless-code * external/cwe/cwe-561 */ + import java import semmle.code.java.Reflection import semmle.code.java.frameworks.Lombok diff --git a/java/ql/src/Violations of Best Practice/Dead Code/UnusedLocal.ql b/java/ql/src/Violations of Best Practice/Dead Code/UnusedLocal.ql index 482d5501d81..5f68dba3e02 100644 --- a/java/ql/src/Violations of Best Practice/Dead Code/UnusedLocal.ql +++ b/java/ql/src/Violations of Best Practice/Dead Code/UnusedLocal.ql @@ -7,6 +7,7 @@ * @id java/unused-local-variable * @tags external/cwe/cwe-563 */ + import java import DeadLocals @@ -28,4 +29,6 @@ where // Rules about catch clauses belong in an exception handling query not exceptionVariable(ve) and not enhancedForVariable(ve) -select v, "Unused local variable " + v.getName() + ". The variable is never read or written to and should be removed." +select v, + "Unused local variable " + v.getName() + + ". The variable is never read or written to and should be removed." diff --git a/java/ql/src/Violations of Best Practice/Declarations/BreakInSwitchCase.ql b/java/ql/src/Violations of Best Practice/Declarations/BreakInSwitchCase.ql index 68d4e1c23f1..bfcd7bdaf71 100644 --- a/java/ql/src/Violations of Best Practice/Declarations/BreakInSwitchCase.ql +++ b/java/ql/src/Violations of Best Practice/Declarations/BreakInSwitchCase.ql @@ -10,6 +10,7 @@ * readability * external/cwe/cwe-484 */ + import java import Common @@ -20,4 +21,5 @@ where not c.(ControlFlowNode).getASuccessor() instanceof DefaultCase and not s.(Annotatable).suppressesWarningsAbout("fallthrough") and mayDropThroughWithoutComment(s, c) -select c, "Switch case may fall through to the next case. Use a break or return to terminate this case." +select c, + "Switch case may fall through to the next case. Use a break or return to terminate this case." diff --git a/java/ql/src/Violations of Best Practice/Declarations/MakeImportsExplicit.ql b/java/ql/src/Violations of Best Practice/Declarations/MakeImportsExplicit.ql index 5137c48a696..a3d0054d63b 100644 --- a/java/ql/src/Violations of Best Practice/Declarations/MakeImportsExplicit.ql +++ b/java/ql/src/Violations of Best Practice/Declarations/MakeImportsExplicit.ql @@ -8,6 +8,7 @@ * @id java/implicit-import * @tags maintainability */ + import java from ImportOnDemandFromPackage i diff --git a/java/ql/src/Violations of Best Practice/Declarations/NoConstantsOnly.ql b/java/ql/src/Violations of Best Practice/Declarations/NoConstantsOnly.ql index 534c0eb3670..937102e9eb3 100644 --- a/java/ql/src/Violations of Best Practice/Declarations/NoConstantsOnly.ql +++ b/java/ql/src/Violations of Best Practice/Declarations/NoConstantsOnly.ql @@ -12,22 +12,17 @@ import semmle.code.java.Member -class ConstantField extends Field { - ConstantField() { - this.isStatic() and this.isFinal() - } -} +class ConstantField extends Field { ConstantField() { this.isStatic() and this.isFinal() } } pragma[noinline] -predicate typeWithConstantField(RefType t) { - exists(ConstantField f | f.getDeclaringType() = t) -} +predicate typeWithConstantField(RefType t) { exists(ConstantField f | f.getDeclaringType() = t) } class ConstantRefType extends RefType { ConstantRefType() { fromSource() and ( - this instanceof Interface or + this instanceof Interface + or this instanceof Class and this.isAbstract() ) and typeWithConstantField(this) and @@ -39,7 +34,8 @@ class ConstantRefType extends RefType { } string getKind() { - result = "interface" and this instanceof Interface or + result = "interface" and this instanceof Interface + or result = "class" and this instanceof Class } } @@ -50,5 +46,4 @@ where sub.getASupertype() = t and not sub instanceof ConstantRefType and sub = sub.getSourceDeclaration() -select sub, "Type " + sub.getName() + " implements constant " + t.getKind() + " $@.", - t, t.getName() +select sub, "Type " + sub.getName() + " implements constant " + t.getKind() + " $@.", t, t.getName() diff --git a/java/ql/src/Violations of Best Practice/Exception Handling/DroppedExceptions.ql b/java/ql/src/Violations of Best Practice/Exception Handling/DroppedExceptions.ql index 8a0fa7f02b8..728aa360955 100644 --- a/java/ql/src/Violations of Best Practice/Exception Handling/DroppedExceptions.ql +++ b/java/ql/src/Violations of Best Practice/Exception Handling/DroppedExceptions.ql @@ -11,6 +11,7 @@ * exceptions * external/cwe/cwe-391 */ + import java from CatchClause cc diff --git a/java/ql/src/Violations of Best Practice/Exception Handling/ExceptionCatch.ql b/java/ql/src/Violations of Best Practice/Exception Handling/ExceptionCatch.ql index 6d2c7fc776d..e3c4476e02f 100644 --- a/java/ql/src/Violations of Best Practice/Exception Handling/ExceptionCatch.ql +++ b/java/ql/src/Violations of Best Practice/Exception Handling/ExceptionCatch.ql @@ -9,10 +9,10 @@ * @tags reliability * external/cwe/cwe-396 */ + import java -private -predicate relevantTypeNames(string typeName, string message) { +private predicate relevantTypeNames(string typeName, string message) { // `Throwable` is the more severe case due to `Error`s such as `OutOfMemoryError`. typeName = "Throwable" and message = "Error" or @@ -20,18 +20,19 @@ predicate relevantTypeNames(string typeName, string message) { typeName = "Exception" and message = "RuntimeException" } -private -Type getAThrownExceptionType(TryStmt t) { +private Type getAThrownExceptionType(TryStmt t) { exists(MethodAccess ma, Exception e | t.getBlock() = ma.getEnclosingStmt().getParent*() and ma.getMethod().getAnException() = e and result = e.getType() - ) or + ) + or exists(ClassInstanceExpr cie, Exception e | t.getBlock() = cie.getEnclosingStmt().getParent*() and cie.getConstructor().getAnException() = e and result = e.getType() - ) or + ) + or exists(ThrowStmt ts | t.getBlock() = ts.getParent*() and result = ts.getExpr().getType() @@ -53,7 +54,6 @@ where not exists(Type et | et = getAThrownExceptionType(t) | et.(RefType).getASubtype*().hasQualifiedName("java.lang", typeName) ) -select - cc, - "Do not catch '" + cc.getVariable().getType() + "'" - + "; " + message + "s should normally be propagated." +select cc, + "Do not catch '" + cc.getVariable().getType() + "'" + "; " + message + + "s should normally be propagated." diff --git a/java/ql/src/Violations of Best Practice/Exception Handling/IgnoreExceptionalReturn.ql b/java/ql/src/Violations of Best Practice/Exception Handling/IgnoreExceptionalReturn.ql index b1c36234f68..fb7f2e34e18 100644 --- a/java/ql/src/Violations of Best Practice/Exception Handling/IgnoreExceptionalReturn.ql +++ b/java/ql/src/Violations of Best Practice/Exception Handling/IgnoreExceptionalReturn.ql @@ -10,6 +10,7 @@ * correctness * external/cwe/cwe-391 */ + import java class SpecialMethod extends Method { @@ -23,14 +24,21 @@ class SpecialMethod extends Method { predicate unboundedQueue(RefType t) { exists(string pack, string clss | t.getASupertype*().getSourceDeclaration().hasQualifiedName(pack, clss) - | - pack = "java.util" and clss = "ArrayDeque" or - pack = "java.util" and clss = "LinkedList" or - pack = "java.util" and clss = "PriorityQueue" or - pack = "java.util.concurrent" and clss = "ConcurrentLinkedQueue" or - pack = "java.util.concurrent" and clss = "ConcurrentLinkedDeque" or - pack = "java.util.concurrent" and clss = "DelayQueue" or - pack = "java.util.concurrent" and clss = "LinkedTransferQueue" or + | + pack = "java.util" and clss = "ArrayDeque" + or + pack = "java.util" and clss = "LinkedList" + or + pack = "java.util" and clss = "PriorityQueue" + or + pack = "java.util.concurrent" and clss = "ConcurrentLinkedQueue" + or + pack = "java.util.concurrent" and clss = "ConcurrentLinkedDeque" + or + pack = "java.util.concurrent" and clss = "DelayQueue" + or + pack = "java.util.concurrent" and clss = "LinkedTransferQueue" + or pack = "java.util.concurrent" and clss = "PriorityBlockingQueue" ) } @@ -40,21 +48,37 @@ where ma.getParent() instanceof ExprStmt and m = ma.getMethod() and ( - m.isMethod("java.util", "Queue", "offer", 1) and not unboundedQueue(m.getDeclaringType()) or - m.isMethod("java.util.concurrent", "BlockingQueue", "offer", 3) and not unboundedQueue(m.getDeclaringType()) or - m.isMethod("java.util.concurrent.locks", "Condition", "await", 2) or - m.isMethod("java.util.concurrent.locks", "Condition", "awaitUntil", 1) or - m.isMethod("java.util.concurrent.locks", "Condition", "awaitNanos", 1) or - m.isMethod("java.io", "File", "createNewFile", 0) or - m.isMethod("java.io", "File", "mkdir", 0) or - m.isMethod("java.io", "File", "renameTo", 1) or - m.isMethod("java.io", "File", "setLastModified", 1) or - m.isMethod("java.io", "File", "setReadOnly", 0) or - m.isMethod("java.io", "File", "setWritable", 1) or - m.isMethod("java.io", "File", "setWritable", 2) or - m.isMethod("java.io", "InputStream", "skip", 1) or - m.isMethod("java.io", "InputStream", "read", 1) or + m.isMethod("java.util", "Queue", "offer", 1) and not unboundedQueue(m.getDeclaringType()) + or + m.isMethod("java.util.concurrent", "BlockingQueue", "offer", 3) and + not unboundedQueue(m.getDeclaringType()) + or + m.isMethod("java.util.concurrent.locks", "Condition", "await", 2) + or + m.isMethod("java.util.concurrent.locks", "Condition", "awaitUntil", 1) + or + m.isMethod("java.util.concurrent.locks", "Condition", "awaitNanos", 1) + or + m.isMethod("java.io", "File", "createNewFile", 0) + or + m.isMethod("java.io", "File", "mkdir", 0) + or + m.isMethod("java.io", "File", "renameTo", 1) + or + m.isMethod("java.io", "File", "setLastModified", 1) + or + m.isMethod("java.io", "File", "setReadOnly", 0) + or + m.isMethod("java.io", "File", "setWritable", 1) + or + m.isMethod("java.io", "File", "setWritable", 2) + or + m.isMethod("java.io", "InputStream", "skip", 1) + or + m.isMethod("java.io", "InputStream", "read", 1) + or m.isMethod("java.io", "InputStream", "read", 3) ) -select ma, "Method " + ma.getEnclosingCallable().getName() + " ignores exceptional return value of " - + ma.getMethod().getDeclaringType().getName() + "." + ma.getMethod().getName() + "." +select ma, + "Method " + ma.getEnclosingCallable().getName() + " ignores exceptional return value of " + + ma.getMethod().getDeclaringType().getName() + "." + ma.getMethod().getName() + "." diff --git a/java/ql/src/Violations of Best Practice/Implementation Hiding/AbstractToConcreteCollection.ql b/java/ql/src/Violations of Best Practice/Implementation Hiding/AbstractToConcreteCollection.ql index 009e0800dfa..20ad661369e 100644 --- a/java/ql/src/Violations of Best Practice/Implementation Hiding/AbstractToConcreteCollection.ql +++ b/java/ql/src/Violations of Best Practice/Implementation Hiding/AbstractToConcreteCollection.ql @@ -11,23 +11,20 @@ * modularity * external/cwe/cwe-485 */ + import java import semmle.code.java.Collections predicate guardedByInstanceOf(VarAccess e, RefType t) { exists(IfStmt s, InstanceOfExpr instanceCheck, Type checkType | - s.getCondition() = instanceCheck - and - instanceCheck.getTypeName().getType() = checkType - and + s.getCondition() = instanceCheck and + instanceCheck.getTypeName().getType() = checkType and // The same variable appears as the subject of the `instanceof`. - instanceCheck.getExpr() = e.getVariable().getAnAccess() - and + instanceCheck.getExpr() = e.getVariable().getAnAccess() and // The checked type is either the type itself, or a raw version. For example, it is usually // fine to check for `x instanceof ArrayList` and then cast to `ArrayList`, because // the generic parameter is usually known. - (checkType = t or checkType = t.getSourceDeclaration().(GenericType).getRawType()) - and + (checkType = t or checkType = t.getSourceDeclaration().(GenericType).getRawType()) and // The expression appears in one of the branches. // (We do not verify here whether the guard is correctly implemented.) exists(Stmt branch | branch = s.getThen() or branch = s.getElse() | @@ -53,8 +50,10 @@ where not e.getEnclosingCallable().suppressesWarningsAbout("unchecked") and // Report the qualified names if the names are the same. if coll.getName() = c.getName() - then (abstractName = coll.getQualifiedName() and concreteName = c.getQualifiedName()) - else (abstractName = coll.getName() and concreteName = c.getName()) -select e, "$@ is cast to the concrete type $@, losing abstraction.", - coll.getSourceDeclaration(), abstractName, - c.getSourceDeclaration(), concreteName + then ( + abstractName = coll.getQualifiedName() and concreteName = c.getQualifiedName() + ) else ( + abstractName = coll.getName() and concreteName = c.getName() + ) +select e, "$@ is cast to the concrete type $@, losing abstraction.", coll.getSourceDeclaration(), + abstractName, c.getSourceDeclaration(), concreteName diff --git a/java/ql/src/Violations of Best Practice/Implementation Hiding/ExposeRepresentation.ql b/java/ql/src/Violations of Best Practice/Implementation Hiding/ExposeRepresentation.ql index f64bcb926b5..d13edff4d4a 100644 --- a/java/ql/src/Violations of Best Practice/Implementation Hiding/ExposeRepresentation.ql +++ b/java/ql/src/Violations of Best Practice/Implementation Hiding/ExposeRepresentation.ql @@ -11,11 +11,13 @@ * modularity * external/cwe/cwe-485 */ + import java import semmle.code.java.dataflow.DefUse predicate relevantType(RefType t) { - t instanceof Array or + t instanceof Array + or exists(RefType sup | sup = t.getASupertype*().getSourceDeclaration() | sup.hasQualifiedName("java.util", "Map") or sup.hasQualifiedName("java.util", "Collection") @@ -23,12 +25,18 @@ predicate relevantType(RefType t) { } predicate modifyMethod(Method m) { - relevantType(m.getDeclaringType()) and ( - m.hasName("add") or m.hasName("addAll") or - m.hasName("put") or m.hasName("putAll") or - m.hasName("push") or m.hasName("pop") or - m.hasName("remove") or m.hasName("removeAll") or - m.hasName("clear") or m.hasName("set") + relevantType(m.getDeclaringType()) and + ( + m.hasName("add") or + m.hasName("addAll") or + m.hasName("put") or + m.hasName("putAll") or + m.hasName("push") or + m.hasName("pop") or + m.hasName("remove") or + m.hasName("removeAll") or + m.hasName("clear") or + m.hasName("set") ) } @@ -47,25 +55,25 @@ predicate returnsArray(Callable c, Field f) { } predicate mayWriteToArray(Expr modified) { - writesToArray(modified) or - + writesToArray(modified) + or // x = __y__; x[0] = 1; exists(AssignExpr e, LocalVariableDecl v | e.getDest() = v.getAnAccess() | modified = e.getSource() and mayWriteToArray(v.getAnAccess()) - ) or - + ) + or // int[] x = __y__; x[0] = 1; exists(LocalVariableDeclExpr e, Variable v | e.getVariable() = v | modified = e.getInit() and mayWriteToArray(v.getAnAccess()) - ) or - + ) + or // return __array__; ... method()[1] = 0 exists(ReturnStmt rs | modified = rs.getResult() and relevantType(modified.getType()) | exists(Callable enclosing, MethodAccess ma | enclosing = rs.getEnclosingCallable() and ma.getMethod() = enclosing - | + | mayWriteToArray(ma) ) ) @@ -74,8 +82,9 @@ predicate mayWriteToArray(Expr modified) { predicate writesToArray(Expr array) { relevantType(array.getType()) and ( - exists(Assignment a, ArrayAccess access | a.getDest() = access | access.getArray() = array)) or - exists(MethodAccess ma | ma.getQualifier() = array | modifyMethod(ma.getMethod()) + exists(Assignment a, ArrayAccess access | a.getDest() = access | access.getArray() = array) + or + exists(MethodAccess ma | ma.getQualifier() = array | modifyMethod(ma.getMethod())) ) } @@ -85,14 +94,14 @@ VarAccess modificationAfter(VarAccess v) { } VarAccess varPassedInto(Callable c, int i) { - exists(Call call | call.getCallee() = c | - call.getArgument(i) = result - ) + exists(Call call | call.getCallee() = c | call.getArgument(i) = result) } predicate exposesByReturn(Callable c, Field f, Expr why, string whyText) { returnsArray(c, f) and - exists(MethodAccess ma | ma.getMethod() = c and ma.getCompilationUnit() != c.getCompilationUnit() | + exists(MethodAccess ma | + ma.getMethod() = c and ma.getCompilationUnit() != c.getCompilationUnit() + | mayWriteToArray(ma) and why = ma and whyText = "after this call to " + c.getName() @@ -113,6 +122,6 @@ from Callable c, Field f, Expr why, string whyText where exposesByReturn(c, f, why, whyText) or exposesByStore(c, f, why, whyText) -select c, c.getName() + " exposes the internal representation stored in field " + f.getName() + - ". The value may be modified $@.", - why.getLocation(), whyText +select c, + c.getName() + " exposes the internal representation stored in field " + f.getName() + + ". The value may be modified $@.", why.getLocation(), whyText diff --git a/java/ql/src/Violations of Best Practice/Implementation Hiding/GetClassGetResource.ql b/java/ql/src/Violations of Best Practice/Implementation Hiding/GetClassGetResource.ql index 979a14a40fe..391af6f6664 100644 --- a/java/ql/src/Violations of Best Practice/Implementation Hiding/GetClassGetResource.ql +++ b/java/ql/src/Violations of Best Practice/Implementation Hiding/GetClassGetResource.ql @@ -9,6 +9,7 @@ * @tags reliability * maintainability */ + import java /** Access to a method in `this` object. */ diff --git a/java/ql/src/Violations of Best Practice/Implementation Hiding/StaticArray.ql b/java/ql/src/Violations of Best Practice/Implementation Hiding/StaticArray.ql index f5ce6800cae..069eadc22ff 100644 --- a/java/ql/src/Violations of Best Practice/Implementation Hiding/StaticArray.ql +++ b/java/ql/src/Violations of Best Practice/Implementation Hiding/StaticArray.ql @@ -9,6 +9,7 @@ * modularity * external/cwe/cwe-582 */ + import java predicate nonEmptyArrayLiteralOrNull(Expr e) { @@ -39,7 +40,5 @@ where f.isFinal() and f.getType() instanceof Array and f.fromSource() and - forall(AssignExpr a | a.getDest() = f.getAnAccess() | - nonEmptyArrayLiteralOrNull(a.getSource()) - ) + forall(AssignExpr a | a.getDest() = f.getAnAccess() | nonEmptyArrayLiteralOrNull(a.getSource())) select f, "The array constant " + f.getName() + " is vulnerable to mutation." diff --git a/java/ql/src/Violations of Best Practice/Magic Constants/MagicConstantsNumbers.ql b/java/ql/src/Violations of Best Practice/Magic Constants/MagicConstantsNumbers.ql index b60fd486f3c..ae0589545ed 100644 --- a/java/ql/src/Violations of Best Practice/Magic Constants/MagicConstantsNumbers.ql +++ b/java/ql/src/Violations of Best Practice/Magic Constants/MagicConstantsNumbers.ql @@ -10,6 +10,7 @@ * statistical * non-attributable */ + import java import MagicConstants diff --git a/java/ql/src/Violations of Best Practice/Magic Constants/MagicConstantsString.ql b/java/ql/src/Violations of Best Practice/Magic Constants/MagicConstantsString.ql index 3e69696daa4..acab4ac3e8b 100644 --- a/java/ql/src/Violations of Best Practice/Magic Constants/MagicConstantsString.ql +++ b/java/ql/src/Violations of Best Practice/Magic Constants/MagicConstantsString.ql @@ -10,6 +10,7 @@ * statistical * non-attributable */ + import java import MagicConstants @@ -51,19 +52,23 @@ predicate isSystemProperty(string e) { predicate trivialContext(Literal e) { // String concatenation. - e.getParent() instanceof AddExpr or - e.getParent() instanceof AssignAddExpr or + e.getParent() instanceof AddExpr + or + e.getParent() instanceof AssignAddExpr + or exists(MethodAccess ma | ma.getMethod().getName() = "append" and (e = ma.getAnArgument() or e = ma.getQualifier()) - ) or + ) + or // Standard property in a call to `System.getProperty()`. exists(MethodAccess ma | ma.getMethod().getName() = "getProperty" and e = ma.getAnArgument() and ma.getMethod().getDeclaringType() instanceof TypeSystem and isSystemProperty(e.getValue()) - ) or + ) + or // Message in an exception. exists(ClassInstanceExpr constr | constr.getType().(RefType).getASupertype+().hasName("Exception") and diff --git a/java/ql/src/Violations of Best Practice/Magic Constants/MagicNumbersUseConstant.ql b/java/ql/src/Violations of Best Practice/Magic Constants/MagicNumbersUseConstant.ql index 5f030dd7da8..b274f3f66e1 100644 --- a/java/ql/src/Violations of Best Practice/Magic Constants/MagicNumbersUseConstant.ql +++ b/java/ql/src/Violations of Best Practice/Magic Constants/MagicNumbersUseConstant.ql @@ -9,6 +9,7 @@ * @tags maintainability * readability */ + import java import MagicConstants diff --git a/java/ql/src/Violations of Best Practice/Magic Constants/MagicStringsUseConstant.ql b/java/ql/src/Violations of Best Practice/Magic Constants/MagicStringsUseConstant.ql index e255165848f..84bde8242ac 100644 --- a/java/ql/src/Violations of Best Practice/Magic Constants/MagicStringsUseConstant.ql +++ b/java/ql/src/Violations of Best Practice/Magic Constants/MagicStringsUseConstant.ql @@ -9,6 +9,7 @@ * @tags maintainability * readability */ + import java import MagicConstants diff --git a/java/ql/src/Violations of Best Practice/Naming Conventions/AmbiguousOuterSuper.ql b/java/ql/src/Violations of Best Practice/Naming Conventions/AmbiguousOuterSuper.ql index cb9791add95..ec71b1207fa 100644 --- a/java/ql/src/Violations of Best Practice/Naming Conventions/AmbiguousOuterSuper.ql +++ b/java/ql/src/Violations of Best Practice/Naming Conventions/AmbiguousOuterSuper.ql @@ -9,14 +9,14 @@ * @tags reliability * readability */ + import java RefType nestedSupertypePlus(RefType t) { t.getASourceSupertype() = result and - t instanceof NestedType or - exists(RefType mid | mid = nestedSupertypePlus(t) | - mid.getASourceSupertype() = result - ) + t instanceof NestedType + or + exists(RefType mid | mid = nestedSupertypePlus(t) | mid.getASourceSupertype() = result) } /** @@ -38,10 +38,8 @@ predicate callToInheritedMethod(RefType lexicalScope, MethodAccess ma, string si * classes "on-route" can be static. */ Method methodInEnclosingType(NestedType nested, string signature) { - (result.isStatic() or not nested.isStatic()) - and - result.getSignature() = signature - and + (result.isStatic() or not nested.isStatic()) and + result.getSignature() = signature and exists(RefType outer | outer = nested.getEnclosingType() | result = outer.getAMethod() or result = methodInEnclosingType(nested, signature) @@ -54,6 +52,5 @@ where m = methodInEnclosingType(nt, signature) and // There is actually scope for confusion. not nt.getASourceSupertype+() = m.getDeclaringType() -select ma, "A $@ is called instead of a $@.", - ma.getMethod(), "method declared in a superclass", - m, "method with the same signature in an enclosing class" +select ma, "A $@ is called instead of a $@.", ma.getMethod(), "method declared in a superclass", m, + "method with the same signature in an enclosing class" diff --git a/java/ql/src/Violations of Best Practice/Naming Conventions/ConfusingMethodNames.ql b/java/ql/src/Violations of Best Practice/Naming Conventions/ConfusingMethodNames.ql index 27f5561be57..1c44dad78cc 100644 --- a/java/ql/src/Violations of Best Practice/Naming Conventions/ConfusingMethodNames.ql +++ b/java/ql/src/Violations of Best Practice/Naming Conventions/ConfusingMethodNames.ql @@ -10,6 +10,7 @@ * readability * naming */ + import java predicate methodTypeAndLowerCaseName(Method m, RefType t, string name) { diff --git a/java/ql/src/Violations of Best Practice/Naming Conventions/ConfusingOverloading.ql b/java/ql/src/Violations of Best Practice/Naming Conventions/ConfusingOverloading.ql index cd754096245..07c071ad2d4 100644 --- a/java/ql/src/Violations of Best Practice/Naming Conventions/ConfusingOverloading.ql +++ b/java/ql/src/Violations of Best Practice/Naming Conventions/ConfusingOverloading.ql @@ -11,16 +11,16 @@ * readability * naming */ + import java -private pragma[nomagic] -predicate confusingPrimitiveBoxedTypes(Type t, Type u) { +pragma[nomagic] +private predicate confusingPrimitiveBoxedTypes(Type t, Type u) { t.(PrimitiveType).getBoxedType() = u or u.(PrimitiveType).getBoxedType() = t } -private -predicate overloadedMethods(Method n, Method m) { +private predicate overloadedMethods(Method n, Method m) { n.fromSource() and exists(RefType rt, string name, int numParams | candidateMethod(rt, m, name, numParams) and @@ -30,12 +30,11 @@ predicate overloadedMethods(Method n, Method m) { n.getSourceDeclaration().getSignature() < m.getSourceDeclaration().getSignature() } -private -predicate overloadedMethodsMostSpecific(Method n, Method m) { +private predicate overloadedMethodsMostSpecific(Method n, Method m) { overloadedMethods(n, m) and not exists(Method nSup, Method mSup | n.overridesOrInstantiates*(nSup) and m.overridesOrInstantiates*(mSup) - | + | overloadedMethods(nSup, mSup) and (n != nSup or m != mSup) ) @@ -45,16 +44,13 @@ predicate overloadedMethodsMostSpecific(Method n, Method m) { * A whitelist of names that are commonly overloaded in odd ways and should * not be reported by this query. */ -private predicate whitelist(string name) { - name = "visit" -} +private predicate whitelist(string name) { name = "visit" } /** * Method `m` has name `name`, number of parameters `numParams` * and is declared in `t` or inherited from a supertype of `t`. */ -private -predicate candidateMethod(RefType t, Method m, string name, int numParam) { +private predicate candidateMethod(RefType t, Method m, string name, int numParam) { exists(Method n | n.getSourceDeclaration() = m | t.inherits(n)) and m.getName() = name and m.getNumberOfParameters() = numParam and @@ -63,22 +59,21 @@ predicate candidateMethod(RefType t, Method m, string name, int numParam) { not whitelist(name) } -private pragma[inline] -predicate potentiallyConfusingTypes(Type a, Type b) { +pragma[inline] +private predicate potentiallyConfusingTypes(Type a, Type b) { exists(RefType commonSubtype | hasSubtypeOrInstantiation*(a, commonSubtype) | hasSubtypeOrInstantiation*(b, commonSubtype) - ) or + ) + or confusingPrimitiveBoxedTypes(a, b) } -private -predicate hasSubtypeOrInstantiation(RefType t, RefType sub) { +private predicate hasSubtypeOrInstantiation(RefType t, RefType sub) { hasSubtype(t, sub) or sub.getSourceDeclaration() = t } -private -predicate confusinglyOverloaded(Method m, Method n) { +private predicate confusinglyOverloaded(Method m, Method n) { overloadedMethodsMostSpecific(n, m) and forall(int i, Parameter p, Parameter q | p = n.getParameter(i) and q = m.getParameter(i) | potentiallyConfusingTypes(p.getType(), q.getType()) @@ -87,15 +82,13 @@ predicate confusinglyOverloaded(Method m, Method n) { not exists(Method target | delegate*(m, target) and delegate*(n, target)) } -private -predicate wrappedAccess(Expr e, MethodAccess ma) { +private predicate wrappedAccess(Expr e, MethodAccess ma) { e = ma or wrappedAccess(e.(ParExpr).getExpr(), ma) or wrappedAccess(e.(CastExpr).getExpr(), ma) } -private -predicate delegate(Method caller, Method callee) { +private predicate delegate(Method caller, Method callee) { exists(MethodAccess ma | ma.getMethod() = callee | exists(Stmt stmt | stmt = caller.getBody().(SingletonBlock).getStmt() | wrappedAccess(stmt.(ExprStmt).getExpr(), ma) or @@ -103,7 +96,8 @@ predicate delegate(Method caller, Method callee) { ) and forex(Parameter p, int i, Expr arg | p = caller.getParameter(i) and ma.getArgument(i) = arg | // The parameter is propagated without modification. - arg = p.getAnAccess() or + arg = p.getAnAccess() + or // The parameter is cast to a supertype. arg.(CastExpr).getExpr() = p.getAnAccess() and arg.getType().(RefType).getASubtype() = p.getType() @@ -114,10 +108,12 @@ predicate delegate(Method caller, Method callee) { from Method m, Method n, string messageQualifier where confusinglyOverloaded(m, n) and - (if m.getDeclaringType() = n.getDeclaringType() - then messageQualifier = "" - else messageQualifier = m.getDeclaringType().getName() + ".") -select n, "Method " + n.getDeclaringType() + "." + n + - "(..) could be confused with overloaded method $@, since dispatch depends on static types.", - m.getSourceDeclaration(), messageQualifier + m.getName() - + ( + if m.getDeclaringType() = n.getDeclaringType() + then messageQualifier = "" + else messageQualifier = m.getDeclaringType().getName() + "." + ) +select n, + "Method " + n.getDeclaringType() + "." + n + + "(..) could be confused with overloaded method $@, since dispatch depends on static types.", + m.getSourceDeclaration(), messageQualifier + m.getName() diff --git a/java/ql/src/Violations of Best Practice/Naming Conventions/ConfusingOverridesNames.ql b/java/ql/src/Violations of Best Practice/Naming Conventions/ConfusingOverridesNames.ql index caeca946f07..62c4ca3ed2c 100644 --- a/java/ql/src/Violations of Best Practice/Naming Conventions/ConfusingOverridesNames.ql +++ b/java/ql/src/Violations of Best Practice/Naming Conventions/ConfusingOverridesNames.ql @@ -10,6 +10,7 @@ * readability * naming */ + import java /** @@ -71,5 +72,5 @@ where notConfusing.getName() = m2.getName() ) select m1, - "It is confusing to have methods " + m1.getName() + " in " + m1.getDeclaringType().getName() + " and " - + m2.getName() + " in " + m2.getDeclaringType().getName() + "." + "It is confusing to have methods " + m1.getName() + " in " + m1.getDeclaringType().getName() + + " and " + m2.getName() + " in " + m2.getDeclaringType().getName() + "." diff --git a/java/ql/src/Violations of Best Practice/Naming Conventions/FieldMasksSuperField.ql b/java/ql/src/Violations of Best Practice/Naming Conventions/FieldMasksSuperField.ql index 37d745a3410..a786facaa1b 100644 --- a/java/ql/src/Violations of Best Practice/Naming Conventions/FieldMasksSuperField.ql +++ b/java/ql/src/Violations of Best Practice/Naming Conventions/FieldMasksSuperField.ql @@ -10,6 +10,7 @@ * @tags maintainability * readability */ + import java class VisibleInstanceField extends Field { @@ -19,17 +20,14 @@ class VisibleInstanceField extends Field { } } -from RefType type, RefType supertype, - VisibleInstanceField masked, VisibleInstanceField masking +from RefType type, RefType supertype, VisibleInstanceField masked, VisibleInstanceField masking where type.getASourceSupertype+() = supertype and masking.getDeclaringType() = type and masked.getDeclaringType() = supertype and masked.getName() = masking.getName() and // Exclude intentional masking. - not exists(VarAccess va | va.getVariable() = masked | - va.getQualifier() instanceof SuperAccess - ) and + not exists(VarAccess va | va.getVariable() = masked | va.getQualifier() instanceof SuperAccess) and type.fromSource() -select masking, "This field shadows another field called $@ in a superclass.", - masked, masked.getName() +select masking, "This field shadows another field called $@ in a superclass.", masked, + masked.getName() diff --git a/java/ql/src/Violations of Best Practice/Naming Conventions/LocalShadowsField.ql b/java/ql/src/Violations of Best Practice/Naming Conventions/LocalShadowsField.ql index bea931366cb..b033cf3100c 100644 --- a/java/ql/src/Violations of Best Practice/Naming Conventions/LocalShadowsField.ql +++ b/java/ql/src/Violations of Best Practice/Naming Conventions/LocalShadowsField.ql @@ -8,6 +8,7 @@ * @id java/local-shadows-field-unused * @tags maintainability */ + import java import Shadowing @@ -16,8 +17,8 @@ where shadows(d, c, f, callable) and not assignmentToShadowingLocal(d, f) and not assignmentFromShadowingLocal(d, f) and - not thisAccess(d, f) and not confusingAccess(d, f) and + not thisAccess(d, f) and + not confusingAccess(d, f) and (if callable instanceof Constructor then callableType = "" else callableType = "method ") -select - d, "This local variable shadows field $@, which is not used in " + callableType + "$@.", - f, f.getName(), callable, callable.getName() +select d, "This local variable shadows field $@, which is not used in " + callableType + "$@.", f, + f.getName(), callable, callable.getName() diff --git a/java/ql/src/Violations of Best Practice/Naming Conventions/LocalShadowsFieldConfusing.ql b/java/ql/src/Violations of Best Practice/Naming Conventions/LocalShadowsFieldConfusing.ql index 75b99c9ae4b..3f4867c8224 100644 --- a/java/ql/src/Violations of Best Practice/Naming Conventions/LocalShadowsFieldConfusing.ql +++ b/java/ql/src/Violations of Best Practice/Naming Conventions/LocalShadowsFieldConfusing.ql @@ -9,6 +9,7 @@ * @tags maintainability * readability */ + import java import Shadowing @@ -17,16 +18,15 @@ where shadows(d, c, f, callable) and not assignmentToShadowingLocal(d, f) and not assignmentFromShadowingLocal(d, f) and - (if callable instanceof Constructor - then callableType = "" - else callableType = "method ") and + (if callable instanceof Constructor then callableType = "" else callableType = "method ") and ( confusingAccess(d, f) and message = "Confusing name: " + callableType + - "$@ also refers to field $@ (without qualifying it with 'this')." + "$@ also refers to field $@ (without qualifying it with 'this')." or - thisAccess(d, f) and not confusingAccess(d, f) and - message = "Potentially confusing name: " + callableType + - "$@ also refers to field $@ (as this." + f.getName() + ")." + thisAccess(d, f) and + not confusingAccess(d, f) and + message = "Potentially confusing name: " + callableType + "$@ also refers to field $@ (as this." + + f.getName() + ")." ) select d, message, callable, callable.getName(), f, f.getName() diff --git a/java/ql/src/Violations of Best Practice/Naming Conventions/SameNameAsSuper.ql b/java/ql/src/Violations of Best Practice/Naming Conventions/SameNameAsSuper.ql index 4ac08aeb8ca..79f5f2cf473 100644 --- a/java/ql/src/Violations of Best Practice/Naming Conventions/SameNameAsSuper.ql +++ b/java/ql/src/Violations of Best Practice/Naming Conventions/SameNameAsSuper.ql @@ -9,6 +9,7 @@ * readability * naming */ + import java from RefType sub, RefType sup @@ -16,6 +17,4 @@ where sub.fromSource() and sup = sub.getASupertype() and sub.getName() = sup.getName() -select - sub, sub.getName() + " has the same name as its supertype $@.", - sup, sup.getQualifiedName() +select sub, sub.getName() + " has the same name as its supertype $@.", sup, sup.getQualifiedName() diff --git a/java/ql/src/Violations of Best Practice/Undesirable Calls/CallsToRunFinalizersOnExit.ql b/java/ql/src/Violations of Best Practice/Undesirable Calls/CallsToRunFinalizersOnExit.ql index 53d484bec6a..0ee14f58b70 100644 --- a/java/ql/src/Violations of Best Practice/Undesirable Calls/CallsToRunFinalizersOnExit.ql +++ b/java/ql/src/Violations of Best Practice/Undesirable Calls/CallsToRunFinalizersOnExit.ql @@ -10,6 +10,7 @@ * @tags reliability * maintainability */ + import java from MethodAccess ma, Method runfinalizers, Class c diff --git a/java/ql/src/Violations of Best Practice/Undesirable Calls/CallsToStringToString.ql b/java/ql/src/Violations of Best Practice/Undesirable Calls/CallsToStringToString.ql index dda46d4f30d..40a4e36d70c 100644 --- a/java/ql/src/Violations of Best Practice/Undesirable Calls/CallsToStringToString.ql +++ b/java/ql/src/Violations of Best Practice/Undesirable Calls/CallsToStringToString.ql @@ -7,6 +7,7 @@ * @id java/useless-tostring-call * @tags maintainability */ + import java from MethodAccess ma, Method tostring diff --git a/java/ql/src/Violations of Best Practice/Undesirable Calls/CallsToSystemExit.ql b/java/ql/src/Violations of Best Practice/Undesirable Calls/CallsToSystemExit.ql index 0921436ddcf..387098d23b7 100644 --- a/java/ql/src/Violations of Best Practice/Undesirable Calls/CallsToSystemExit.ql +++ b/java/ql/src/Violations of Best Practice/Undesirable Calls/CallsToSystemExit.ql @@ -10,6 +10,7 @@ * maintainability * external/cwe/cwe-382 */ + import java from Method m, MethodAccess sysexitCall, Method sysexit, Class system @@ -17,7 +18,8 @@ where sysexitCall = m.getACallSite(sysexit) and (sysexit.hasName("exit") or sysexit.hasName("halt")) and sysexit.getDeclaringType() = system and - ( system.hasQualifiedName("java.lang", "System") or + ( + system.hasQualifiedName("java.lang", "System") or system.hasQualifiedName("java.lang", "Runtime") ) and m.fromSource() and diff --git a/java/ql/src/Violations of Best Practice/Undesirable Calls/DefaultToString.ql b/java/ql/src/Violations of Best Practice/Undesirable Calls/DefaultToString.ql index 826fc9df913..7d9ef5b85f9 100644 --- a/java/ql/src/Violations of Best Practice/Undesirable Calls/DefaultToString.ql +++ b/java/ql/src/Violations of Best Practice/Undesirable Calls/DefaultToString.ql @@ -9,6 +9,7 @@ * @tags reliability * maintainability */ + import java import semmle.code.java.StringFormat @@ -58,5 +59,6 @@ where bad(sourceType) and not sourceType.isAbstract() and sourceType.fromSource() -select e, "Default toString(): " + e.getType().getName() + - " inherits toString() from Object, and so is not suitable for printing." +select e, + "Default toString(): " + e.getType().getName() + + " inherits toString() from Object, and so is not suitable for printing." diff --git a/java/ql/src/Violations of Best Practice/Undesirable Calls/GarbageCollection.ql b/java/ql/src/Violations of Best Practice/Undesirable Calls/GarbageCollection.ql index f48e6d00b1e..f30dd30759f 100644 --- a/java/ql/src/Violations of Best Practice/Undesirable Calls/GarbageCollection.ql +++ b/java/ql/src/Violations of Best Practice/Undesirable Calls/GarbageCollection.ql @@ -9,6 +9,7 @@ * @tags reliability * maintainability */ + import java from MethodAccess mc, Method m diff --git a/java/ql/src/Violations of Best Practice/Undesirable Calls/NextFromIterator.ql b/java/ql/src/Violations of Best Practice/Undesirable Calls/NextFromIterator.ql index 1bc74ae7724..7c78ffeb712 100644 --- a/java/ql/src/Violations of Best Practice/Undesirable Calls/NextFromIterator.ql +++ b/java/ql/src/Violations of Best Practice/Undesirable Calls/NextFromIterator.ql @@ -9,6 +9,7 @@ * @tags reliability * correctness */ + import java from MethodAccess m diff --git a/java/ql/src/Violations of Best Practice/Undesirable Calls/PrintLnArray.ql b/java/ql/src/Violations of Best Practice/Undesirable Calls/PrintLnArray.ql index 077de8b19e6..d778dc4ce7a 100644 --- a/java/ql/src/Violations of Best Practice/Undesirable Calls/PrintLnArray.ql +++ b/java/ql/src/Violations of Best Practice/Undesirable Calls/PrintLnArray.ql @@ -8,6 +8,7 @@ * @id java/print-array * @tags maintainability */ + import java import semmle.code.java.StringFormat @@ -22,6 +23,7 @@ predicate arraysToStringArgument(Expr e) { m.hasName("toString") ) } + from Expr arr where arr.getType() instanceof Array and diff --git a/java/ql/src/Violations of Best Practice/legacy/AutoBoxing.ql b/java/ql/src/Violations of Best Practice/legacy/AutoBoxing.ql index 5cb5a443e24..6b865844b4b 100644 --- a/java/ql/src/Violations of Best Practice/legacy/AutoBoxing.ql +++ b/java/ql/src/Violations of Best Practice/legacy/AutoBoxing.ql @@ -12,28 +12,19 @@ import java /** An expression of primitive type. */ -class PrimitiveExpr extends Expr { - PrimitiveExpr() { - this.getType() instanceof PrimitiveType - } -} +class PrimitiveExpr extends Expr { PrimitiveExpr() { this.getType() instanceof PrimitiveType } } /** An expression of boxed type. */ -class BoxedExpr extends Expr { - BoxedExpr() { - this.getType() instanceof BoxedType - } -} +class BoxedExpr extends Expr { BoxedExpr() { this.getType() instanceof BoxedType } } /** * Relate expressions and the variables they flow into in one step, * either by assignment or parameter passing. */ Variable flowTarget(Expr arg) { - arg = result.getAnAssignedValue() or - exists(Call c, int i | - c.getArgument(i) = arg and result = c.getCallee().getParameter(i) - ) + arg = result.getAnAssignedValue() + or + exists(Call c, int i | c.getArgument(i) = arg and result = c.getCallee().getParameter(i)) } /** @@ -41,15 +32,12 @@ Variable flowTarget(Expr arg) { */ predicate unboxed(BoxedExpr e) { exists(BinaryExpr bin | e = bin.getAnOperand() | - if (bin instanceof EqualityTest or bin instanceof ComparisonExpr) then - bin.getAnOperand() instanceof PrimitiveExpr - else - bin instanceof PrimitiveExpr + if (bin instanceof EqualityTest or bin instanceof ComparisonExpr) + then bin.getAnOperand() instanceof PrimitiveExpr + else bin instanceof PrimitiveExpr ) or - exists(Assignment assign | assign.getDest() instanceof PrimitiveExpr | - assign.getSource() = e - ) + exists(Assignment assign | assign.getDest() instanceof PrimitiveExpr | assign.getSource() = e) or flowTarget(e).getType() instanceof PrimitiveType or @@ -62,8 +50,7 @@ predicate unboxed(BoxedExpr e) { * Holds if `e` is in a syntactic position where it is implicitly boxed. */ predicate boxed(PrimitiveExpr e) { - exists(AssignExpr assign | assign.getDest() instanceof BoxedExpr | - assign.getSource() = e) + exists(AssignExpr assign | assign.getDest() instanceof BoxedExpr | assign.getSource() = e) or flowTarget(e).getType() instanceof BoxedType or @@ -88,6 +75,7 @@ where unboxed(e) and conv = "This expression is implicitly unboxed." or exists(Variable v | rebox(e, v) | - conv = "This expression implicitly unboxes, updates, and reboxes the value of '" + v.getName() + "'." + conv = "This expression implicitly unboxes, updates, and reboxes the value of '" + v.getName() + + "'." ) select e, conv diff --git a/java/ql/src/Violations of Best Practice/legacy/FinallyMayNotComplete.ql b/java/ql/src/Violations of Best Practice/legacy/FinallyMayNotComplete.ql index 3e04d76e2be..bf2e0a0a7ac 100644 --- a/java/ql/src/Violations of Best Practice/legacy/FinallyMayNotComplete.ql +++ b/java/ql/src/Violations of Best Practice/legacy/FinallyMayNotComplete.ql @@ -14,9 +14,7 @@ import java -Block finallyBlock() { - exists(TryStmt try | try.getFinally() = result) -} +Block finallyBlock() { exists(TryStmt try | try.getFinally() = result) } Stmt statementIn(Block finally) { finallyBlock() = finally and @@ -26,8 +24,10 @@ Stmt statementIn(Block finally) { predicate banned(Stmt s, Block finally) { s = statementIn(finally) and ( - s instanceof ReturnStmt or - exists(ThrowStmt throw | s = throw and not throw.getLexicalCatchIfAny() = statementIn(finally)) or + s instanceof ReturnStmt + or + exists(ThrowStmt throw | s = throw and not throw.getLexicalCatchIfAny() = statementIn(finally)) + or exists(JumpStmt jump | s = jump and not jump.getTarget() = statementIn(finally)) ) } diff --git a/java/ql/src/Violations of Best Practice/legacy/InexactVarArg.ql b/java/ql/src/Violations of Best Practice/legacy/InexactVarArg.ql index 1a14d9ed95b..2fd2709ef3d 100644 --- a/java/ql/src/Violations of Best Practice/legacy/InexactVarArg.ql +++ b/java/ql/src/Violations of Best Practice/legacy/InexactVarArg.ql @@ -9,20 +9,25 @@ * @id java/inexact-varargs * @tags reliability */ + import java predicate varArgsMethod(Method method, Array varargsType, int arity) { - exists(MethodAccess access | access.getMethod() = method and + exists(MethodAccess access | + access.getMethod() = method and arity = method.getNumberOfParameters() and not access.getNumArgument() = arity and - method.getParameterType(arity-1) = varargsType + method.getParameterType(arity - 1) = varargsType ) } RefType normalised(Type type) { - type.(RawType).getErasure() = result or - type.(ParameterizedType).getErasure() = result or - type.(BoundedType).getUpperBoundType() = result or + type.(RawType).getErasure() = result + or + type.(ParameterizedType).getErasure() = result + or + type.(BoundedType).getUpperBoundType() = result + or (not type instanceof RawType and not type instanceof ParameterizedType and type = result) } @@ -38,5 +43,7 @@ where access.getNumArgument() = params and usedType = access.getArgument(params - 1).getType() and not equivalent(declaredType, usedType) and - declaredType.getDimension() != usedType.getDimension()+1 -select access.getArgument(params - 1), "Call to varargs method $@ with inexact argument type (compiler dependent).", target, target.getName() + declaredType.getDimension() != usedType.getDimension() + 1 +select access.getArgument(params - 1), + "Call to varargs method $@ with inexact argument type (compiler dependent).", target, + target.getName() diff --git a/java/ql/src/Violations of Best Practice/legacy/UnnecessaryImport.ql b/java/ql/src/Violations of Best Practice/legacy/UnnecessaryImport.ql index 2be3595fcdf..096cd8b551f 100644 --- a/java/ql/src/Violations of Best Practice/legacy/UnnecessaryImport.ql +++ b/java/ql/src/Violations of Best Practice/legacy/UnnecessaryImport.ql @@ -18,22 +18,21 @@ string neededByJavadoc(JavadocElement c) { result = c.(SeeTag).getReference() } -Annotation nestedAnnotation(Annotation a) { - result.getAnnotatedElement().(Expr).getParent+() = a -} +Annotation nestedAnnotation(Annotation a) { result.getAnnotatedElement().(Expr).getParent+() = a } RefType neededByAnnotation(Annotation a) { - exists(TypeAccess t | t.getParent+() = a | - result = t.getType().(RefType).getSourceDeclaration() - ) or + exists(TypeAccess t | t.getParent+() = a | result = t.getType().(RefType).getSourceDeclaration()) + or exists(ArrayTypeAccess at | at.getParent+() = a | result = at.getType().(Array).getElementType().(RefType).getSourceDeclaration() - ) or - exists(VarAccess va | va.getParent+() = a | - result = va.getVariable().(Field).getDeclaringType() - ) or - result = a.getType() or - result = a.getType().(NestedType).getEnclosingType+() or + ) + or + exists(VarAccess va | va.getParent+() = a | result = va.getVariable().(Field).getDeclaringType()) + or + result = a.getType() + or + result = a.getType().(NestedType).getEnclosingType+() + or result = neededByAnnotation(nestedAnnotation(a)) } @@ -41,22 +40,22 @@ RefType neededType(CompilationUnit cu) { // Annotations exists(Annotation a | a.getAnnotatedElement().getCompilationUnit() = cu | result = neededByAnnotation(a) - ) or + ) + or // type accesses exists(TypeAccess t | t.getCompilationUnit() = cu | result = t.getType().(RefType).getSourceDeclaration() - ) or + ) + or exists(ArrayTypeAccess at | at.getCompilationUnit() = cu | result = at.getType().(Array).getElementType().(RefType).getSourceDeclaration() - ) or - // throws clauses - exists(Callable c | c.getCompilationUnit() = cu | - result = c.getAnException().getType() - ) or - // Javadoc - exists(JavadocElement j | cu.getFile() = j.getFile() | - result.getName() = neededByJavadoc(j) ) + or + // throws clauses + exists(Callable c | c.getCompilationUnit() = cu | result = c.getAnException().getType()) + or + // Javadoc + exists(JavadocElement j | cu.getFile() = j.getFile() | result.getName() = neededByJavadoc(j)) } RefType importedType(Import i) { @@ -65,9 +64,7 @@ RefType importedType(Import i) { result = i.(ImportType).getImportedType() } -predicate neededImport(Import i) { - importedType(i) = neededType(i.getCompilationUnit()) -} +predicate neededImport(Import i) { importedType(i) = neededType(i.getCompilationUnit()) } from Import i where diff --git a/java/ql/src/definitions.ql b/java/ql/src/definitions.ql index ab7a8d95993..d6fe9adb77b 100644 --- a/java/ql/src/definitions.ql +++ b/java/ql/src/definitions.ql @@ -20,46 +20,52 @@ import java class LocationOverridingMethodAccess extends MethodAccess { override predicate hasLocationInfo(string path, int sl, int sc, int el, int ec) { exists(MemberRefExpr e | e.getReferencedCallable() = getMethod() | - exists(int elRef, int ecRef | - e.hasLocationInfo(path, _, _, elRef, ecRef) - | + exists(int elRef, int ecRef | e.hasLocationInfo(path, _, _, elRef, ecRef) | sl = elRef and sc = ecRef - getMethod().getName().length() + 1 and el = elRef and ec = ecRef ) - ) or + ) + or not exists(MemberRefExpr e | e.getReferencedCallable() = getMethod()) and exists(int slSuper, int scSuper, int elSuper, int ecSuper | super.hasLocationInfo(path, slSuper, scSuper, elSuper, ecSuper) - | + | ( if (exists(getTypeArgument(_))) - then exists(Location locTypeArg | locTypeArg = getTypeArgument(count(getTypeArgument(_))-1).getLocation() | - sl = locTypeArg.getEndLine() and - sc = locTypeArg.getEndColumn()+2) + then + exists(Location locTypeArg | + locTypeArg = getTypeArgument(count(getTypeArgument(_)) - 1).getLocation() + | + sl = locTypeArg.getEndLine() and + sc = locTypeArg.getEndColumn() + 2 + ) else ( if exists(getQualifier()) - // Note: this needs to be the original (full) location of the qualifier, not the modified one. - then exists(Location locQual | locQual = getQualifier().getLocation() | - sl = locQual.getEndLine() and - sc = locQual.getEndColumn()+2) + then + // Note: this needs to be the original (full) location of the qualifier, not the modified one. + exists(Location locQual | locQual = getQualifier().getLocation() | + sl = locQual.getEndLine() and + sc = locQual.getEndColumn() + 2 + ) else ( sl = slSuper and sc = scSuper ) ) - ) - and + ) and ( - if (getNumArgument()>0) - // Note: this needs to be the original (full) location of the first argument, not the modified one. - then exists(Location locArg | locArg = getArgument(0).getLocation() | - el = locArg.getStartLine() and - ec = locArg.getStartColumn()-2 - ) else ( + if (getNumArgument() > 0) + then + // Note: this needs to be the original (full) location of the first argument, not the modified one. + exists(Location locArg | locArg = getArgument(0).getLocation() | + el = locArg.getStartLine() and + ec = locArg.getStartColumn() - 2 + ) + else ( el = elSuper and - ec = ecSuper-2 + ec = ecSuper - 2 ) ) ) @@ -74,26 +80,29 @@ class LocationOverridingTypeAccess extends TypeAccess { override predicate hasLocationInfo(string path, int sl, int sc, int el, int ec) { exists(int slSuper, int scSuper, int elSuper, int ecSuper | super.hasLocationInfo(path, slSuper, scSuper, elSuper, ecSuper) - | + | ( if exists(getQualifier()) - // Note: this needs to be the original (full) location of the qualifier, not the modified one. - then exists(Location locQual | locQual = getQualifier().getLocation() | - sl = locQual.getEndLine() and - sc = locQual.getEndColumn()+2) + then + // Note: this needs to be the original (full) location of the qualifier, not the modified one. + exists(Location locQual | locQual = getQualifier().getLocation() | + sl = locQual.getEndLine() and + sc = locQual.getEndColumn() + 2 + ) else ( sl = slSuper and sc = scSuper ) - ) - and + ) and ( if (exists(getTypeArgument(_))) - // Note: this needs to be the original (full) location of the first type argument, not the modified one. - then exists(Location locArg | locArg = getTypeArgument(0).getLocation() | - el = locArg.getStartLine() and - ec = locArg.getStartColumn()-2 - ) else ( + then + // Note: this needs to be the original (full) location of the first type argument, not the modified one. + exists(Location locArg | locArg = getTypeArgument(0).getLocation() | + el = locArg.getStartLine() and + ec = locArg.getStartColumn() - 2 + ) + else ( el = elSuper and ec = ecSuper ) @@ -110,7 +119,7 @@ class LocationOverridingFieldAccess extends FieldAccess { override predicate hasLocationInfo(string path, int sl, int sc, int el, int ec) { super.hasLocationInfo(path, _, _, el, ec) and sl = el and - sc = ec-(getField().getName().length())+1 + sc = ec - (getField().getName().length()) + 1 } } @@ -122,11 +131,11 @@ class LocationOverridingImportType extends ImportType { override predicate hasLocationInfo(string path, int sl, int sc, int el, int ec) { exists(int slSuper, int scSuper, int elSuper, int ecSuper | super.hasLocationInfo(path, slSuper, scSuper, elSuper, ecSuper) - | + | el = elSuper and - ec = ecSuper-1 and + ec = ecSuper - 1 and sl = el and - sc = ecSuper-(getImportedType().getName().length()) + sc = ecSuper - (getImportedType().getName().length()) ) } } @@ -139,11 +148,11 @@ class LocationOverridingImportStaticTypeMember extends ImportStaticTypeMember { override predicate hasLocationInfo(string path, int sl, int sc, int el, int ec) { exists(int slSuper, int scSuper, int elSuper, int ecSuper | super.hasLocationInfo(path, slSuper, scSuper, elSuper, ecSuper) - | + | el = elSuper and - ec = ecSuper-1 and + ec = ecSuper - 1 and sl = el and - sc = ecSuper-(getName().length()) + sc = ecSuper - (getName().length()) ) } } @@ -157,7 +166,8 @@ Element definition(Element e, string kind) { result = v.(Field).getSourceDeclaration() or result = v.(Parameter).getSourceDeclaration() or result = v.(LocalVariableDecl) - ) and kind = "V" + ) and + kind = "V" or e.(ImportType).getImportedType() = result and kind = "I" or @@ -172,7 +182,9 @@ predicate dummyVarAccess(VarAccess va) { } predicate dummyTypeAccess(TypeAccess ta) { - exists(FunctionalExpr e | e.getAnonymousClass().getClassInstanceExpr().getTypeName() = ta.getParent*()) + exists(FunctionalExpr e | + e.getAnonymousClass().getClassInstanceExpr().getTypeName() = ta.getParent*() + ) } from Element e, Element def, string kind diff --git a/java/ql/src/external/DuplicateAnonymous.ql b/java/ql/src/external/DuplicateAnonymous.ql index 76a6e83f588..79b291dca01 100644 --- a/java/ql/src/external/DuplicateAnonymous.ql +++ b/java/ql/src/external/DuplicateAnonymous.ql @@ -12,6 +12,7 @@ * statistical * non-attributable */ + import java import CodeDuplication @@ -19,5 +20,5 @@ from AnonymousClass c, AnonymousClass other where duplicateAnonymousClass(c, other) and not fileLevelDuplication(c.getCompilationUnit(), other.getCompilationUnit()) -select c, "Anonymous class is identical to $@.", - other, "another anonymous class in " + other.getFile().getStem() +select c, "Anonymous class is identical to $@.", other, + "another anonymous class in " + other.getFile().getStem() diff --git a/java/ql/src/external/DuplicateBlock.ql b/java/ql/src/external/DuplicateBlock.ql index b8b36e318cc..dbee6e5767c 100644 --- a/java/ql/src/external/DuplicateBlock.ql +++ b/java/ql/src/external/DuplicateBlock.ql @@ -6,6 +6,7 @@ * @precision low * @id java/duplicate-block */ + import CodeDuplication from DuplicateBlock d, DuplicateBlock other, int lines, File otherFile, int otherLine @@ -16,6 +17,6 @@ where other != d and otherFile = other.sourceFile() and otherLine = other.sourceStartLine() -select - d, - "Duplicate code: " + lines + " lines are duplicated at " + otherFile.getStem() + ":" + otherLine + "." +select d, + "Duplicate code: " + lines + " lines are duplicated at " + otherFile.getStem() + ":" + otherLine + + "." diff --git a/java/ql/src/external/DuplicateMethod.ql b/java/ql/src/external/DuplicateMethod.ql index 6084cf89c3c..f094707ac56 100644 --- a/java/ql/src/external/DuplicateMethod.ql +++ b/java/ql/src/external/DuplicateMethod.ql @@ -13,11 +13,13 @@ * statistical * non-attributable */ + import java import CodeDuplication predicate relevant(Method m) { - m.getNumberOfLinesOfCode() > 5 and not m.getName().matches("get%") or + m.getNumberOfLinesOfCode() > 5 and not m.getName().matches("get%") + or m.getNumberOfLinesOfCode() > 10 } @@ -27,5 +29,5 @@ where relevant(m) and not fileLevelDuplication(m.getCompilationUnit(), other.getCompilationUnit()) and not classLevelDuplication(m.getDeclaringType(), other.getDeclaringType()) -select m, "Method " + m.getName() + " is duplicated in $@.", - other, other.getDeclaringType().getQualifiedName() +select m, "Method " + m.getName() + " is duplicated in $@.", other, + other.getDeclaringType().getQualifiedName() diff --git a/java/ql/src/external/MostlyDuplicateClass.ql b/java/ql/src/external/MostlyDuplicateClass.ql index 68734f314ee..897e117c799 100644 --- a/java/ql/src/external/MostlyDuplicateClass.ql +++ b/java/ql/src/external/MostlyDuplicateClass.ql @@ -13,6 +13,7 @@ * statistical * non-attributable */ + import java import CodeDuplication diff --git a/java/ql/src/external/MostlyDuplicateFile.ql b/java/ql/src/external/MostlyDuplicateFile.ql index 2a339830839..8c194342934 100644 --- a/java/ql/src/external/MostlyDuplicateFile.ql +++ b/java/ql/src/external/MostlyDuplicateFile.ql @@ -13,10 +13,11 @@ * statistical * non-attributable */ + import java import CodeDuplication from File f, File other, int percent where duplicateFiles(f, other, percent) -select f, percent + "% of the lines in " + f.getStem() + " are copies of lines in $@.", - other, other.getStem() +select f, percent + "% of the lines in " + f.getStem() + " are copies of lines in $@.", other, + other.getStem() diff --git a/java/ql/src/external/MostlyDuplicateMethod.ql b/java/ql/src/external/MostlyDuplicateMethod.ql index 53fb1271b05..7e276836043 100644 --- a/java/ql/src/external/MostlyDuplicateMethod.ql +++ b/java/ql/src/external/MostlyDuplicateMethod.ql @@ -13,6 +13,7 @@ * statistical * non-attributable */ + import java import CodeDuplication @@ -26,5 +27,5 @@ where not duplicateMethod(m, other) and not classLevelDuplication(m.getDeclaringType(), other.getDeclaringType()) and not fileLevelDuplication(m.getCompilationUnit(), other.getCompilationUnit()) -select m, percent + "% of the statements in " + m.getName() + " are duplicated in $@.", - other, other.getDeclaringType().getName() + "." + other.getStringSignature() +select m, percent + "% of the statements in " + m.getName() + " are duplicated in $@.", other, + other.getDeclaringType().getName() + "." + other.getStringSignature() diff --git a/java/ql/src/external/MostlySimilarFile.ql b/java/ql/src/external/MostlySimilarFile.ql index 70bd6e68ce4..1d30077cdd9 100644 --- a/java/ql/src/external/MostlySimilarFile.ql +++ b/java/ql/src/external/MostlySimilarFile.ql @@ -13,10 +13,11 @@ * statistical * non-attributable */ + import java import CodeDuplication from File f, File other, int percent where similarFiles(f, other, percent) -select f, percent + "% of the lines in " + f.getStem() + " are similar to lines in $@.", - other, other.getStem() +select f, percent + "% of the lines in " + f.getStem() + " are similar to lines in $@.", other, + other.getStem() diff --git a/java/ql/src/filters/ClassifyFiles.ql b/java/ql/src/filters/ClassifyFiles.ql index 080f4530a43..70f3c31b021 100644 --- a/java/ql/src/filters/ClassifyFiles.ql +++ b/java/ql/src/filters/ClassifyFiles.ql @@ -9,9 +9,12 @@ import java predicate classify(File f, string tag) { - f instanceof GeneratedFile and tag = "generated" or - exists(GeneratedClass gc | gc.getFile() = f | tag = "generated") or - exists(TestClass tc | tc.getFile() = f | tag = "test") or + f instanceof GeneratedFile and tag = "generated" + or + exists(GeneratedClass gc | gc.getFile() = f | tag = "generated") + or + exists(TestClass tc | tc.getFile() = f | tag = "test") + or exists(TestMethod tm | tm.getFile() = f | tag = "test") } diff --git a/java/ql/src/filters/FromSource.ql b/java/ql/src/filters/FromSource.ql index a2fbd760763..5d655c4954e 100644 --- a/java/ql/src/filters/FromSource.ql +++ b/java/ql/src/filters/FromSource.ql @@ -4,6 +4,7 @@ * @kind problem * @id java/source-filter */ + import java import external.DefectFilter diff --git a/java/ql/src/filters/ImportAdditionalLibraries.ql b/java/ql/src/filters/ImportAdditionalLibraries.ql index d3a5f8bc52a..0774fe8894e 100644 --- a/java/ql/src/filters/ImportAdditionalLibraries.ql +++ b/java/ql/src/filters/ImportAdditionalLibraries.ql @@ -8,7 +8,6 @@ */ import java - import semmle.code.java.dataflow.Guards import semmle.code.java.security.DataFlow diff --git a/java/ql/src/filters/NotGenerated.ql b/java/ql/src/filters/NotGenerated.ql index 967ec2be72d..d20e8ca5e58 100644 --- a/java/ql/src/filters/NotGenerated.ql +++ b/java/ql/src/filters/NotGenerated.ql @@ -4,6 +4,7 @@ * @kind problem * @id java/not-generated-file-filter */ + import java import external.DefectFilter diff --git a/java/ql/src/filters/NotGeneratedForMetric.ql b/java/ql/src/filters/NotGeneratedForMetric.ql index 198b9a283d5..8d424cea687 100644 --- a/java/ql/src/filters/NotGeneratedForMetric.ql +++ b/java/ql/src/filters/NotGeneratedForMetric.ql @@ -4,6 +4,7 @@ * @kind treemap * @id java/not-generated-file-metric-filter */ + import java import external.MetricFilter diff --git a/java/ql/src/filters/RecentDefects.ql b/java/ql/src/filters/RecentDefects.ql index c1d22b6da73..573ca6f5448 100644 --- a/java/ql/src/filters/RecentDefects.ql +++ b/java/ql/src/filters/RecentDefects.ql @@ -4,15 +4,14 @@ * @kind problem * @id java/recently-changed-file-filter */ + import java import external.DefectFilter import external.VCS -private pragma[noopt] -predicate recent(File file) { - exists(Commit e | file = e.getAnAffectedFile() | - e.isRecent() and not artificialChange(e) - ) and +pragma[noopt] +private predicate recent(File file) { + exists(Commit e | file = e.getAnAffectedFile() | e.isRecent() and not artificialChange(e)) and exists(file.getLocation()) } diff --git a/java/ql/src/filters/RecentDefectsForMetric.ql b/java/ql/src/filters/RecentDefectsForMetric.ql index 261977405ee..3587ea20d7b 100644 --- a/java/ql/src/filters/RecentDefectsForMetric.ql +++ b/java/ql/src/filters/RecentDefectsForMetric.ql @@ -4,15 +4,14 @@ * @kind treemap * @id java/recently-changed-file-metric-filter */ + import java import external.MetricFilter import external.VCS -private pragma[noopt] -predicate recent(File file) { - exists(Commit e | file = e.getAnAffectedFile() | - e.isRecent() and not artificialChange(e) - ) and +pragma[noopt] +private predicate recent(File file) { + exists(Commit e | file = e.getAnAffectedFile() | e.isRecent() and not artificialChange(e)) and exists(file.getLocation()) } diff --git a/java/ql/src/filters/SuppressionComment.ql b/java/ql/src/filters/SuppressionComment.ql index fdb984fab83..f9a8d85bcfa 100644 --- a/java/ql/src/filters/SuppressionComment.ql +++ b/java/ql/src/filters/SuppressionComment.ql @@ -11,17 +11,15 @@ * @kind problem * @id java/nosemmle-suppression-comment-filter */ + import java import external.DefectFilter class SuppressionComment extends Javadoc { - SuppressionComment() { - this.getAChild*().getText().matches("%NOSEMMLE%") - } + SuppressionComment() { this.getAChild*().getText().matches("%NOSEMMLE%") } private string getASuppressionDirective() { - result = this.getAChild*().getText() - .regexpFind("\\bNOSEMMLE\\b(\\([^)]+?\\)|/[^/]+?/|)", _, 0) + result = this.getAChild*().getText().regexpFind("\\bNOSEMMLE\\b(\\([^)]+?\\)|/[^/]+?/|)", _, 0) } private string getAnActualSubstringArg() { @@ -33,16 +31,18 @@ class SuppressionComment extends Javadoc { } private string getASuppressionRegex() { - result = getAnActualRegexArg() or + result = getAnActualRegexArg() + or exists(string substring | substring = getAnActualSubstringArg() | result = "\\Q" + substring.replaceAll("\\E", "\\E\\\\E\\Q") + "\\E" - ) or + ) + or (result = ".*" and getASuppressionDirective() = "NOSEMMLE") } predicate suppresses(DefectResult res) { this.getFile() = res.getFile() and - res.getEndLine() - this.getLocation().getEndLine() in [0..2] and + res.getEndLine() - this.getLocation().getEndLine() in [0 .. 2] and res.getMessage().regexpMatch(this.getASuppressionRegex()) } } diff --git a/java/ql/src/meta/ssa/AmbiguousToString.ql b/java/ql/src/meta/ssa/AmbiguousToString.ql index d1a5d1753ab..7dacb7ac8a3 100644 --- a/java/ql/src/meta/ssa/AmbiguousToString.ql +++ b/java/ql/src/meta/ssa/AmbiguousToString.ql @@ -11,21 +11,17 @@ import java import semmle.code.java.dataflow.SSA -predicate noToString(SsaVariable v) { - not exists(v.toString()) -} +predicate noToString(SsaVariable v) { not exists(v.toString()) } -predicate multipleToString(SsaVariable v) { - 1 < count(v.toString()) -} +predicate multipleToString(SsaVariable v) { 1 < count(v.toString()) } from SsaVariable ssa, ControlFlowNode n, Variable v, string problem where ( - noToString(ssa) and problem = "SSA variable without 'toString()' for " or + noToString(ssa) and problem = "SSA variable without 'toString()' for " + or multipleToString(ssa) and problem = "SSA variable with multiple 'toString()' results for " ) and n = ssa.getCFGNode() and v = ssa.getSourceVariable().getVariable() -select - n, problem + v +select n, problem + v diff --git a/java/ql/src/meta/ssa/TooFewPhiInputs.ql b/java/ql/src/meta/ssa/TooFewPhiInputs.ql index 16216b92a3d..3c868610c1d 100644 --- a/java/ql/src/meta/ssa/TooFewPhiInputs.ql +++ b/java/ql/src/meta/ssa/TooFewPhiInputs.ql @@ -14,5 +14,4 @@ from SsaPhiNode phi, int inputs where inputs = count(SsaVariable v | v = phi.getAPhiInput()) and inputs < 2 -select - phi, "Phi node for " + phi.getSourceVariable() + " has only " + inputs + " inputs." +select phi, "Phi node for " + phi.getSourceVariable() + " has only " + inputs + " inputs." diff --git a/java/ql/src/meta/ssa/UncertainDefWithoutPrior.ql b/java/ql/src/meta/ssa/UncertainDefWithoutPrior.ql index 06f32120296..172f620912b 100644 --- a/java/ql/src/meta/ssa/UncertainDefWithoutPrior.ql +++ b/java/ql/src/meta/ssa/UncertainDefWithoutPrior.ql @@ -12,8 +12,10 @@ import java import semmle.code.java.dataflow.SSA predicate live(SsaVariable v) { - exists(v.getAUse()) or - exists(SsaPhiNode phi | live(phi) and phi.getAPhiInput() = v) or + exists(v.getAUse()) + or + exists(SsaPhiNode phi | live(phi) and phi.getAPhiInput() = v) + or exists(SsaUncertainImplicitUpdate upd | live(upd) and upd.getPriorDef() = v) } @@ -21,5 +23,4 @@ from SsaUncertainImplicitUpdate upd where live(upd) and not exists(upd.getPriorDef()) -select - upd, "No prior definition of " + upd +select upd, "No prior definition of " + upd diff --git a/java/ql/src/meta/ssa/UseWithoutUniqueSsaVariable.ql b/java/ql/src/meta/ssa/UseWithoutUniqueSsaVariable.ql index 8ec45904cd0..421252fd508 100644 --- a/java/ql/src/meta/ssa/UseWithoutUniqueSsaVariable.ql +++ b/java/ql/src/meta/ssa/UseWithoutUniqueSsaVariable.ql @@ -15,9 +15,12 @@ class SsaConvertibleReadAccess extends RValue { SsaConvertibleReadAccess() { this.getEnclosingCallable().getBody().getBasicBlock().getABBSuccessor*() = this.getBasicBlock() and ( - not exists(this.getQualifier()) or - this.getVariable() instanceof LocalScopeVariable or - this.getVariable().(Field).isStatic() or + not exists(this.getQualifier()) + or + this.getVariable() instanceof LocalScopeVariable + or + this.getVariable().(Field).isStatic() + or exists(Expr q | q = this.getQualifier() | q instanceof ThisAccess or q instanceof SuperAccess or @@ -41,7 +44,9 @@ predicate readAccessWithAmbiguousSsaVariable(SsaConvertibleReadAccess va) { from SsaConvertibleReadAccess va, string problem where - accessWithoutSourceVariable(va) and problem = "No source variable" or - readAccessWithoutSsaVariable(va) and problem = "No SSA variable" or + accessWithoutSourceVariable(va) and problem = "No source variable" + or + readAccessWithoutSsaVariable(va) and problem = "No SSA variable" + or readAccessWithAmbiguousSsaVariable(va) and problem = "Multiple SSA variables" select va, problem diff --git a/java/ql/test/library-tests/JDK/Main.ql b/java/ql/test/library-tests/JDK/Main.ql index 99ffefefaec..efb4b207e77 100644 --- a/java/ql/test/library-tests/JDK/Main.ql +++ b/java/ql/test/library-tests/JDK/Main.ql @@ -2,6 +2,7 @@ * @name Main * @description Test the definition of class MainMethod */ + import default from Class cl, MainMethod mm diff --git a/java/ql/test/library-tests/RelativePaths/relativePath.ql b/java/ql/test/library-tests/RelativePaths/relativePath.ql index 6d952f9f561..32dd929bdcb 100644 --- a/java/ql/test/library-tests/RelativePaths/relativePath.ql +++ b/java/ql/test/library-tests/RelativePaths/relativePath.ql @@ -1,6 +1,7 @@ import semmle.code.java.security.RelativePaths from Element elem, string command -where relativePath(elem, command) - and elem.fromSource() +where + relativePath(elem, command) and + elem.fromSource() select elem, command diff --git a/java/ql/test/library-tests/annotations/Annotations.ql b/java/ql/test/library-tests/annotations/Annotations.ql index f1e11d16850..b4aaec06933 100644 --- a/java/ql/test/library-tests/annotations/Annotations.ql +++ b/java/ql/test/library-tests/annotations/Annotations.ql @@ -5,13 +5,11 @@ import default -private -int numberOfLocations(Annotation a) { - result = count(a.getLocation()) -} +private int numberOfLocations(Annotation a) { result = count(a.getLocation()) } from Annotation a, RefType c, Location loc -where c.hasQualifiedName("annotations", "C") - and c.getAnAnnotation() = a.getParent*() - and loc = a.getLocation() +where + c.hasQualifiedName("annotations", "C") and + c.getAnAnnotation() = a.getParent*() and + loc = a.getLocation() select loc.getStartLine(), loc.getStartColumn(), a, numberOfLocations(a) diff --git a/java/ql/test/library-tests/annotations/GetAnnotationValue.ql b/java/ql/test/library-tests/annotations/GetAnnotationValue.ql index 8e638b6b70c..b2b2bc43b1f 100644 --- a/java/ql/test/library-tests/annotations/GetAnnotationValue.ql +++ b/java/ql/test/library-tests/annotations/GetAnnotationValue.ql @@ -1,6 +1,7 @@ /** * @name GetAnnotationValue */ + import default from Annotatable a, string key diff --git a/java/ql/test/library-tests/annotations/GetLibraryAnnotationElement.ql b/java/ql/test/library-tests/annotations/GetLibraryAnnotationElement.ql index 23d57999f3b..f1e1c1cfd71 100644 --- a/java/ql/test/library-tests/annotations/GetLibraryAnnotationElement.ql +++ b/java/ql/test/library-tests/annotations/GetLibraryAnnotationElement.ql @@ -1,11 +1,13 @@ /** * @name GetLibraryAnnotationElement */ + import default from Class cl, Annotation ann, AnnotationType anntp, AnnotationElement anne -where cl.fromSource() and - ann = cl.getAnAnnotation() and - anntp = ann.getType() and - anne = anntp.getAnAnnotationElement() +where + cl.fromSource() and + ann = cl.getAnAnnotation() and + anntp = ann.getType() and + anne = anntp.getAnAnnotationElement() select cl, ann, anntp.getQualifiedName(), anne.getName() diff --git a/java/ql/test/library-tests/arrays/Dimension.ql b/java/ql/test/library-tests/arrays/Dimension.ql index 65c671a3d73..1e39c21325c 100644 --- a/java/ql/test/library-tests/arrays/Dimension.ql +++ b/java/ql/test/library-tests/arrays/Dimension.ql @@ -1,6 +1,7 @@ /** * @name Dimension */ + import default from Array a diff --git a/java/ql/test/library-tests/arrays/ElementType.ql b/java/ql/test/library-tests/arrays/ElementType.ql index 0b75901bdb4..4fd0ebfc2d6 100644 --- a/java/ql/test/library-tests/arrays/ElementType.ql +++ b/java/ql/test/library-tests/arrays/ElementType.ql @@ -1,6 +1,7 @@ /** * @name ElementType */ + import default from Array a diff --git a/java/ql/test/library-tests/collections/MapMethods.ql b/java/ql/test/library-tests/collections/MapMethods.ql index 6e429469f22..23755773187 100644 --- a/java/ql/test/library-tests/collections/MapMethods.ql +++ b/java/ql/test/library-tests/collections/MapMethods.ql @@ -3,4 +3,5 @@ import semmle.code.java.Maps from Call c, MapMethod mm where mm = c.getCallee() -select c, mm.getDeclaringType().getQualifiedName()+"."+mm.getSignature(), mm.getReceiverKeyType().getQualifiedName(), mm.getReceiverValueType().getQualifiedName() +select c, mm.getDeclaringType().getQualifiedName() + "." + mm.getSignature(), + mm.getReceiverKeyType().getQualifiedName(), mm.getReceiverValueType().getQualifiedName() diff --git a/java/ql/test/library-tests/collections/Maps.ql b/java/ql/test/library-tests/collections/Maps.ql index 4dc2af9cb24..9dd8a0ad551 100644 --- a/java/ql/test/library-tests/collections/Maps.ql +++ b/java/ql/test/library-tests/collections/Maps.ql @@ -2,6 +2,7 @@ import default import semmle.code.java.Maps from Variable v, MapType mt -where v.fromSource() and - mt = v.getType() +where + v.fromSource() and + mt = v.getType() select v, mt.toString(), mt.getKeyType().getQualifiedName(), mt.getValueType().getQualifiedName() diff --git a/java/ql/test/library-tests/commentedcode/CommentedCode.ql b/java/ql/test/library-tests/commentedcode/CommentedCode.ql index 328a78b36a3..4b5dc868ea8 100644 --- a/java/ql/test/library-tests/commentedcode/CommentedCode.ql +++ b/java/ql/test/library-tests/commentedcode/CommentedCode.ql @@ -2,4 +2,3 @@ import Violations_of_Best_Practice.Comments.CommentedCode from CommentedOutCode c select c, c.getCodeLines() - diff --git a/java/ql/test/library-tests/constants/CompileTimeConstantExpr.ql b/java/ql/test/library-tests/constants/CompileTimeConstantExpr.ql index 4f0862c12a2..93bf17e23b4 100644 --- a/java/ql/test/library-tests/constants/CompileTimeConstantExpr.ql +++ b/java/ql/test/library-tests/constants/CompileTimeConstantExpr.ql @@ -2,6 +2,6 @@ import semmle.code.java.Expr from CompileTimeConstantExpr constant, RefType tpe where - constant.getEnclosingCallable().getDeclaringType() = tpe - and tpe.hasQualifiedName("constants", "Constants") + constant.getEnclosingCallable().getDeclaringType() = tpe and + tpe.hasQualifiedName("constants", "Constants") select constant diff --git a/java/ql/test/library-tests/constants/getBooleanValue.ql b/java/ql/test/library-tests/constants/getBooleanValue.ql index db93b769236..2b10d95ff9b 100644 --- a/java/ql/test/library-tests/constants/getBooleanValue.ql +++ b/java/ql/test/library-tests/constants/getBooleanValue.ql @@ -2,8 +2,8 @@ import semmle.code.java.Variable from Variable v, Expr init, RefType enclosing, boolean constant where - v.getInitializer() = init - and init.getEnclosingCallable().getDeclaringType() = enclosing - and enclosing.hasQualifiedName("constants", "Values") - and constant = init.(CompileTimeConstantExpr).getBooleanValue() + v.getInitializer() = init and + init.getEnclosingCallable().getDeclaringType() = enclosing and + enclosing.hasQualifiedName("constants", "Values") and + constant = init.(CompileTimeConstantExpr).getBooleanValue() select init, constant diff --git a/java/ql/test/library-tests/constants/getInitializer.ql b/java/ql/test/library-tests/constants/getInitializer.ql index e558f0be0d8..6e4b28ee938 100644 --- a/java/ql/test/library-tests/constants/getInitializer.ql +++ b/java/ql/test/library-tests/constants/getInitializer.ql @@ -2,7 +2,7 @@ import semmle.code.java.Variable from Variable v, Expr init, RefType enclosing where - v.getInitializer() = init - and init.getEnclosingCallable().getDeclaringType() = enclosing - and enclosing.hasQualifiedName("constants", "Initializers") + v.getInitializer() = init and + init.getEnclosingCallable().getDeclaringType() = enclosing and + enclosing.hasQualifiedName("constants", "Initializers") select v, init diff --git a/java/ql/test/library-tests/constants/getIntValue.ql b/java/ql/test/library-tests/constants/getIntValue.ql index 502a25e85a0..dbb2c5bd967 100644 --- a/java/ql/test/library-tests/constants/getIntValue.ql +++ b/java/ql/test/library-tests/constants/getIntValue.ql @@ -2,8 +2,8 @@ import semmle.code.java.Variable from Variable v, Expr init, RefType enclosing, int constant where - v.getInitializer() = init - and init.getEnclosingCallable().getDeclaringType() = enclosing - and enclosing.hasQualifiedName("constants", "Values") - and constant = init.(CompileTimeConstantExpr).getIntValue() + v.getInitializer() = init and + init.getEnclosingCallable().getDeclaringType() = enclosing and + enclosing.hasQualifiedName("constants", "Values") and + constant = init.(CompileTimeConstantExpr).getIntValue() select init, constant diff --git a/java/ql/test/library-tests/constructors/ClassInstanceExpr.ql b/java/ql/test/library-tests/constructors/ClassInstanceExpr.ql index 22f48895595..27a00ff0c22 100644 --- a/java/ql/test/library-tests/constructors/ClassInstanceExpr.ql +++ b/java/ql/test/library-tests/constructors/ClassInstanceExpr.ql @@ -1,8 +1,6 @@ import default // There should just be one class instance expr - from ClassInstanceExpr expr -where - expr.getCompilationUnit().getPackage().hasName("constructors") +where expr.getCompilationUnit().getPackage().hasName("constructors") select expr diff --git a/java/ql/test/library-tests/constructors/ConstructorCalls.ql b/java/ql/test/library-tests/constructors/ConstructorCalls.ql index f865aa0e2b5..2c65099836c 100644 --- a/java/ql/test/library-tests/constructors/ConstructorCalls.ql +++ b/java/ql/test/library-tests/constructors/ConstructorCalls.ql @@ -2,10 +2,10 @@ * @name ConstructorCalls * @description Test the difference between ClassInstanceExpr and ConstructorCall */ + import default // There should be three constructor calls, including the class instance // expression 'new A(...)' - from ConstructorCall call select call diff --git a/java/ql/test/library-tests/controlflow/basic/bbStmts.ql b/java/ql/test/library-tests/controlflow/basic/bbStmts.ql index 4aa570899ce..52c95e13650 100644 --- a/java/ql/test/library-tests/controlflow/basic/bbStmts.ql +++ b/java/ql/test/library-tests/controlflow/basic/bbStmts.ql @@ -1,6 +1,7 @@ import default from BasicBlock b, ControlFlowNode n, int i -where b.getNode(i) = n - and b.getFile().(CompilationUnit).fromSource() +where + b.getNode(i) = n and + b.getFile().(CompilationUnit).fromSource() select b, n, i diff --git a/java/ql/test/library-tests/controlflow/dominance/dominanceBad.ql b/java/ql/test/library-tests/controlflow/dominance/dominanceBad.ql index 10a65688255..847b0347d37 100644 --- a/java/ql/test/library-tests/controlflow/dominance/dominanceBad.ql +++ b/java/ql/test/library-tests/controlflow/dominance/dominanceBad.ql @@ -2,7 +2,8 @@ import java import semmle.code.java.controlflow.Dominance from IfStmt i, Block b -where b = i.getThen() and - dominates(i.getThen(), b) and - dominates(i.getElse(), b) +where + b = i.getThen() and + dominates(i.getThen(), b) and + dominates(i.getElse(), b) select i, b diff --git a/java/ql/test/library-tests/controlflow/dominance/dominanceWrong.ql b/java/ql/test/library-tests/controlflow/dominance/dominanceWrong.ql index a0d4e5fa732..298e0752ee4 100644 --- a/java/ql/test/library-tests/controlflow/dominance/dominanceWrong.ql +++ b/java/ql/test/library-tests/controlflow/dominance/dominanceWrong.ql @@ -7,7 +7,8 @@ import semmle.code.java.controlflow.Dominance * dominate `node`. */ predicate dominanceCounterExample(ControlFlowNode entry, ControlFlowNode dom, ControlFlowNode node) { - node = entry or + node = entry + or exists(ControlFlowNode mid | dominanceCounterExample(entry, dom, mid) and mid != dom and mid.getASuccessor() = node ) diff --git a/java/ql/test/library-tests/controlflow/dominance/dominatedByStart.ql b/java/ql/test/library-tests/controlflow/dominance/dominatedByStart.ql index 124c14a64ca..b5bdf688996 100644 --- a/java/ql/test/library-tests/controlflow/dominance/dominatedByStart.ql +++ b/java/ql/test/library-tests/controlflow/dominance/dominatedByStart.ql @@ -1,17 +1,16 @@ // All nodes should be dominated by their associated start node - import default import semmle.code.java.controlflow.Dominance ControlFlowNode reachableIn(Method func) { - result = func.getBody() - or result = reachableIn(func).getASuccessor() + result = func.getBody() or + result = reachableIn(func).getASuccessor() } from Method func, ControlFlowNode entry, ControlFlowNode node where - func.getBody() = entry - and reachableIn(func) = node - and entry != node - and not strictlyDominates(func.getBody(), node) + func.getBody() = entry and + reachableIn(func) = node and + entry != node and + not strictlyDominates(func.getBody(), node) select func, node diff --git a/java/ql/test/library-tests/controlflow/dominance/dominator.ql b/java/ql/test/library-tests/controlflow/dominance/dominator.ql index 06093f07bf9..701640bf720 100644 --- a/java/ql/test/library-tests/controlflow/dominance/dominator.ql +++ b/java/ql/test/library-tests/controlflow/dominance/dominator.ql @@ -3,9 +3,7 @@ import semmle.code.java.controlflow.Dominance from Method func, ControlFlowNode dominator, ControlFlowNode node where - iDominates(dominator, node) - and dominator.getEnclosingStmt().getEnclosingCallable() = func - and func.getDeclaringType().hasName("Test") -select - dominator, - node + iDominates(dominator, node) and + dominator.getEnclosingStmt().getEnclosingCallable() = func and + func.getDeclaringType().hasName("Test") +select dominator, node diff --git a/java/ql/test/library-tests/controlflow/dominance/dominatorExists.ql b/java/ql/test/library-tests/controlflow/dominance/dominatorExists.ql index 9827dddd089..34469a686b1 100644 --- a/java/ql/test/library-tests/controlflow/dominance/dominatorExists.ql +++ b/java/ql/test/library-tests/controlflow/dominance/dominatorExists.ql @@ -1,18 +1,16 @@ // Every reachable node has a dominator - import default import semmle.code.java.controlflow.Dominance /** transitive dominance */ ControlFlowNode reachableIn(Method func) { - result = func.getBody() - or result = reachableIn(func).getASuccessor() + result = func.getBody() or + result = reachableIn(func).getASuccessor() } - from Method func, ControlFlowNode node where - node = reachableIn(func) - and node != func.getBody() - and not iDominates(_, node) + node = reachableIn(func) and + node != func.getBody() and + not iDominates(_, node) select func, node diff --git a/java/ql/test/library-tests/controlflow/dominance/dominatorUnique.ql b/java/ql/test/library-tests/controlflow/dominance/dominatorUnique.ql index eb8f75c0deb..eaf75ab7bfa 100644 --- a/java/ql/test/library-tests/controlflow/dominance/dominatorUnique.ql +++ b/java/ql/test/library-tests/controlflow/dominance/dominatorUnique.ql @@ -1,12 +1,11 @@ // Every reachable node has a dominator - import default import semmle.code.java.controlflow.Dominance from Method func, ControlFlowNode dom1, ControlFlowNode dom2, ControlFlowNode node where - iDominates(dom1, node) - and iDominates(dom2, node) - and dom1 != dom2 - and func = node.getEnclosingStmt().getEnclosingCallable() + iDominates(dom1, node) and + iDominates(dom2, node) and + dom1 != dom2 and + func = node.getEnclosingStmt().getEnclosingCallable() select func, node, dom1, dom2 diff --git a/java/ql/test/library-tests/controlflow/paths/paths.ql b/java/ql/test/library-tests/controlflow/paths/paths.ql index 7d5d6faaaf8..7216b8e829a 100644 --- a/java/ql/test/library-tests/controlflow/paths/paths.ql +++ b/java/ql/test/library-tests/controlflow/paths/paths.ql @@ -2,15 +2,13 @@ import java import semmle.code.java.controlflow.Paths class PathTestConf extends ActionConfiguration { - PathTestConf() { - this = "PathTestConf" - } + PathTestConf() { this = "PathTestConf" } + override predicate isAction(ControlFlowNode node) { node.(MethodAccess).getMethod().hasName("action") } } from Callable c, PathTestConf conf -where -conf.callableAlwaysPerformsAction(c) +where conf.callableAlwaysPerformsAction(c) select c diff --git a/java/ql/test/library-tests/dataflow/fields/flow.ql b/java/ql/test/library-tests/dataflow/fields/flow.ql index 2b0143e8e34..02a3f7e3adb 100644 --- a/java/ql/test/library-tests/dataflow/fields/flow.ql +++ b/java/ql/test/library-tests/dataflow/fields/flow.ql @@ -3,7 +3,9 @@ import semmle.code.java.dataflow.DataFlow class Conf extends DataFlow::Configuration { Conf() { this = "FieldFlowConf" } + override predicate isSource(DataFlow::Node src) { src.asExpr() instanceof ClassInstanceExpr } + override predicate isSink(DataFlow::Node sink) { exists(MethodAccess ma | ma.getMethod().hasName("sink") and diff --git a/java/ql/test/library-tests/dataflow/this-flow/this-flow.ql b/java/ql/test/library-tests/dataflow/this-flow/this-flow.ql index b8e8c68e5c6..481cb2108d9 100644 --- a/java/ql/test/library-tests/dataflow/this-flow/this-flow.ql +++ b/java/ql/test/library-tests/dataflow/this-flow/this-flow.ql @@ -4,17 +4,16 @@ import DataFlow class ThisFlowConfig extends Configuration { ThisFlowConfig() { this = "ThisFlowConfig" } + override predicate isSource(Node src) { - exists(PostUpdateNode cie | - cie.asExpr() instanceof ClassInstanceExpr - | + exists(PostUpdateNode cie | cie.asExpr() instanceof ClassInstanceExpr | cie.getPreUpdateNode() = src or cie = src ) } + override predicate isSink(Node sink) { any() } } from Node n, ThisFlowConfig conf -where -conf.hasFlow(_, n) +where conf.hasFlow(_, n) select n diff --git a/java/ql/test/library-tests/defUse/defUse.ql b/java/ql/test/library-tests/defUse/defUse.ql index dd7a4ce0784..5e30b68e3ea 100644 --- a/java/ql/test/library-tests/defUse/defUse.ql +++ b/java/ql/test/library-tests/defUse/defUse.ql @@ -3,4 +3,4 @@ import semmle.code.java.dataflow.DefUse from VariableUpdate d, RValue u, Variable v where defUsePair(d, u) and u.getVariable() = v -select v,d.getLocation().getStartLine(), u.getLocation().getStartLine() +select v, d.getLocation().getStartLine(), u.getLocation().getStartLine() diff --git a/java/ql/test/library-tests/defUse/useUse.ql b/java/ql/test/library-tests/defUse/useUse.ql index 2621aecf005..33b6c1b855d 100644 --- a/java/ql/test/library-tests/defUse/useUse.ql +++ b/java/ql/test/library-tests/defUse/useUse.ql @@ -3,4 +3,4 @@ import semmle.code.java.dataflow.DefUse from RValue u1, RValue u2, Variable v where useUsePair(u1, u2) and u1.getVariable() = v -select v,u1.getLocation().getStartLine(), u2.getLocation().getStartLine() +select v, u1.getLocation().getStartLine(), u2.getLocation().getStartLine() diff --git a/java/ql/test/library-tests/dependency-counts/NumDepends.ql b/java/ql/test/library-tests/dependency-counts/NumDepends.ql index b48b0ae97df..931099d545d 100644 --- a/java/ql/test/library-tests/dependency-counts/NumDepends.ql +++ b/java/ql/test/library-tests/dependency-counts/NumDepends.ql @@ -2,6 +2,7 @@ import java import semmle.code.java.DependencyCounts from RefType t, RefType dep, int num -where numDepends(t, dep, num) - and t.getFile().getStem() = "Example" +where + numDepends(t, dep, num) and + t.getFile().getStem() = "Example" select t, dep.getName(), num diff --git a/java/ql/test/library-tests/dependency/Depends.ql b/java/ql/test/library-tests/dependency/Depends.ql index 2cb49b946df..30f5b2c6c56 100644 --- a/java/ql/test/library-tests/dependency/Depends.ql +++ b/java/ql/test/library-tests/dependency/Depends.ql @@ -1,6 +1,7 @@ /** * @name Depends */ + import default from RefType rt1, RefType rt2 diff --git a/java/ql/test/library-tests/dependency/UsesType.ql b/java/ql/test/library-tests/dependency/UsesType.ql index c2358ccf205..f5ffc558643 100644 --- a/java/ql/test/library-tests/dependency/UsesType.ql +++ b/java/ql/test/library-tests/dependency/UsesType.ql @@ -1,6 +1,7 @@ /** * @name UsesType */ + import default from Type t, RefType rt diff --git a/java/ql/test/library-tests/dispatch/viableCallable.ql b/java/ql/test/library-tests/dispatch/viableCallable.ql index db07fe28819..2ab3552e3ee 100644 --- a/java/ql/test/library-tests/dispatch/viableCallable.ql +++ b/java/ql/test/library-tests/dispatch/viableCallable.ql @@ -2,7 +2,9 @@ import java import semmle.code.java.dispatch.VirtualDispatch from MethodAccess ma, Method m -where ma.getFile().toString().matches("ViableCallable%") -and ma.getMethod().getSourceDeclaration().fromSource() -and m = viableImpl(ma) -select ma, m.toString(), m.getDeclaringType().getLocation().getStartLine(), m.getDeclaringType().toString() +where + ma.getFile().toString().matches("ViableCallable%") and + ma.getMethod().getSourceDeclaration().fromSource() and + m = viableImpl(ma) +select ma, m.toString(), m.getDeclaringType().getLocation().getStartLine(), + m.getDeclaringType().toString() diff --git a/java/ql/test/library-tests/dispatch/virtualDispatch.ql b/java/ql/test/library-tests/dispatch/virtualDispatch.ql index 1b1c3779b1c..141feb0ea82 100644 --- a/java/ql/test/library-tests/dispatch/virtualDispatch.ql +++ b/java/ql/test/library-tests/dispatch/virtualDispatch.ql @@ -2,6 +2,7 @@ import default import semmle.code.java.dispatch.VirtualDispatch from MethodAccess m -where m.getEnclosingCallable().getName() = "run" -and m.getMethod().fromSource() +where + m.getEnclosingCallable().getName() = "run" and + m.getMethod().fromSource() select m, exactVirtualMethod(m) as def, def.getDeclaringType() diff --git a/java/ql/test/library-tests/fields/FieldAnnotations.ql b/java/ql/test/library-tests/fields/FieldAnnotations.ql index b06272a781f..7f28c79d6c7 100644 --- a/java/ql/test/library-tests/fields/FieldAnnotations.ql +++ b/java/ql/test/library-tests/fields/FieldAnnotations.ql @@ -1,6 +1,7 @@ import default from Annotation ann, Element elt -where elt = ann.getAnnotatedElement() and - elt.fromSource() +where + elt = ann.getAnnotatedElement() and + elt.fromSource() select ann, elt diff --git a/java/ql/test/library-tests/generics/BinaryTypeVars.ql b/java/ql/test/library-tests/generics/BinaryTypeVars.ql index 6ecf831a098..feae1d2ca37 100644 --- a/java/ql/test/library-tests/generics/BinaryTypeVars.ql +++ b/java/ql/test/library-tests/generics/BinaryTypeVars.ql @@ -1,15 +1,17 @@ import default from TypeVariable tv, string qname -where exists(GenericType gt | - gt = tv.getGenericType() and - gt.hasQualifiedName("java.util", "HashMap") and - qname = gt.getQualifiedName() - ) or - exists(GenericCallable gm | - gm = tv.getGenericCallable() and - gm.hasName("asList") and - gm.getDeclaringType().hasQualifiedName("java.util", "Arrays") and - qname = gm.getDeclaringType().getQualifiedName() + "." + gm.getSignature() - ) +where + exists(GenericType gt | + gt = tv.getGenericType() and + gt.hasQualifiedName("java.util", "HashMap") and + qname = gt.getQualifiedName() + ) + or + exists(GenericCallable gm | + gm = tv.getGenericCallable() and + gm.hasName("asList") and + gm.getDeclaringType().hasQualifiedName("java.util", "Arrays") and + qname = gm.getDeclaringType().getQualifiedName() + "." + gm.getSignature() + ) select tv.getName(), qname diff --git a/java/ql/test/library-tests/generics/SourceDeclaration.ql b/java/ql/test/library-tests/generics/SourceDeclaration.ql index 0179d6c207e..baac459b688 100644 --- a/java/ql/test/library-tests/generics/SourceDeclaration.ql +++ b/java/ql/test/library-tests/generics/SourceDeclaration.ql @@ -1,10 +1,11 @@ /** * @name SourceDeclaration */ + import default from Class cls, Class sourceDecl where - cls.getPackage().hasName("generics") - and cls.getSourceDeclaration() = sourceDecl + cls.getPackage().hasName("generics") and + cls.getSourceDeclaration() = sourceDecl select cls.getLocation().getStartLine(), cls, sourceDecl.getLocation().getStartLine(), sourceDecl diff --git a/java/ql/test/library-tests/generics/TypeVarsUpperBound.ql b/java/ql/test/library-tests/generics/TypeVarsUpperBound.ql index ea33adf28fa..83317e16ee6 100644 --- a/java/ql/test/library-tests/generics/TypeVarsUpperBound.ql +++ b/java/ql/test/library-tests/generics/TypeVarsUpperBound.ql @@ -1,6 +1,7 @@ import default from BoundedType bt -where bt.fromSource() or - exists(TypeAccess ta | ta.getType().(ParameterizedType).getATypeArgument() = bt) +where + bt.fromSource() or + exists(TypeAccess ta | ta.getType().(ParameterizedType).getATypeArgument() = bt) select bt, bt.getUpperBoundType().toString() diff --git a/java/ql/test/library-tests/guards/guards.ql b/java/ql/test/library-tests/guards/guards.ql index 30be5e81edc..e2d80a4e738 100644 --- a/java/ql/test/library-tests/guards/guards.ql +++ b/java/ql/test/library-tests/guards/guards.ql @@ -2,6 +2,7 @@ import java import semmle.code.java.controlflow.Guards from ConditionBlock cb, boolean testIsTrue, BasicBlock controlled -where cb.controls(controlled, testIsTrue) -and cb.getEnclosingCallable().getDeclaringType().hasName("Test") +where + cb.controls(controlled, testIsTrue) and + cb.getEnclosingCallable().getDeclaringType().hasName("Test") select cb.getCondition(), testIsTrue, controlled diff --git a/java/ql/test/library-tests/guards/guardslogic.ql b/java/ql/test/library-tests/guards/guardslogic.ql index f3283d568ce..516a8670473 100644 --- a/java/ql/test/library-tests/guards/guardslogic.ql +++ b/java/ql/test/library-tests/guards/guardslogic.ql @@ -2,7 +2,8 @@ import java import semmle.code.java.controlflow.Guards from Guard g, BasicBlock bb, boolean branch -where g.controls(bb, branch) -and not g instanceof ParExpr -and g.getEnclosingCallable().getDeclaringType().hasName("Logic") +where + g.controls(bb, branch) and + not g instanceof ParExpr and + g.getEnclosingCallable().getDeclaringType().hasName("Logic") select g, branch, bb diff --git a/java/ql/test/library-tests/j2objc/OCNIComment.ql b/java/ql/test/library-tests/j2objc/OCNIComment.ql index f47e159220f..8e206709a98 100644 --- a/java/ql/test/library-tests/j2objc/OCNIComment.ql +++ b/java/ql/test/library-tests/j2objc/OCNIComment.ql @@ -1,11 +1,6 @@ import semmle.code.java.frameworks.j2objc.J2ObjC from OCNIComment ocni -select - ocni.getFile().getStem(), - ocni.getLocation().getStartLine(), - ocni.getLocation().getStartColumn(), - ocni.getLocation().getEndLine(), - ocni.getLocation().getEndColumn(), - ocni.toString(), - ocni.getAQlClass() +select ocni.getFile().getStem(), ocni.getLocation().getStartLine(), + ocni.getLocation().getStartColumn(), ocni.getLocation().getEndLine(), + ocni.getLocation().getEndColumn(), ocni.toString(), ocni.getAQlClass() diff --git a/java/ql/test/library-tests/java7/MultiCatch/MultiCatch.ql b/java/ql/test/library-tests/java7/MultiCatch/MultiCatch.ql index 20f72e60b47..61e48930ea7 100644 --- a/java/ql/test/library-tests/java7/MultiCatch/MultiCatch.ql +++ b/java/ql/test/library-tests/java7/MultiCatch/MultiCatch.ql @@ -1,6 +1,7 @@ import default from CatchClause cc, UnionTypeAccess uta -where cc.isMultiCatch() and - uta = cc.getVariable().getTypeAccess() +where + cc.isMultiCatch() and + uta = cc.getVariable().getTypeAccess() select cc, uta.getAnAlternative(), uta.getType().toString() diff --git a/java/ql/test/library-tests/localvars/LocalVarDeclExprs.ql b/java/ql/test/library-tests/localvars/LocalVarDeclExprs.ql index 1c69e4ac4c8..e6dca62147a 100644 --- a/java/ql/test/library-tests/localvars/LocalVarDeclExprs.ql +++ b/java/ql/test/library-tests/localvars/LocalVarDeclExprs.ql @@ -1,8 +1,9 @@ import default from LocalVariableDeclExpr lvde, Type type, string name, string init, LocalVariableDecl var -where type = lvde.getType() and - name = lvde.getName() and - (if exists(lvde.getInit()) then init = lvde.getInit().toString() else init = "(none)") and - var = lvde.getVariable() +where + type = lvde.getType() and + name = lvde.getName() and + (if exists(lvde.getInit()) then init = lvde.getInit().toString() else init = "(none)") and + var = lvde.getVariable() select lvde, type.toString(), name, init, var diff --git a/java/ql/test/library-tests/locations/TypeLocations.ql b/java/ql/test/library-tests/locations/TypeLocations.ql index 428840ace29..643bd02b0e7 100644 --- a/java/ql/test/library-tests/locations/TypeLocations.ql +++ b/java/ql/test/library-tests/locations/TypeLocations.ql @@ -2,12 +2,18 @@ import default // restrict to built-in types accessed from source and source-level types to avoid dependencies on JDK version from Type t, string fp, int sl, int sc, int el, int ec -where ( - t instanceof PrimitiveType or - t instanceof VoidType or - t instanceof NullType or - (t instanceof Wildcard and exists(WildcardTypeAccess wta | wta.getType() = t)) or - (t instanceof Array and exists(ArrayTypeAccess ata | ata.getType() = t)) or +where + ( + t instanceof PrimitiveType + or + t instanceof VoidType + or + t instanceof NullType + or + (t instanceof Wildcard and exists(WildcardTypeAccess wta | wta.getType() = t)) + or + (t instanceof Array and exists(ArrayTypeAccess ata | ata.getType() = t)) + or t.fromSource() ) and t.hasLocationInfo(fp, sl, sc, el, ec) diff --git a/java/ql/test/library-tests/modifiers/EnumFinality.ql b/java/ql/test/library-tests/modifiers/EnumFinality.ql index 6fd41c81967..9d0ef09cc7f 100644 --- a/java/ql/test/library-tests/modifiers/EnumFinality.ql +++ b/java/ql/test/library-tests/modifiers/EnumFinality.ql @@ -1,6 +1,7 @@ import java from EnumType e, string isFinal -where e.fromSource() and - if e.isFinal() then isFinal = "final" else isFinal = "not final" +where + e.fromSource() and + if e.isFinal() then isFinal = "final" else isFinal = "not final" select e, isFinal diff --git a/java/ql/test/library-tests/overrides/ConstructedOverrides2.ql b/java/ql/test/library-tests/overrides/ConstructedOverrides2.ql index bb1b18583d9..43f1d0ba2d3 100644 --- a/java/ql/test/library-tests/overrides/ConstructedOverrides2.ql +++ b/java/ql/test/library-tests/overrides/ConstructedOverrides2.ql @@ -1,6 +1,7 @@ import java from Method c, Method d -where c.getSourceDeclaration().fromSource() - and c.overrides(d) +where + c.getSourceDeclaration().fromSource() and + c.overrides(d) select c.getDeclaringType(), c.getStringSignature(), d.getDeclaringType(), d.getStringSignature() diff --git a/java/ql/test/library-tests/qlengine/castAtType.ql b/java/ql/test/library-tests/qlengine/castAtType.ql index 6de0e323f0d..5556fe055f9 100644 --- a/java/ql/test/library-tests/qlengine/castAtType.ql +++ b/java/ql/test/library-tests/qlengine/castAtType.ql @@ -1,8 +1,8 @@ import java - from Class c, Member m -where c.hasQualifiedName("","Tst") and - c.getAMember() = m and - exists(m.(@field)) +where + c.hasQualifiedName("", "Tst") and + c.getAMember() = m and + exists(m.(@field)) select m diff --git a/java/ql/test/library-tests/qlengine/fromAtType.ql b/java/ql/test/library-tests/qlengine/fromAtType.ql index b002b23cef0..cba665fc091 100644 --- a/java/ql/test/library-tests/qlengine/fromAtType.ql +++ b/java/ql/test/library-tests/qlengine/fromAtType.ql @@ -1,4 +1,5 @@ import java + from @reftype t where t.(Class).hasName("Tst") select t.(Class) diff --git a/java/ql/test/library-tests/qlengine/instanceOfAtType.ql b/java/ql/test/library-tests/qlengine/instanceOfAtType.ql index 2998c50e68a..b7c51e42513 100644 --- a/java/ql/test/library-tests/qlengine/instanceOfAtType.ql +++ b/java/ql/test/library-tests/qlengine/instanceOfAtType.ql @@ -1,8 +1,8 @@ import java - from Class c, Member m -where c.hasQualifiedName("","Tst") and - c.getAMember() = m and - m instanceof @field +where + c.hasQualifiedName("", "Tst") and + c.getAMember() = m and + m instanceof @field select m diff --git a/java/ql/test/library-tests/qlengine/selectAtType.expected b/java/ql/test/library-tests/qlengine/selectAtType.expected index e891b0aaee1..e5eb1d6ba35 100644 --- a/java/ql/test/library-tests/qlengine/selectAtType.expected +++ b/java/ql/test/library-tests/qlengine/selectAtType.expected @@ -1 +1 @@ -ERROR: class or primitive expected in query (selectAtType.ql:7,8-15) +ERROR: class or primitive expected in query (selectAtType.ql:5,8-15) diff --git a/java/ql/test/library-tests/qlengine/selectAtType.ql b/java/ql/test/library-tests/qlengine/selectAtType.ql index b9dc4949fac..3947b504059 100644 --- a/java/ql/test/library-tests/qlengine/selectAtType.ql +++ b/java/ql/test/library-tests/qlengine/selectAtType.ql @@ -1,7 +1,5 @@ import java -@class clasz() { - any() -} +@class clasz() { any() } select clasz() diff --git a/java/ql/test/library-tests/ssa-large/countssa.ql b/java/ql/test/library-tests/ssa-large/countssa.ql index 8c283d5cad7..2289148a888 100644 --- a/java/ql/test/library-tests/ssa-large/countssa.ql +++ b/java/ql/test/library-tests/ssa-large/countssa.ql @@ -3,6 +3,6 @@ import semmle.code.java.dataflow.SSA from int uses, int live where -uses = strictcount(SsaVariable ssa, RValue use | use = ssa.getAUse()) and -live = strictcount(SsaVariable ssa, BasicBlock b | ssa.isLiveAtEndOfBlock(b)) + uses = strictcount(SsaVariable ssa, RValue use | use = ssa.getAUse()) and + live = strictcount(SsaVariable ssa, BasicBlock b | ssa.isLiveAtEndOfBlock(b)) select uses, live diff --git a/java/ql/test/library-tests/ssa/ssaDef.ql b/java/ql/test/library-tests/ssa/ssaDef.ql index fa3735982b5..9f08ddc0c40 100644 --- a/java/ql/test/library-tests/ssa/ssaDef.ql +++ b/java/ql/test/library-tests/ssa/ssaDef.ql @@ -2,6 +2,11 @@ import java import semmle.code.java.dataflow.SSA from SsaVariable ssa, SsaSourceVariable v, string s -where ssa.getSourceVariable() = v -and (s = ssa.toString() or not exists(ssa.toString()) and s = "error") +where + ssa.getSourceVariable() = v and + ( + s = ssa.toString() + or + not exists(ssa.toString()) and s = "error" + ) select v, ssa.getCFGNode(), s diff --git a/java/ql/test/library-tests/structure/DeclaresMember.ql b/java/ql/test/library-tests/structure/DeclaresMember.ql index 7bd36571b2e..c141ce29da5 100644 --- a/java/ql/test/library-tests/structure/DeclaresMember.ql +++ b/java/ql/test/library-tests/structure/DeclaresMember.ql @@ -1,9 +1,11 @@ /** * @name DeclaresMember */ + import default from Type t, Member m -where m.getDeclaringType() = t - and (t.fromSource() or t instanceof TypeObject) +where + m.getDeclaringType() = t and + (t.fromSource() or t instanceof TypeObject) select t.toString(), m.toString() diff --git a/java/ql/test/library-tests/structure/EnclosingCallables.ql b/java/ql/test/library-tests/structure/EnclosingCallables.ql index 0c2aa005bf9..f049a440d62 100644 --- a/java/ql/test/library-tests/structure/EnclosingCallables.ql +++ b/java/ql/test/library-tests/structure/EnclosingCallables.ql @@ -8,6 +8,4 @@ string printableEnclosingCallable(Expr e) { from Expr e where e.getFile().toString() = "A" -select - e, - printableEnclosingCallable(e) +select e, printableEnclosingCallable(e) diff --git a/java/ql/test/library-tests/structure/EnclosingStatements.ql b/java/ql/test/library-tests/structure/EnclosingStatements.ql index 08108d5f5e1..44ea9d9b9ff 100644 --- a/java/ql/test/library-tests/structure/EnclosingStatements.ql +++ b/java/ql/test/library-tests/structure/EnclosingStatements.ql @@ -8,6 +8,4 @@ string printableEnclosingStmt(Expr e) { from Expr e where e.getFile().toString() = "A" -select - e, - printableEnclosingStmt(e) +select e, printableEnclosingStmt(e) diff --git a/java/ql/test/library-tests/structure/HasMethod.ql b/java/ql/test/library-tests/structure/HasMethod.ql index 0293ed98fb6..a88bde2e005 100644 --- a/java/ql/test/library-tests/structure/HasMethod.ql +++ b/java/ql/test/library-tests/structure/HasMethod.ql @@ -1,6 +1,7 @@ /** * @name HasMethod */ + import default from RefType inheritor, Method method, RefType declarer diff --git a/java/ql/test/library-tests/structure/HasObjectMethod.ql b/java/ql/test/library-tests/structure/HasObjectMethod.ql index 8d47431defc..c659eee2d77 100644 --- a/java/ql/test/library-tests/structure/HasObjectMethod.ql +++ b/java/ql/test/library-tests/structure/HasObjectMethod.ql @@ -1,9 +1,13 @@ /** * @name HasMethod */ + import default from RefType inheritor, Method method, RefType declarer -where inheritor.hasMethod(method, declarer) and inheritor.fromSource() -and declarer.hasName("Object") and inheritor.getFile().toString() = "Inherit" +where + inheritor.hasMethod(method, declarer) and + inheritor.fromSource() and + declarer.hasName("Object") and + inheritor.getFile().toString() = "Inherit" select inheritor.toString(), method.toString(), declarer.toString() diff --git a/java/ql/test/library-tests/structure/InSameTopLevelType.ql b/java/ql/test/library-tests/structure/InSameTopLevelType.ql index 73f62f3100e..aae3a71825c 100644 --- a/java/ql/test/library-tests/structure/InSameTopLevelType.ql +++ b/java/ql/test/library-tests/structure/InSameTopLevelType.ql @@ -1,11 +1,14 @@ /** * @name InSameTopLevelType */ + import default from Element e, Element f -where exists(TopLevelType t | t.hasChildElement*(e) and t.hasChildElement*(f)) and - e.fromSource() and f.fromSource() and - e.getName() < f.getName() and - e.getFile().toString() = "A" +where + exists(TopLevelType t | t.hasChildElement*(e) and t.hasChildElement*(f)) and + e.fromSource() and + f.fromSource() and + e.getName() < f.getName() and + e.getFile().toString() = "A" select e, f diff --git a/java/ql/test/library-tests/structure/IsInType.ql b/java/ql/test/library-tests/structure/IsInType.ql index e7592b3f19c..7c3412b5862 100644 --- a/java/ql/test/library-tests/structure/IsInType.ql +++ b/java/ql/test/library-tests/structure/IsInType.ql @@ -1,6 +1,7 @@ /** * @name IsInType */ + import default from Element e, RefType t diff --git a/java/ql/test/library-tests/structure/IsNestedType.ql b/java/ql/test/library-tests/structure/IsNestedType.ql index b70f249d51b..50aaf4caecb 100644 --- a/java/ql/test/library-tests/structure/IsNestedType.ql +++ b/java/ql/test/library-tests/structure/IsNestedType.ql @@ -1,6 +1,7 @@ /** * @name IsNestedType */ + import default from RefType t diff --git a/java/ql/test/library-tests/structure/IsTopLevelType.ql b/java/ql/test/library-tests/structure/IsTopLevelType.ql index ba6ca697b1a..1e15dd838eb 100644 --- a/java/ql/test/library-tests/structure/IsTopLevelType.ql +++ b/java/ql/test/library-tests/structure/IsTopLevelType.ql @@ -1,6 +1,7 @@ /** * @name IsTopLevelType */ + import default from TopLevelType tp diff --git a/java/ql/test/library-tests/structure/OuterType.ql b/java/ql/test/library-tests/structure/OuterType.ql index 6f5a80bdcd8..eaa2f26584e 100644 --- a/java/ql/test/library-tests/structure/OuterType.ql +++ b/java/ql/test/library-tests/structure/OuterType.ql @@ -1,6 +1,7 @@ /** * @name OuterType */ + import default from TopLevelType t diff --git a/java/ql/test/library-tests/structure/TypeGetCompilationUnit.ql b/java/ql/test/library-tests/structure/TypeGetCompilationUnit.ql index 720a145e5fa..f3a335b8fc0 100644 --- a/java/ql/test/library-tests/structure/TypeGetCompilationUnit.ql +++ b/java/ql/test/library-tests/structure/TypeGetCompilationUnit.ql @@ -1,12 +1,9 @@ import semmle.code.java.Type -predicate typeIsInCU(Type tpe, CompilationUnit cu) { - tpe.getCompilationUnit() = cu -} - +predicate typeIsInCU(Type tpe, CompilationUnit cu) { tpe.getCompilationUnit() = cu } from Type tpe, CompilationUnit Ajava where - Ajava.hasName("A") - and typeIsInCU(tpe, Ajava) + Ajava.hasName("A") and + typeIsInCU(tpe, Ajava) select tpe diff --git a/java/ql/test/library-tests/structure/TypeIsInPackage.ql b/java/ql/test/library-tests/structure/TypeIsInPackage.ql index 8783459eb23..c9b657215c8 100644 --- a/java/ql/test/library-tests/structure/TypeIsInPackage.ql +++ b/java/ql/test/library-tests/structure/TypeIsInPackage.ql @@ -1,6 +1,7 @@ /** * @name TypeIsInPackage */ + import default from RefType tp diff --git a/java/ql/test/library-tests/successors/CloseReaderTest/TestSucc.ql b/java/ql/test/library-tests/successors/CloseReaderTest/TestSucc.ql index 1233ba0ee52..9de77b3c42b 100644 --- a/java/ql/test/library-tests/successors/CloseReaderTest/TestSucc.ql +++ b/java/ql/test/library-tests/successors/CloseReaderTest/TestSucc.ql @@ -1,6 +1,8 @@ import java from ControlFlowNode n, ControlFlowNode succ -where succ = n.getASuccessor() and n.getLocation().getFile().getExtension() = "java" and - not n.getFile().getStem() = "PopulateRuntimeException" +where + succ = n.getASuccessor() and + n.getLocation().getFile().getExtension() = "java" and + not n.getFile().getStem() = "PopulateRuntimeException" select n, succ diff --git a/java/ql/test/library-tests/successors/LoopVarReadTest/TestSucc.ql b/java/ql/test/library-tests/successors/LoopVarReadTest/TestSucc.ql index 1233ba0ee52..9de77b3c42b 100644 --- a/java/ql/test/library-tests/successors/LoopVarReadTest/TestSucc.ql +++ b/java/ql/test/library-tests/successors/LoopVarReadTest/TestSucc.ql @@ -1,6 +1,8 @@ import java from ControlFlowNode n, ControlFlowNode succ -where succ = n.getASuccessor() and n.getLocation().getFile().getExtension() = "java" and - not n.getFile().getStem() = "PopulateRuntimeException" +where + succ = n.getASuccessor() and + n.getLocation().getFile().getExtension() = "java" and + not n.getFile().getStem() = "PopulateRuntimeException" select n, succ diff --git a/java/ql/test/library-tests/successors/SaveFileTest/TestSucc.ql b/java/ql/test/library-tests/successors/SaveFileTest/TestSucc.ql index 1233ba0ee52..9de77b3c42b 100644 --- a/java/ql/test/library-tests/successors/SaveFileTest/TestSucc.ql +++ b/java/ql/test/library-tests/successors/SaveFileTest/TestSucc.ql @@ -1,6 +1,8 @@ import java from ControlFlowNode n, ControlFlowNode succ -where succ = n.getASuccessor() and n.getLocation().getFile().getExtension() = "java" and - not n.getFile().getStem() = "PopulateRuntimeException" +where + succ = n.getASuccessor() and + n.getLocation().getFile().getExtension() = "java" and + not n.getFile().getStem() = "PopulateRuntimeException" select n, succ diff --git a/java/ql/test/library-tests/successors/SchackTest/TestSucc.ql b/java/ql/test/library-tests/successors/SchackTest/TestSucc.ql index 1233ba0ee52..9de77b3c42b 100644 --- a/java/ql/test/library-tests/successors/SchackTest/TestSucc.ql +++ b/java/ql/test/library-tests/successors/SchackTest/TestSucc.ql @@ -1,6 +1,8 @@ import java from ControlFlowNode n, ControlFlowNode succ -where succ = n.getASuccessor() and n.getLocation().getFile().getExtension() = "java" and - not n.getFile().getStem() = "PopulateRuntimeException" +where + succ = n.getASuccessor() and + n.getLocation().getFile().getExtension() = "java" and + not n.getFile().getStem() = "PopulateRuntimeException" select n, succ diff --git a/java/ql/test/library-tests/successors/TestBreak/TestSucc.ql b/java/ql/test/library-tests/successors/TestBreak/TestSucc.ql index 1233ba0ee52..9de77b3c42b 100644 --- a/java/ql/test/library-tests/successors/TestBreak/TestSucc.ql +++ b/java/ql/test/library-tests/successors/TestBreak/TestSucc.ql @@ -1,6 +1,8 @@ import java from ControlFlowNode n, ControlFlowNode succ -where succ = n.getASuccessor() and n.getLocation().getFile().getExtension() = "java" and - not n.getFile().getStem() = "PopulateRuntimeException" +where + succ = n.getASuccessor() and + n.getLocation().getFile().getExtension() = "java" and + not n.getFile().getStem() = "PopulateRuntimeException" select n, succ diff --git a/java/ql/test/library-tests/successors/TestContinue/TestSucc.ql b/java/ql/test/library-tests/successors/TestContinue/TestSucc.ql index 1233ba0ee52..9de77b3c42b 100644 --- a/java/ql/test/library-tests/successors/TestContinue/TestSucc.ql +++ b/java/ql/test/library-tests/successors/TestContinue/TestSucc.ql @@ -1,6 +1,8 @@ import java from ControlFlowNode n, ControlFlowNode succ -where succ = n.getASuccessor() and n.getLocation().getFile().getExtension() = "java" and - not n.getFile().getStem() = "PopulateRuntimeException" +where + succ = n.getASuccessor() and + n.getLocation().getFile().getExtension() = "java" and + not n.getFile().getStem() = "PopulateRuntimeException" select n, succ diff --git a/java/ql/test/library-tests/successors/TestDeclarations/TestSucc.ql b/java/ql/test/library-tests/successors/TestDeclarations/TestSucc.ql index 1233ba0ee52..9de77b3c42b 100644 --- a/java/ql/test/library-tests/successors/TestDeclarations/TestSucc.ql +++ b/java/ql/test/library-tests/successors/TestDeclarations/TestSucc.ql @@ -1,6 +1,8 @@ import java from ControlFlowNode n, ControlFlowNode succ -where succ = n.getASuccessor() and n.getLocation().getFile().getExtension() = "java" and - not n.getFile().getStem() = "PopulateRuntimeException" +where + succ = n.getASuccessor() and + n.getLocation().getFile().getExtension() = "java" and + not n.getFile().getStem() = "PopulateRuntimeException" select n, succ diff --git a/java/ql/test/library-tests/successors/TestFinally/TestSucc.ql b/java/ql/test/library-tests/successors/TestFinally/TestSucc.ql index 1233ba0ee52..9de77b3c42b 100644 --- a/java/ql/test/library-tests/successors/TestFinally/TestSucc.ql +++ b/java/ql/test/library-tests/successors/TestFinally/TestSucc.ql @@ -1,6 +1,8 @@ import java from ControlFlowNode n, ControlFlowNode succ -where succ = n.getASuccessor() and n.getLocation().getFile().getExtension() = "java" and - not n.getFile().getStem() = "PopulateRuntimeException" +where + succ = n.getASuccessor() and + n.getLocation().getFile().getExtension() = "java" and + not n.getFile().getStem() = "PopulateRuntimeException" select n, succ diff --git a/java/ql/test/library-tests/successors/TestFinallyBreakContinue/TestSucc.ql b/java/ql/test/library-tests/successors/TestFinallyBreakContinue/TestSucc.ql index 1233ba0ee52..9de77b3c42b 100644 --- a/java/ql/test/library-tests/successors/TestFinallyBreakContinue/TestSucc.ql +++ b/java/ql/test/library-tests/successors/TestFinallyBreakContinue/TestSucc.ql @@ -1,6 +1,8 @@ import java from ControlFlowNode n, ControlFlowNode succ -where succ = n.getASuccessor() and n.getLocation().getFile().getExtension() = "java" and - not n.getFile().getStem() = "PopulateRuntimeException" +where + succ = n.getASuccessor() and + n.getLocation().getFile().getExtension() = "java" and + not n.getFile().getStem() = "PopulateRuntimeException" select n, succ diff --git a/java/ql/test/library-tests/successors/TestLoopBranch/TestSucc.ql b/java/ql/test/library-tests/successors/TestLoopBranch/TestSucc.ql index 1233ba0ee52..9de77b3c42b 100644 --- a/java/ql/test/library-tests/successors/TestLoopBranch/TestSucc.ql +++ b/java/ql/test/library-tests/successors/TestLoopBranch/TestSucc.ql @@ -1,6 +1,8 @@ import java from ControlFlowNode n, ControlFlowNode succ -where succ = n.getASuccessor() and n.getLocation().getFile().getExtension() = "java" and - not n.getFile().getStem() = "PopulateRuntimeException" +where + succ = n.getASuccessor() and + n.getLocation().getFile().getExtension() = "java" and + not n.getFile().getStem() = "PopulateRuntimeException" select n, succ diff --git a/java/ql/test/library-tests/successors/TestThrow/TestSucc.ql b/java/ql/test/library-tests/successors/TestThrow/TestSucc.ql index 1233ba0ee52..9de77b3c42b 100644 --- a/java/ql/test/library-tests/successors/TestThrow/TestSucc.ql +++ b/java/ql/test/library-tests/successors/TestThrow/TestSucc.ql @@ -1,6 +1,8 @@ import java from ControlFlowNode n, ControlFlowNode succ -where succ = n.getASuccessor() and n.getLocation().getFile().getExtension() = "java" and - not n.getFile().getStem() = "PopulateRuntimeException" +where + succ = n.getASuccessor() and + n.getLocation().getFile().getExtension() = "java" and + not n.getFile().getStem() = "PopulateRuntimeException" select n, succ diff --git a/java/ql/test/library-tests/successors/TestThrow2/TestSucc.ql b/java/ql/test/library-tests/successors/TestThrow2/TestSucc.ql index 1233ba0ee52..9de77b3c42b 100644 --- a/java/ql/test/library-tests/successors/TestThrow2/TestSucc.ql +++ b/java/ql/test/library-tests/successors/TestThrow2/TestSucc.ql @@ -1,6 +1,8 @@ import java from ControlFlowNode n, ControlFlowNode succ -where succ = n.getASuccessor() and n.getLocation().getFile().getExtension() = "java" and - not n.getFile().getStem() = "PopulateRuntimeException" +where + succ = n.getASuccessor() and + n.getLocation().getFile().getExtension() = "java" and + not n.getFile().getStem() = "PopulateRuntimeException" select n, succ diff --git a/java/ql/test/library-tests/successors/TestTryCatch/TestSucc.ql b/java/ql/test/library-tests/successors/TestTryCatch/TestSucc.ql index 1233ba0ee52..9de77b3c42b 100644 --- a/java/ql/test/library-tests/successors/TestTryCatch/TestSucc.ql +++ b/java/ql/test/library-tests/successors/TestTryCatch/TestSucc.ql @@ -1,6 +1,8 @@ import java from ControlFlowNode n, ControlFlowNode succ -where succ = n.getASuccessor() and n.getLocation().getFile().getExtension() = "java" and - not n.getFile().getStem() = "PopulateRuntimeException" +where + succ = n.getASuccessor() and + n.getLocation().getFile().getExtension() = "java" and + not n.getFile().getStem() = "PopulateRuntimeException" select n, succ diff --git a/java/ql/test/library-tests/successors/TestTryWithResources/TestSucc.ql b/java/ql/test/library-tests/successors/TestTryWithResources/TestSucc.ql index 1233ba0ee52..9de77b3c42b 100644 --- a/java/ql/test/library-tests/successors/TestTryWithResources/TestSucc.ql +++ b/java/ql/test/library-tests/successors/TestTryWithResources/TestSucc.ql @@ -1,6 +1,8 @@ import java from ControlFlowNode n, ControlFlowNode succ -where succ = n.getASuccessor() and n.getLocation().getFile().getExtension() = "java" and - not n.getFile().getStem() = "PopulateRuntimeException" +where + succ = n.getASuccessor() and + n.getLocation().getFile().getExtension() = "java" and + not n.getFile().getStem() = "PopulateRuntimeException" select n, succ diff --git a/java/ql/test/library-tests/typeflow/typeflow.ql b/java/ql/test/library-tests/typeflow/typeflow.ql index 52b9a84cf4d..e6d3d32d6b2 100644 --- a/java/ql/test/library-tests/typeflow/typeflow.ql +++ b/java/ql/test/library-tests/typeflow/typeflow.ql @@ -2,6 +2,5 @@ import java import semmle.code.java.dataflow.TypeFlow from RValue e, RefType t, boolean exact -where - exprTypeFlow(e, t, exact) +where exprTypeFlow(e, t, exact) select e, t.toString(), exact diff --git a/java/ql/test/library-tests/varargs/Varargs.ql b/java/ql/test/library-tests/varargs/Varargs.ql index e81c7342e1b..27622ebd5ba 100644 --- a/java/ql/test/library-tests/varargs/Varargs.ql +++ b/java/ql/test/library-tests/varargs/Varargs.ql @@ -1,7 +1,8 @@ import default from Callable c, Parameter varargparm -where varargparm = c.getAParameter() and - varargparm.isVarargs() and - (exists(c.getAReference()) or c.fromSource()) +where + varargparm = c.getAParameter() and + varargparm.isVarargs() and + (exists(c.getAReference()) or c.fromSource()) select c.getDeclaringType().getQualifiedName(), c.getStringSignature(), varargparm.getName() diff --git a/java/ql/test/query-tests/lgtm-example-queries/voidreturntype.ql b/java/ql/test/query-tests/lgtm-example-queries/voidreturntype.ql index 5377902fac9..5ad4e7e07e2 100644 --- a/java/ql/test/query-tests/lgtm-example-queries/voidreturntype.ql +++ b/java/ql/test/query-tests/lgtm-example-queries/voidreturntype.ql @@ -11,6 +11,7 @@ import java from Method m -where m.getReturnType() instanceof VoidType - and m.fromSource() +where + m.getReturnType() instanceof VoidType and + m.fromSource() select m diff --git a/java/ql/test/query-tests/maven-dependencies/MavenDeps.ql b/java/ql/test/query-tests/maven-dependencies/MavenDeps.ql index 50ed66456e3..6ac6bedb81b 100644 --- a/java/ql/test/query-tests/maven-dependencies/MavenDeps.ql +++ b/java/ql/test/query-tests/maven-dependencies/MavenDeps.ql @@ -8,4 +8,3 @@ import semmle.code.xml.MavenPom from Dependency d select d, d.getParent*().(Pom), d.getPom() - diff --git a/java/ql/test/query-tests/security/CWE-089/semmle/examples/controlledString.ql b/java/ql/test/query-tests/security/CWE-089/semmle/examples/controlledString.ql index 614e204cbae..b3f5bfe8676 100644 --- a/java/ql/test/query-tests/security/CWE-089/semmle/examples/controlledString.ql +++ b/java/ql/test/query-tests/security/CWE-089/semmle/examples/controlledString.ql @@ -2,8 +2,8 @@ import semmle.code.java.security.ControlledString from Expr controlled, Method method, int line where - controlledString(controlled) - and method = controlled.getEnclosingCallable() - and line = controlled.getLocation().getStartLine() - method.getLocation().getStartLine() - and controlled.getCompilationUnit().fromSource() + controlledString(controlled) and + method = controlled.getEnclosingCallable() and + line = controlled.getLocation().getStartLine() - method.getLocation().getStartLine() and + controlled.getCompilationUnit().fromSource() select method.getName(), line, controlled diff --git a/java/ql/test/query-tests/security/CWE-089/semmle/examples/endsInQuote.ql b/java/ql/test/query-tests/security/CWE-089/semmle/examples/endsInQuote.ql index 90579ef9c05..369cd0cc4d2 100644 --- a/java/ql/test/query-tests/security/CWE-089/semmle/examples/endsInQuote.ql +++ b/java/ql/test/query-tests/security/CWE-089/semmle/examples/endsInQuote.ql @@ -2,7 +2,5 @@ import semmle.code.java.security.ControlledString from Expr precedes, Method method where endsInQuote(precedes) and precedes.getEnclosingCallable() = method -select - method.getName(), - precedes.getLocation().getStartLine() - method.getLocation().getStartLine(), - precedes +select method.getName(), + precedes.getLocation().getStartLine() - method.getLocation().getStartLine(), precedes diff --git a/java/ql/test/query-tests/security/CWE-089/semmle/examples/getAnAppend.ql b/java/ql/test/query-tests/security/CWE-089/semmle/examples/getAnAppend.ql index b02ebc79825..96f5bad1a8c 100644 --- a/java/ql/test/query-tests/security/CWE-089/semmle/examples/getAnAppend.ql +++ b/java/ql/test/query-tests/security/CWE-089/semmle/examples/getAnAppend.ql @@ -2,11 +2,6 @@ import semmle.code.java.dataflow.TaintTracking from StringBuilderVar sbv, MethodAccess append, Method method where sbv.getAnAppend() = append and append.getEnclosingCallable() = method -select - method.getName(), - sbv.getLocation().getStartLine() - method.getLocation().getStartLine(), - sbv, - append.getLocation().getStartLine() - method.getLocation().getStartLine(), - append, +select method.getName(), sbv.getLocation().getStartLine() - method.getLocation().getStartLine(), + sbv, append.getLocation().getStartLine() - method.getLocation().getStartLine(), append, append.getArgument(0) - diff --git a/java/ql/test/query-tests/security/CWE-089/semmle/examples/getToStringCall.ql b/java/ql/test/query-tests/security/CWE-089/semmle/examples/getToStringCall.ql index 3a93badf489..812c9cdd6b0 100644 --- a/java/ql/test/query-tests/security/CWE-089/semmle/examples/getToStringCall.ql +++ b/java/ql/test/query-tests/security/CWE-089/semmle/examples/getToStringCall.ql @@ -2,9 +2,5 @@ import semmle.code.java.dataflow.TaintTracking from StringBuilderVar sbv, MethodAccess toString, Method method where sbv.getToStringCall() = toString and toString.getEnclosingCallable() = method -select - method.getName(), - sbv.getLocation().getStartLine() - method.getLocation().getStartLine(), - sbv, - toString.getLocation().getStartLine() - method.getLocation().getStartLine(), - toString +select method.getName(), sbv.getLocation().getStartLine() - method.getLocation().getStartLine(), + sbv, toString.getLocation().getStartLine() - method.getLocation().getStartLine(), toString diff --git a/java/ql/test/query-tests/security/CWE-089/semmle/examples/sbQuery.ql b/java/ql/test/query-tests/security/CWE-089/semmle/examples/sbQuery.ql index 1fa38c728cb..63fe72f989e 100644 --- a/java/ql/test/query-tests/security/CWE-089/semmle/examples/sbQuery.ql +++ b/java/ql/test/query-tests/security/CWE-089/semmle/examples/sbQuery.ql @@ -2,13 +2,8 @@ import semmle.code.java.security.SqlUnescapedLib from StringBuilderVar sbv, Expr uncontrolled, Method method, int methodLine where - uncontrolledStringBuilderQuery(sbv, uncontrolled) - and method = uncontrolled.getEnclosingCallable() - and methodLine = method.getLocation().getStartLine() -select - method.getName(), - sbv.getLocation().getStartLine() - methodLine, - sbv, - uncontrolled.getLocation().getStartLine() - methodLine, - uncontrolled - + uncontrolledStringBuilderQuery(sbv, uncontrolled) and + method = uncontrolled.getEnclosingCallable() and + methodLine = method.getLocation().getStartLine() +select method.getName(), sbv.getLocation().getStartLine() - methodLine, sbv, + uncontrolled.getLocation().getStartLine() - methodLine, uncontrolled diff --git a/java/ql/test/query-tests/security/CWE-089/semmle/examples/taintedString.ql b/java/ql/test/query-tests/security/CWE-089/semmle/examples/taintedString.ql index 945d1c29310..73b8290e716 100644 --- a/java/ql/test/query-tests/security/CWE-089/semmle/examples/taintedString.ql +++ b/java/ql/test/query-tests/security/CWE-089/semmle/examples/taintedString.ql @@ -2,13 +2,12 @@ import semmle.code.java.dataflow.FlowSources class Conf extends TaintTracking::Configuration { Conf() { this = "qltest:cwe-089:taintedString" } + override predicate isSource(DataFlow::Node source) { source instanceof UserInput } + override predicate isSink(DataFlow::Node sink) { any() } } from Conf conf, Expr tainted, Method method where conf.hasFlowToExpr(tainted) and tainted.getEnclosingCallable() = method -select - method, - tainted.getLocation().getStartLine() - method.getLocation().getStartLine(), - tainted +select method, tainted.getLocation().getStartLine() - method.getLocation().getStartLine(), tainted