Merge pull request #3349 from aschackmull/java/qldoc1

Java: Improve qldoc coverage.
This commit is contained in:
yo-h
2020-04-27 12:49:23 -04:00
committed by GitHub
21 changed files with 100 additions and 9 deletions

View File

@@ -1,3 +1,8 @@
/**
* Provides classes and predicates for reasoning about instances of
* `java.util.Collection` and their methods.
*/
import java
/**
@@ -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 }
}

View File

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

View File

@@ -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 }
}

View File

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

View File

@@ -1,3 +1,8 @@
/**
* Provides classes and predicates for reasoning about instances of
* `java.util.Map` and their methods.
*/
import java
import Collections
@@ -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 }
}
@@ -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) }
}

View File

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

View File

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

View File

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

View File

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

View File

@@ -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
@@ -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`. */
@@ -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
}

View File

@@ -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.
@@ -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 }
}
@@ -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

View File

@@ -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
@@ -701,7 +701,7 @@ private predicate isReset(
}
/** The abstract value of the tracked variable. */
newtype TrackedValue =
private newtype TrackedValue =
TrackedValueA() or
TrackedValueB() or
TrackedValueUnknown()

View File

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

View File

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

View File

@@ -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()
@@ -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
@@ -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. */
@@ -1113,7 +1117,7 @@ class SsaPhiNode extends SsaVariable, TSsaPhiNode {
}
}
library class RefTypeCastExpr extends CastExpr {
private class RefTypeCastExpr extends CastExpr {
RefTypeCastExpr() { this.getType() instanceof RefType }
}

View File

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

View File

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

View File

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

View File

@@ -1,3 +1,8 @@
/**
* Provides classes and predicates for reasoning about calls that may invoke one
* of their arguments.
*/
import java
import VirtualDispatch

View File

@@ -7,7 +7,7 @@
import java
newtype AssertKind =
private newtype AssertKind =
AssertKindTrue() or
AssertKindFalse() or
AssertKindNotNull() or
@@ -50,6 +50,7 @@ private predicate assertionMethod(Method m, AssertKind kind) {
)
}
/** An assertion method. */
class AssertionMethod extends Method {
AssertionMethod() { assertionMethod(this, _) }

View File

@@ -1,21 +1,25 @@
/*
/**
* Definitions related to `java.net.*`.
*/
import semmle.code.java.Type
/** The type `java.net.URLConnection`. */
class TypeUrlConnection extends RefType {
TypeUrlConnection() { hasQualifiedName("java.net", "URLConnection") }
}
/** The type `java.net.Socket`. */
class TypeSocket extends RefType {
TypeSocket() { hasQualifiedName("java.net", "Socket") }
}
/** The type `java.net.URL`. */
class TypeUrl extends RefType {
TypeUrl() { hasQualifiedName("java.net", "URL") }
}
/** The method `java.net.URLConnection::getInputStream`. */
class URLConnectionGetInputStreamMethod extends Method {
URLConnectionGetInputStreamMethod() {
getDeclaringType() instanceof TypeUrlConnection and
@@ -24,6 +28,7 @@ class URLConnectionGetInputStreamMethod extends Method {
}
}
/** The method `java.net.Socket::getInputStream`. */
class SocketGetInputStreamMethod extends Method {
SocketGetInputStreamMethod() {
getDeclaringType() instanceof TypeSocket and