Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions java/ql/src/semmle/code/java/Collections.qll
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
/**
* Provides classes and predicates for reasoning about instances of
* `java.util.Collection` and their methods.
*/

import java

/**
Expand Down Expand Up @@ -77,6 +82,7 @@ class CollectionMutator extends CollectionMethod {
class CollectionMutation extends MethodAccess {
CollectionMutation() { this.getMethod() instanceof CollectionMutator }

/** Holds if the result of this call is not immediately discarded. */
predicate resultIsChecked() { not this.getParent() instanceof ExprStmt }
}

Expand Down
8 changes: 7 additions & 1 deletion java/ql/src/semmle/code/java/Completion.qll
Original file line number Diff line number Diff line change
Expand Up @@ -68,21 +68,27 @@ newtype Completion =
*/
ThrowCompletion(ThrowableType tt)

/** A completion that is either a `NormalCompletion` or a `BooleanCompletion`. */
class NormalOrBooleanCompletion extends Completion {
NormalOrBooleanCompletion() {
this instanceof NormalCompletion or this instanceof BooleanCompletion
}

/** Gets a textual representation of this completion. */
string toString() { result = "completion" }
}

/** Gets the completion `ContinueCompletion(NoLabel())`. */
ContinueCompletion anonymousContinueCompletion() { result = ContinueCompletion(NoLabel()) }

/** Gets the completion `ContinueCompletion(JustLabel(l))`. */
ContinueCompletion labelledContinueCompletion(Label l) { result = ContinueCompletion(JustLabel(l)) }

/** Gets the completion `BreakCompletion(NoLabel())`. */
BreakCompletion anonymousBreakCompletion() { result = BreakCompletion(NoLabel()) }

/** Gets the completion `BreakCompletion(JustLabel(l))`. */
BreakCompletion labelledBreakCompletion(Label l) { result = BreakCompletion(JustLabel(l)) }

/** Gets the completion `booleanCompletion(value, value)`. */
/** Gets the completion `BooleanCompletion(value, value)`. */
Completion basicBooleanCompletion(boolean value) { result = BooleanCompletion(value, value) }
1 change: 1 addition & 0 deletions java/ql/src/semmle/code/java/ControlFlowGraph.qll
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ class ControlFlowNode extends Top, @exprparent {
result = succ(this, NormalCompletion())
}

/** Gets the basic block that contains this node. */
BasicBlock getBasicBlock() { result.getANode() = this }
}

Expand Down
1 change: 1 addition & 0 deletions java/ql/src/semmle/code/java/Expr.qll
Original file line number Diff line number Diff line change
Expand Up @@ -844,6 +844,7 @@ class EqualityTest extends BinaryExpr {
this instanceof NEExpr
}

