Java: Autoformat.

This commit is contained in:
Anders Schack-Mulligen
2018-10-11 10:02:20 +02:00
parent 766b07ba59
commit 62ef811169
8 changed files with 165 additions and 156 deletions

View File

@@ -20,26 +20,24 @@ predicate whitelist(Dependency d) {
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."

View File

@@ -13,18 +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."

View File

@@ -9,20 +9,23 @@
* 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

View File

@@ -9,6 +9,7 @@
* @tags maintainability
* external/cwe/cwe-561
*/
import java
import semmle.code.java.deadcode.DeadCode
@@ -16,31 +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

View File

@@ -37,9 +37,7 @@ class InstanceFieldWrite extends FieldWrite {
*/
class ImpureStmt extends Stmt {
ImpureStmt() {
exists(Expr e |
e.getEnclosingStmt() = this
|
exists(Expr e | e.getEnclosingStmt() = this |
// Only permit calls to set of whitelisted targets.
(
e instanceof Call and
@@ -57,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,12 +71,8 @@ class SpringPureClass extends Class {
(
// 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()
|
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
@@ -88,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
@@ -103,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)
)
}
@@ -130,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.
*/
@@ -139,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()
)
}
@@ -158,7 +150,8 @@ 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
@@ -170,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()
)
@@ -218,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

View File

@@ -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
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
(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() |

View File

@@ -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,18 +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.
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
)
@@ -145,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."

View File

@@ -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,7 +69,7 @@ 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,
@@ -90,21 +83,22 @@ where
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