/** Gets a boolean indicating whether this is `==` (true) or `!=` (false). */
boolean polarity() {
result = true and this instanceof EQExpr
or
Expand Down
8 changes: 8 additions & 0 deletions java/ql/src/semmle/code/java/Maps.qll
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
/**
* Provides classes and predicates for reasoning about instances of
* `java.util.Map` and their methods.
*/

import java
import Collections

Expand Down Expand Up @@ -47,6 +52,7 @@ class MapSizeMethod extends MapMethod {
class MapMutation extends MethodAccess {
MapMutation() { this.getMethod() instanceof MapMutator }

/** Holds if the result of this call is not immediately discarded. */
predicate resultIsChecked() { not this.getParent() instanceof ExprStmt }
}

Expand All @@ -72,7 +78,9 @@ class FreshMap extends ClassInstanceExpr {
class MapPutCall extends MethodAccess {
MapPutCall() { getCallee().(MapMethod).hasName("put") }

/** Gets the key argument of this call. */
Expr getKey() { result = getArgument(0) }

/** Gets the value argument of this call. */
Expr getValue() { result = getArgument(1) }
}
3 changes: 3 additions & 0 deletions java/ql/src/semmle/code/java/Reflection.qll
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@ import JDKAnnotations
import Serializability
import semmle.code.java.dataflow.DefUse

/** Holds if `f` is a field that may be read by reflection. */
predicate reflectivelyRead(Field f) {
f instanceof SerializableField or
f.getAnAnnotation() instanceof ReflectiveAccessAnnotation or
referencedInXmlFile(f)
}

/** Holds if `f` is a field that may be written by reflection. */
predicate reflectivelyWritten(Field f) {
f instanceof DeserializableField or
f.getAnAnnotation() instanceof ReflectiveAccessAnnotation or
Expand Down Expand Up @@ -360,6 +362,7 @@ class ReflectiveFieldAccess extends ClassMethodAccess {
this.getCallee().hasName("getDeclaredField")
}

/** Gets the field accessed by this call. */
Field inferAccessedField() {
(
if this.getCallee().hasName("getDeclaredField")
Expand Down
3 changes: 3 additions & 0 deletions java/ql/src/semmle/code/java/StringFormat.qll
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ private newtype TFmtSyntax =

/** A syntax for format strings. */
class FmtSyntax extends TFmtSyntax {
/** Gets a textual representation of this format string syntax. */
string toString() {
result = "printf (%) syntax" and this = TFmtPrintf()
or
Expand Down Expand Up @@ -130,6 +131,7 @@ class FormattingCall extends Call {
formatWrapper(this.getCallee(), result, _)
}

/** Gets the format string syntax used by this call. */
FmtSyntax getSyntax() {
this.getCallee() instanceof StringFormatMethod and result = TFmtPrintf()
or
Expand All @@ -146,6 +148,7 @@ class FormattingCall extends Call {
)
}

/** Holds if this uses the "logger ({})" format syntax and the last argument is a `Throwable`. */
predicate hasTrailingThrowableArgument() {
getSyntax() = TFmtLogger() and
getLastArg().getType().(RefType).getASourceSupertype*() instanceof TypeThrowable
Expand Down
2 changes: 2 additions & 0 deletions java/ql/src/semmle/code/java/Type.qll
Original file line number Diff line number Diff line change
Expand Up @@ -637,10 +637,12 @@ class IntersectionType extends RefType, @class {

private RefType superInterface() { implInterface(this, result) }

/** Gets a textual representation of this type that includes all the intersected types. */
string getLongName() {
result = superType().toString() + concat(" & " + superInterface().toString())
}

/** Gets the first bound of this intersection type. */
RefType getFirstBound() { extendsReftype(this, result) }
}

Expand Down
5 changes: 5 additions & 0 deletions java/ql/src/semmle/code/java/controlflow/Guards.qll
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
/**
* Provides classes and predicates for reasoning about guards and the control
* flow elements controlled by those guards.
*/

import java
private import semmle.code.java.controlflow.Dominance
private import semmle.code.java.controlflow.internal.GuardsLogic
Expand Down
12 changes: 12 additions & 0 deletions java/ql/src/semmle/code/java/dataflow/Bound.qll
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/**
* Provides classes for representing abstract bounds for use in, for example, range analysis.
*/

import java
private import SSA
private import RangeUtils
Expand All @@ -14,6 +18,7 @@ private newtype TBound =
* A bound that may be inferred for an expression plus/minus an integer delta.
*/
abstract class Bound extends TBound {
/** Gets a textual representation of this bound. */
abstract string toString();

/** Gets an expression that equals this bound plus `delta`. */
Expand All @@ -22,6 +27,13 @@ abstract class Bound extends TBound {
/** Gets an expression that equals this bound. */
Expr getExpr() { result = getExpr(0) }

/**
* Holds if this element is at the specified location.
* The location spans column `sc` of line `sl` to
* column `ec` of line `el` in file `path`.
* For more information, see
* [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
*/
predicate hasLocationInfo(string path, int sl, int sc, int el, int ec) {
path = "" and sl = 0 and sc = 0 and el = 0 and ec = 0
}
Expand Down
9 changes: 8 additions & 1 deletion java/ql/src/semmle/code/java/dataflow/FlowSources.qll
Original file line number Diff line number Diff line change
Expand Up @@ -152,9 +152,13 @@ deprecated class RemoteUserInput extends UserInput {
RemoteUserInput() { this instanceof RemoteFlowSource }
}

/** Input that may be controlled by a local user. */
/** A node with input that may be controlled by a local user. */
abstract class LocalUserInput extends UserInput { }

/**
* A node with input from the local environment, such as files, standard in,
* environment variables, and main method parameters.
*/
class EnvInput extends LocalUserInput {
EnvInput() {
// Parameters to a main method.
Expand All @@ -180,6 +184,7 @@ class EnvInput extends LocalUserInput {
}
}

/** A node with input from a database. */
class DatabaseInput extends LocalUserInput {
DatabaseInput() { this.asExpr().(MethodAccess).getMethod() instanceof ResultSetGetStringMethod }
}
Expand Down Expand Up @@ -222,10 +227,12 @@ private class EnvTaintedMethod extends Method {
}
}

/** The type `java.net.InetAddress`. */
class TypeInetAddr extends RefType {
TypeInetAddr() { this.getQualifiedName() = "java.net.InetAddress" }
}

/** A reverse DNS method. */
class ReverseDNSMethod extends Method {
ReverseDNSMethod() {
this.getDeclaringType() instanceof TypeInetAddr and
Expand Down
4 changes: 2 additions & 2 deletions java/ql/src/semmle/code/java/dataflow/Nullness.qll
Original file line number Diff line number Diff line change
Expand Up @@ -579,7 +579,7 @@ private predicate varMaybeNullInBlock_corrCond(
* - int: A means a specific integer value and B means any other value.
*/

newtype TrackVarKind =
private newtype TrackVarKind =
TrackVarKindNull() or
TrackVarKindBool() or
TrackVarKindEnum() or
Expand Down Expand Up @@ -701,7 +701,7 @@ private predicate isReset(
}

/** The abstract value of the tracked variable. */
newtype TrackedValue =
private newtype TrackedValue =
TrackedValueA() or
TrackedValueB() or
TrackedValueUnknown()
Expand Down
7 changes: 7 additions & 0 deletions java/ql/src/semmle/code/java/dataflow/RangeAnalysis.qll
Original file line number Diff line number Diff line change
Expand Up @@ -264,14 +264,21 @@ private newtype TReason =
* without going through a bounding condition.
*/
abstract class Reason extends TReason {
/** Gets a textual representation of this reason. */
abstract string toString();
}

/**
* A reason for an inferred bound that indicates that the bound is inferred
* without going through a bounding condition.
*/
class NoReason extends Reason, TNoReason {
override string toString() { result = "NoReason" }
}

/** A reason for an inferred bound pointing to a condition. */
class CondReason extends Reason, TCondReason {
/** Gets the condition that is the reason for the bound. */
Guard getCond() { this = TCondReason(result) }

override string toString() { result = getCond().toString() }
Expand Down
1 change: 1 addition & 0 deletions java/ql/src/semmle/code/java/dataflow/RangeUtils.qll
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ class SsaReadPosition extends TSsaReadPosition {
/** Holds if `v` is read at this position. */
abstract predicate hasReadOfVar(SsaVariable v);

/** Gets a textual representation of this SSA read position. */
abstract string toString();
}

Expand Down
6 changes: 5 additions & 1 deletion java/ql/src/semmle/code/java/dataflow/SSA.qll
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ class SsaSourceVariable extends TSsaSourceVariable {
this = TQualifiedField(result, _, _)
}

/** Gets a textual representation of this `SsaSourceVariable`. */
string toString() {
exists(LocalScopeVariable v, Callable c | this = TLocalVar(c, v) |
if c = v.getCallable()
Expand All @@ -112,6 +113,7 @@ class SsaSourceVariable extends TSsaSourceVariable {
)
}

/** Gets the source location for this element. */
Location getLocation() {
exists(LocalScopeVariable v | this = TLocalVar(_, v) and result = v.getLocation())
or
Expand Down Expand Up @@ -935,8 +937,10 @@ class SsaVariable extends TSsaVariable {
this = TSsaUntracked(_, result)
}

/** Gets a textual representation of this SSA variable. */
string toString() { none() }

/** Gets the source location for this element. */
Location getLocation() { result = getCFGNode().getLocation() }

/** Gets the `BasicBlock` in which this SSA variable is defined. */
Expand Down Expand Up @@ -1113,7 +1117,7 @@ class SsaPhiNode extends SsaVariable, TSsaPhiNode {
}
}

library class RefTypeCastExpr extends CastExpr {
private class RefTypeCastExpr extends CastExpr {
RefTypeCastExpr() { this.getType() instanceof RefType }
}

Expand Down
4 changes: 2 additions & 2 deletions java/ql/src/semmle/code/java/dataflow/TypeFlow.qll
Original file line number Diff line number Diff line change
Expand Up @@ -365,12 +365,12 @@ private predicate typeFlow(TypeFlowNode n, RefType t) {
}

pragma[nomagic]
predicate erasedTypeBound(RefType t) {
private predicate erasedTypeBound(RefType t) {
exists(RefType t0 | typeFlow(_, t0) and t = t0.getErasure())
}

pragma[nomagic]
predicate typeBound(RefType t) { typeFlow(_, t) }
private predicate typeBound(RefType t) { typeFlow(_, t) }

/**
* Holds if we have a bound for `n` that is better than `t`, taking only erased
Expand Down
8 changes: 8 additions & 0 deletions java/ql/src/semmle/code/java/dispatch/DispatchFlow.qll
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
/**
* INTERNAL: This is part of the virtual dispatch computation.
*
* Provides a strengthening of the virtual dispatch relation using a dedicated
* data flow check for lambdas, anonymous classes, and other sufficiently
* private classes where all object instantiations are accounted for.
*/

import java
private import VirtualDispatch
private import semmle.code.java.dataflow.internal.BaseSSA
Expand Down
6 changes: 6 additions & 0 deletions java/ql/src/semmle/code/java/dispatch/VirtualDispatch.qll
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
/**
* Provides predicates for reasoning about runtime call targets through virtual
* dispatch.
*/

import java
import semmle.code.java.dataflow.TypeFlow
private import DispatchFlow as DispatchFlow
Expand Down Expand Up @@ -27,6 +32,7 @@ Callable exactCallable(Call c) {

private predicate implCount(MethodAccess m, int c) { strictcount(viableImpl(m)) = c }

/** Gets a viable implementation of the target of the given `Call`. */
Callable viableCallable(Call c) {
result = viableImpl(c)
or
Expand Down
5 changes: 5 additions & 0 deletions java/ql/src/semmle/code/java/dispatch/WrappedInvocation.qll
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
/**
* Provides classes and predicates for reasoning about calls that may invoke one
* of their arguments.
*/

import java
import VirtualDispatch

Expand Down
3 changes: 2 additions & 1 deletion java/ql/src/semmle/code/java/frameworks/Assertions.qll
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import java

newtype AssertKind =
private newtype AssertKind =
AssertKindTrue() or
AssertKindFalse() or
AssertKindNotNull() or
Expand Down Expand Up @@ -50,6 +50,7 @@ private predicate assertionMethod(Method m, AssertKind kind) {
)
}

/** An assertion method. */
class AssertionMethod extends Method {
AssertionMethod() { assertionMethod(this, _) }

Expand Down
Loading