Compare commits

...

10 Commits

Author SHA1 Message Date
Alex Eyers-Taylor
ea8c73428d Java: Make non-returning methods use local to global. 2025-06-12 18:39:32 +01:00
Kasper Svendsen
a80fbf09a8 Overlay annotation script shouldn't manage overlay[local] and overlay[global] 2025-05-27 08:30:14 +02:00
Kasper Svendsen
5b487266f1 Mark ActivateModels subclasses overlay[local?] 2025-05-27 08:30:14 +02:00
Kasper Svendsen
e89079ce76 Virtual dispatch must be local 2025-05-27 08:30:13 +02:00
Kasper Svendsen
b98300bc79 DataFlowImplCommon: Mark LambdaFlow as overlay global 2025-05-27 08:30:13 +02:00
Kasper Svendsen
9ada903922 Member: Allow methods with empty bodies for overlay 2025-05-27 08:30:12 +02:00
Kasper Svendsen
f8373c1f19 Define entity discard predicates for Java 2025-05-27 08:30:11 +02:00
Philip Ginsbach
6454521957 set compileForOverlayEval true for java 2025-05-27 08:30:11 +02:00
Philip Ginsbach
9712e25fec update python and csharp via config/sync-files.py 2025-05-27 08:30:10 +02:00
Philip Ginsbach
8d9281e9d1 annotate .qll files in java and shared via script 2025-05-27 08:30:10 +02:00
443 changed files with 1422 additions and 107 deletions

View File

@@ -0,0 +1,175 @@
# This script is used to annotate .qll files with overlay[local?] annotations.
# It will walk the directory tree and annotate most .qll files, skipping only
# some specific cases (e.g., empty files, files that configure dataflow for queries).
# It will also add overlay[caller] annotations to predicates that are pragma[inline]
# and either not private or in a hardcoded list of predicates.
# The script takes a list of languages and processes the corresponding directories.
# Usage: python3 annotate-overlay-local.py <language1> <language2> ...
# The script will modify the files in place and print the changes made.
# The script is designed to be run from the root of the repository.
#!/usr/bin/python3
import sys
import os
from difflib import *
# These are the only two predicates that are pragma[inline], private, and must be
# overlay[caller] in order to successfully compile our internal java queries.
hardcoded_overlay_caller_preds = [
"fwdFlowInCand", "fwdFlowInCandTypeFlowDisabled"]
def filter_out_annotations(filename):
'''
Read the file and strip all existing overlay[...] annotations from the contents.
Return the file modified file content as a list of lines.
'''
overlays = ["local?", "caller"]
annotations = [f"overlay[{t}]" for t in overlays]
with open(filename, 'r') as file_in:
lines = [l for l in file_in if not l.strip() in annotations]
for ann in annotations:
if any(line for line in lines if ann in line):
raise Exception(f"Failed to filter out {ann} from {filename}.")
return lines
def insert_toplevel_maybe_local_anntotation(filename, lines):
'''
Find a suitable place to insert an overlay[local?] annotation at the top of the file.
Return a pair: (string describing action taken, modified content as list of lines).
'''
out_lines = []
status = 0
for line in lines:
if status == 0 and line.rstrip().endswith("module;"):
out_lines.append("overlay[local?]\n")
status = 1
out_lines.append(line)
if status == 1:
return (f"Annotating \"{filename}\" via existing file-level module statement", out_lines)
out_lines = []
empty_line_buffer = []
status = 0
for line in lines:
trimmed = line.strip()
if not trimmed:
empty_line_buffer.append(line)
continue
if status <= 1 and trimmed.endswith("*/"):
status = 2
elif status == 0 and trimmed.startswith("/**"):
status = 1
elif status == 0 and not trimmed.startswith("/*"):
out_lines.append("overlay[local?]\n")
out_lines.append("module;\n")
out_lines.append("\n")
status = 3
elif status == 2 and (trimmed.startswith("import ") or trimmed.startswith("private import ")):
out_lines.append("overlay[local?]\n")
out_lines.append("module;\n")
status = 3
elif status == 2 and (trimmed.startswith("class ") or trimmed.startswith("predicate ")
or trimmed.startswith("module ") or trimmed.startswith("signature ")):
out_lines = ["overlay[local?]\n", "module;\n", "\n"] + out_lines
status = 3
elif status == 2 and trimmed.startswith("/*"):
out_lines.append("overlay[local?]\n")
out_lines.append("module;\n")
status = 3
elif status == 2:
status = 4
if empty_line_buffer:
out_lines += empty_line_buffer
empty_line_buffer = []
out_lines.append(line)
if status == 3:
out_lines += empty_line_buffer
if status == 3:
return (f"Annotating \"{filename}\" after file-level module qldoc", out_lines)
raise Exception(f"Failed to annotate \"{filename}\" as overlay[local?].")
def insert_overlay_caller_annotations(lines):
'''
Mark pragma[inline] predicates as overlay[caller] if they are not declared private
or if they are private but are in the list of hardcoded_overlay_caller_preds.
'''
out_lines = []
for i, line in enumerate(lines):
trimmed = line.strip()
if trimmed == "pragma[inline]":
if (not "private" in lines[i+1] or
any(pred in lines[i+1] for pred in hardcoded_overlay_caller_preds)):
whitespace = line[0: line.find(trimmed)]
out_lines.append(f"{whitespace}overlay[caller]\n")
out_lines.append(line)
return out_lines
def annotate_as_appropriate(filename):
'''
Read file and strip all existing overlay[...] annotations from the contents;
then insert new overlay[...] annotations according to heuristics.
Return a pair: (string describing action taken, modified content as list of lines).
'''
lines = filter_out_annotations(filename)
lines = insert_overlay_caller_annotations(lines)
# These simple heuristics filter out those .qll files that we no _not_ want to annotate
# as overlay[local?]. It is not clear that these heuristics are exactly what we want,
# but they seem to work well enough for now (as determined by speed and accuracy numbers).
if (filename.endswith("Test.qll") or
((filename.endswith("Query.qll") or filename.endswith("Config.qll")) and
any("implements DataFlow::ConfigSig" in line for line in lines))):
return (f"Keeping \"{filename}\" global because it configures dataflow for a query", lines)
elif not any(line for line in lines if line.strip()):
return (f"Keeping \"{filename}\" global because it is empty", lines)
return insert_toplevel_maybe_local_anntotation(filename, lines)
def process_single_file(filename):
'''
Process a single file, annotating it as appropriate and writing the changes back to the file.
'''
annotate_result = annotate_as_appropriate(filename)
old = [line for line in open(filename)]
new = annotate_result[1]
if old != new:
diff = context_diff(old, new, fromfile=filename, tofile=filename)
diff = [line for line in diff]
if diff:
print(annotate_result[0])
for line in diff:
print(line.rstrip())
with open(filename, "w") as out_file:
for line in new:
out_file.write(line)
dirs = []
for lang in sys.argv[1:]:
if lang in ["cpp", "go", "csharp", "java", "javascript", "python", "ruby", "rust", "swift"]:
dirs.append(f"{lang}/ql/lib")
else:
raise Exception(f"Unknown language \"{lang}\".")
if dirs:
dirs.append("shared")
for roots in dirs:
for dirpath, dirnames, filenames in os.walk(roots):
for filename in filenames:
if filename.endswith(".qll") and not dirpath.endswith("tutorial"):
process_single_file(os.path.join(dirpath, filename))

View File

@@ -1,6 +1,8 @@
/**
* Provides classes for representing abstract bounds for use in, for example, range analysis.
*/
overlay[local?]
module;
private import internal.rangeanalysis.BoundSpecific

View File

@@ -3,6 +3,8 @@
* an expression, `b` is a `Bound` (typically zero or the value of an SSA
* variable), and `v` is an integer in the range `[0 .. m-1]`.
*/
overlay[local?]
module;
private import internal.rangeanalysis.ModulusAnalysisSpecific::Private
private import Bound

View File

@@ -1,3 +1,6 @@
overlay[local?]
module;
newtype TSign =
TNeg() or
TZero() or

View File

@@ -5,6 +5,8 @@
* The analysis is implemented as an abstract interpretation over the
* three-valued domain `{negative, zero, positive}`.
*/
overlay[local?]
module;
private import SignAnalysisSpecific::Private
private import SsaReadPositionCommon

View File

@@ -1,6 +1,8 @@
/**
* Provides classes for representing a position at which an SSA variable is read.
*/
overlay[local?]
module;
private import SsaReadPositionSpecific
import SsaReadPositionSpecific::Public

View File

@@ -8,5 +8,7 @@
* the `RemoteFlowSource` and `AdditionalTaintStep` classes associated with the security queries
* to model frameworks that are not covered by the standard library.
*/
overlay[local?]
module;
import java

View File

@@ -1,6 +1,8 @@
/**
* Provides shared predicates related to contextual queries in the code viewer.
*/
overlay[local?]
module;
import semmle.files.FileSystem
private import codeql.util.FileSystem

View File

@@ -1,3 +1,5 @@
/** DEPRECATED: use `java.qll` instead. */
overlay[local?]
module;
import java

View File

@@ -2,6 +2,8 @@
* Provides classes and predicates related to jump-to-definition links
* in the code viewer.
*/
overlay[local?]
module;
import java
import IDEContextual

View File

@@ -1,3 +1,6 @@
overlay[local?]
module;
import java
import semmle.code.java.dataflow.DataFlow
import semmle.code.java.dataflow.TaintTracking

View File

@@ -1,3 +1,6 @@
overlay[local?]
module;
private import java as Language
private import semmle.code.java.security.InsecureRandomnessQuery
private import semmle.code.java.security.RandomQuery

View File

@@ -1,3 +1,6 @@
overlay[local?]
module;
import java
class ExternalData extends @externalDataElement {

View File

@@ -1,4 +1,6 @@
/** Provides all default Java QL imports. */
overlay[local?]
module;
import Customizations
import semmle.code.FileSystem
@@ -24,6 +26,7 @@ import semmle.code.java.KotlinType
import semmle.code.java.Member
import semmle.code.java.Modifier
import semmle.code.java.Modules
import semmle.code.java.Overlay
import semmle.code.java.Package
import semmle.code.java.Statement
import semmle.code.java.Type

View File

@@ -1,4 +1,6 @@
/** Provides classes for working with files and folders. */
overlay[local?]
module;
import Location
private import codeql.util.FileSystem

View File

@@ -3,6 +3,8 @@
*
* Locations represent parts of files and are used to map elements to their source location.
*/
overlay[local?]
module;
import FileSystem
import semmle.code.java.Element
@@ -219,3 +221,17 @@ private predicate fixedHasLocation(Top l, Location loc, File f) {
not hasSourceLocation(l, _, _) and
locations_default(loc, f, _, _, _, _)
}
overlay[local]
pragma[nomagic]
predicate discardableLocation(string file, @location l) {
not hasOverlay() and
file = getRawFileForLoc(l) and
not exists(@file f | hasLocation(f, l))
}
overlay[discard_entity]
pragma[nomagic]
predicate discardLocation(@location l) {
exists(string file | discardableLocation(file, l) and discardFile(file))
}

View File

@@ -1,6 +1,8 @@
/**
* Provides classes and predicates for working with SMAP files (see JSR-045).
*/
overlay[local?]
module;
import java

View File

@@ -1,3 +1,5 @@
/** Provides the `Unit` class. */
overlay[local?]
module;
import codeql.util.Unit

View File

@@ -2,6 +2,8 @@
* Provides classes and predicates for working with configuration files, such
* as Java `.properties` or `.ini` files.
*/
overlay[local?]
module;
import semmle.code.Location

View File

@@ -8,6 +8,8 @@
* Each annotation type has zero or more annotation elements that contain a
* name and possibly a value.
*/
overlay[local?]
module;
import Element
import Expr

View File

@@ -2,6 +2,8 @@
* Provides classes and predicates for reasoning about instances of
* `java.util.Collection` and their methods.
*/
overlay[local?]
module;
import java

View File

@@ -1,6 +1,8 @@
/**
* Provides a class representing individual compiler invocations that occurred during the build.
*/
overlay[local?]
module;
import semmle.code.FileSystem

View File

@@ -1,6 +1,8 @@
/**
* Provides classes and predicates for working with Java compilation units.
*/
overlay[local?]
module;
import Element
import Package

View File

@@ -1,6 +1,8 @@
/**
* Provides classes and predicates for representing completions.
*/
overlay[local?]
module;
/*
* A completion represents how a statement or expression terminates.

View File

@@ -1,3 +1,6 @@
overlay[local?]
module;
import java
/**

View File

@@ -1,6 +1,8 @@
/**
* Provdides a module to calculate constant integer and boolean values.
*/
overlay[local?]
module;
import java

View File

@@ -7,6 +7,8 @@
* statement, an expression, or an exit node for a callable, indicating that
* execution of the callable terminates.
*/
overlay[local?]
module;
/*
* The implementation is centered around the concept of a _completion_, which
@@ -429,115 +431,132 @@ private module ControlFlowGraphImpl {
}
/**
* A virtual method with a unique implementation. That is, the method does not
* participate in overriding and there are no call targets that could dispatch
* to both this and another method.
* Module containing a global non-returning method analysis. The result is injected back into
* a local predicate `nonReturningMethodCall()`, which is used in further local predicates
* within this file.
*/
private class EffectivelyNonVirtualMethod extends SrcMethod {
EffectivelyNonVirtualMethod() {
exists(this.getBody()) and
this.isVirtual() and
not this = any(Method m).getASourceOverriddenMethod() and
not this.overrides(_) and
// guard against implicit overrides of default methods
not this.getAPossibleImplementationOfSrcMethod() != this and
// guard against interface implementations in inheriting subclasses
not exists(SrcMethod m |
1 < strictcount(m.getAPossibleImplementationOfSrcMethod()) and
this = m.getAPossibleImplementationOfSrcMethod()
) and
// UnsupportedOperationException could indicate that this is meant to be overridden
not exists(ClassInstanceExpr ex |
this.getBody().getLastStmt().(ThrowStmt).getExpr() = ex and
ex.getConstructedType().hasQualifiedName("java.lang", "UnsupportedOperationException")
) and
// an unused parameter could indicate that this is meant to be overridden
forall(Parameter p | p = this.getAParameter() | exists(p.getAnAccess()))
overlay[global]
private module NonReturningAnalysis {
/**
* A virtual method with a unique implementation. That is, the method does not
* participate in overriding and there are no call targets that could dispatch
* to both this and another method.
*/
private class EffectivelyNonVirtualMethod extends SrcMethod {
EffectivelyNonVirtualMethod() {
exists(this.getBody()) and
this.isVirtual() and
not this = any(Method m).getASourceOverriddenMethod() and
not this.overrides(_) and
// guard against implicit overrides of default methods
not this.getAPossibleImplementationOfSrcMethod() != this and
// guard against interface implementations in inheriting subclasses
not exists(SrcMethod m |
1 < strictcount(m.getAPossibleImplementationOfSrcMethod()) and
this = m.getAPossibleImplementationOfSrcMethod()
) and
// UnsupportedOperationException could indicate that this is meant to be overridden
not exists(ClassInstanceExpr ex |
this.getBody().getLastStmt().(ThrowStmt).getExpr() = ex and
ex.getConstructedType().hasQualifiedName("java.lang", "UnsupportedOperationException")
) and
// an unused parameter could indicate that this is meant to be overridden
forall(Parameter p | p = this.getAParameter() | exists(p.getAnAccess()))
}
/** Gets a `MethodCall` that calls this method. */
MethodCall getAnAccess() { result.getMethod().getAPossibleImplementation() = this }
}
/** Gets a `MethodCall` that calls this method. */
MethodCall getAnAccess() { result.getMethod().getAPossibleImplementation() = this }
}
/** Holds if a call to `m` indicates that `m` is expected to return. */
private predicate expectedReturn(EffectivelyNonVirtualMethod m) {
exists(Stmt s, BlockStmt b |
m.getAnAccess().getEnclosingStmt() = s and
b.getAStmt() = s and
not b.getLastStmt() = s
)
}
/**
* Gets a non-overridable method that always throws an exception or calls `exit`.
*/
private Method nonReturningMethod() {
result instanceof MethodExit
or
not result.isOverridable() and
exists(BlockStmt body |
body = result.getBody() and
not exists(ReturnStmt ret | ret.getEnclosingCallable() = result)
|
not result.getReturnType() instanceof VoidType or
body.getLastStmt() = nonReturningStmt()
)
}
/**
* Gets a virtual method that always throws an exception or calls `exit`.
*/
private EffectivelyNonVirtualMethod likelyNonReturningMethod() {
result.getReturnType() instanceof VoidType and
not exists(ReturnStmt ret | ret.getEnclosingCallable() = result) and
not expectedReturn(result) and
forall(Parameter p | p = result.getAParameter() | exists(p.getAnAccess())) and
result.getBody().getLastStmt() = nonReturningStmt()
}
/**
* Gets a `MethodCall` that always throws an exception or calls `exit`.
*/
private MethodCall nonReturningMethodCall() {
result.getMethod().getSourceDeclaration() = nonReturningMethod() or
result = likelyNonReturningMethod().getAnAccess()
}
/**
* Gets a statement that always throws an exception or calls `exit`.
*/
private Stmt nonReturningStmt() {
result instanceof ThrowStmt
or
result.(ExprStmt).getExpr() = nonReturningExpr()
or
result.(BlockStmt).getLastStmt() = nonReturningStmt()
or
exists(IfStmt ifstmt | ifstmt = result |
ifstmt.getThen() = nonReturningStmt() and
ifstmt.getElse() = nonReturningStmt()
)
or
exists(TryStmt try | try = result |
try.getBlock() = nonReturningStmt() and
forall(CatchClause cc | cc = try.getACatchClause() | cc.getBlock() = nonReturningStmt())
)
}
/**
* Gets an expression that always throws an exception or calls `exit`.
*/
private Expr nonReturningExpr() {
result = nonReturningMethodCall()
or
result.(StmtExpr).getStmt() = nonReturningStmt()
or
exists(WhenExpr whenexpr | whenexpr = result |
whenexpr.getBranch(_).isElseBranch() and
forex(WhenBranch whenbranch | whenbranch = whenexpr.getBranch(_) |
whenbranch.getRhs() = nonReturningStmt()
/** Holds if a call to `m` indicates that `m` is expected to return. */
private predicate expectedReturn(EffectivelyNonVirtualMethod m) {
exists(Stmt s, BlockStmt b |
m.getAnAccess().getEnclosingStmt() = s and
b.getAStmt() = s and
not b.getLastStmt() = s
)
)
}
/**
* Gets a non-overridable method that always throws an exception or calls `exit`.
*/
private Method nonReturningMethod() {
result instanceof MethodExit
or
not result.isOverridable() and
exists(BlockStmt body |
body = result.getBody() and
not exists(ReturnStmt ret | ret.getEnclosingCallable() = result)
|
not result.getReturnType() instanceof VoidType or
body.getLastStmt() = nonReturningStmt()
)
}
/**
* Gets a virtual method that always throws an exception or calls `exit`.
*/
private EffectivelyNonVirtualMethod likelyNonReturningMethod() {
result.getReturnType() instanceof VoidType and
not exists(ReturnStmt ret | ret.getEnclosingCallable() = result) and
not expectedReturn(result) and
forall(Parameter p | p = result.getAParameter() | exists(p.getAnAccess())) and
result.getBody().getLastStmt() = nonReturningStmt()
}
/**
* Gets a `MethodCall` that always throws an exception or calls `exit`.
*/
private MethodCall nonReturningMethodCallGlobal() {
result.getMethod().getSourceDeclaration() = nonReturningMethod() or
result = likelyNonReturningMethod().getAnAccess()
}
/**
* Gets a `MethodCall` that always throws an exception or calls `exit`.
*
* This predicate is local so gives the local anaylyis for base and the global
* analyis for overlay cases.
*/
overlay[local]
MethodCall nonReturningMethodCall() = localToGlobal(nonReturningMethodCallGlobal/0)(result)
/**
* Gets a statement that always throws an exception or calls `exit`.
*/
private Stmt nonReturningStmt() {
result instanceof ThrowStmt
or
result.(ExprStmt).getExpr() = nonReturningExpr()
or
result.(BlockStmt).getLastStmt() = nonReturningStmt()
or
exists(IfStmt ifstmt | ifstmt = result |
ifstmt.getThen() = nonReturningStmt() and
ifstmt.getElse() = nonReturningStmt()
)
or
exists(TryStmt try | try = result |
try.getBlock() = nonReturningStmt() and
forall(CatchClause cc | cc = try.getACatchClause() | cc.getBlock() = nonReturningStmt())
)
}
/**
* Gets an expression that always throws an exception or calls `exit`.
*/
private Expr nonReturningExpr() {
result = nonReturningMethodCallGlobal()
or
result.(StmtExpr).getStmt() = nonReturningStmt()
or
exists(WhenExpr whenexpr | whenexpr = result |
whenexpr.getBranch(_).isElseBranch() and
forex(WhenBranch whenbranch | whenbranch = whenexpr.getBranch(_) |
whenbranch.getRhs() = nonReturningStmt()
)
)
}
}
// Join order engineering -- first determine the switch block and the case indices required, then retrieve them.
@@ -764,7 +783,7 @@ private module ControlFlowGraphImpl {
not this instanceof BooleanLiteral and
not this instanceof ReturnStmt and
not this instanceof ThrowStmt and
not this = nonReturningMethodCall()
not this = NonReturningAnalysis::nonReturningMethodCall()
}
}

View File

@@ -4,6 +4,8 @@
*
* See the Java Language Specification, Section 5, for details.
*/
overlay[local?]
module;
import java
import semmle.code.java.arithmetic.Overflow

View File

@@ -1,6 +1,8 @@
/**
* Provides utility predicates for representing dependencies between types.
*/
overlay[local?]
module;
import Type
import Generics

View File

@@ -1,6 +1,8 @@
/**
* This library provides utility predicates for representing the number of dependencies between types.
*/
overlay[local?]
module;
import Type
import Generics

View File

@@ -1,6 +1,8 @@
/**
* Provides classes representing warnings generated during compilation.
*/
overlay[local?]
module;
import java

View File

@@ -1,6 +1,8 @@
/**
* Provides a class that represents named elements in Java programs.
*/
overlay[local?]
module;
import CompilationUnit
import semmle.code.Location

View File

@@ -1,6 +1,8 @@
/**
* Provides classes and predicates for working with Java exceptions.
*/
overlay[local?]
module;
import Element
import Type

View File

@@ -1,6 +1,8 @@
/**
* Provides classes for working with Java expressions.
*/
overlay[local?]
module;
import java
private import semmle.code.java.frameworks.android.Compose
@@ -2699,3 +2701,16 @@ class RecordPatternExpr extends Expr, @recordpatternexpr {
)
}
}
overlay[local]
pragma[nomagic]
predicate discardableExpr(string file, @expr e) {
not hasOverlay() and
file = getRawFile(e)
}
overlay[discard_entity]
pragma[nomagic]
predicate discardExpr(@expr e) {
exists(string file | discardableExpr(file, e) and discardFile(file))
}

View File

@@ -1,6 +1,8 @@
/**
* Provides classes and predicates for working with the most common types of generated files.
*/
overlay[local?]
module;
import Type
private import semmle.code.java.frameworks.JavaxAnnotations

View File

@@ -30,6 +30,8 @@
*
* The terminology for generic methods is analogous.
*/
overlay[local?]
module;
import Type

View File

@@ -1,6 +1,8 @@
/**
* Provides classes and predicates for working with Java imports.
*/
overlay[local?]
module;
import semmle.code.Location
import CompilationUnit

View File

@@ -1,6 +1,8 @@
/**
* Provides classes and predicates for working with J2EE bean types.
*/
overlay[local?]
module;
import Type

View File

@@ -1,6 +1,8 @@
/**
* Provides classes and predicates for working with standard classes and methods from the JDK.
*/
overlay[local?]
module;
import Member
import semmle.code.java.security.ExternalProcess

View File

@@ -1,6 +1,8 @@
/**
* Provides classes that represent standard annotations from the JDK.
*/
overlay[local?]
module;
import java

View File

@@ -1,6 +1,8 @@
/**
* Provides classes and predicates for working with JMX bean types.
*/
overlay[local?]
module;
import Type

View File

@@ -1,6 +1,8 @@
/**
* Provides classes and predicates for working with Javadoc documentation.
*/
overlay[local?]
module;
import semmle.code.Location
@@ -194,3 +196,16 @@ class KtCommentSection extends @ktcommentsection {
/** Gets the string representation of this section. */
string toString() { result = this.getContent() }
}
overlay[local]
pragma[nomagic]
predicate discardableJavadoc(string file, @javadoc d) {
not hasOverlay() and
exists(@member m | file = getRawFile(m) and hasJavadoc(m, d))
}
overlay[discard_entity]
pragma[nomagic]
predicate discardJavadoc(@javadoc d) {
exists(string file | discardableJavadoc(file, d) and discardFile(file))
}

View File

@@ -1,6 +1,8 @@
/**
* Provides classes and predicates for working with Kotlin types.
*/
overlay[local?]
module;
import java

View File

@@ -2,6 +2,8 @@
* Provides classes and predicates for reasoning about instances of
* `java.util.Map` and their methods.
*/
overlay[local?]
module;
import java
import Collections

View File

@@ -2,6 +2,8 @@
* Provides classes and predicates for working with members of Java classes and interfaces,
* that is, methods, constructors, fields and nested types.
*/
overlay[local?]
module;
import Element
import Type
@@ -621,7 +623,11 @@ class SrcMethod extends Method {
then implementsInterfaceMethod(result, this)
else result.getASourceOverriddenMethod*() = this
) and
(exists(result.getBody()) or result.hasModifier("native"))
(
hasOverlay() or
exists(result.getBody()) or
result.hasModifier("native")
)
}
}
@@ -895,3 +901,36 @@ class ExtensionMethod extends Method {
else result = 0
}
}
overlay[local]
pragma[nomagic]
predicate discardableMethod(string file, @method m) {
not hasOverlay() and
file = getRawFile(m) and
exists(@classorinterface c | methods(m, _, _, _, c, _) and isAnonymClass(c, _))
}
overlay[discard_entity]
pragma[nomagic]
predicate discardAnonMethod(@method m) {
exists(string file | discardableMethod(file, m) and discardFile(file))
}
overlay[local]
pragma[nomagic]
predicate discardableBaseMethod(string file, @method m) {
not hasOverlay() and
file = getRawFile(m)
}
overlay[local]
pragma[nomagic]
predicate usedOverlayMethod(@method m) { hasOverlay() and methods(m, _, _, _, _, _) }
overlay[discard_entity]
pragma[nomagic]
predicate discardMethod(@method m) {
exists(string file |
discardableBaseMethod(file, m) and discardFile(file) and not usedOverlayMethod(m)
)
}

View File

@@ -1,6 +1,8 @@
/**
* Provides classes and predicates for working with Java modifiers.
*/
overlay[local?]
module;
import Element

View File

@@ -1,6 +1,8 @@
/**
* Provides classes for working with Java modules.
*/
overlay[local?]
module;
import CompilationUnit

View File

@@ -1,4 +1,6 @@
/** Provides classes and predicates for reasoning about `java.lang.NumberFormatException`. */
overlay[local?]
module;
import java

View File

@@ -0,0 +1,29 @@
overlay[local?]
module;
import java
overlay[local]
pragma[nomagic]
predicate hasOverlay() { databaseMetadata("isOverlay", "true") }
overlay[local]
string getRawFile(@locatable el) {
exists(@location loc, @file file |
hasLocation(el, loc) and
locations_default(loc, file, _, _, _, _) and
files(file, result)
)
}
overlay[local]
string getRawFileForLoc(@location l) {
exists(@file f | locations_default(l, f, _, _, _, _) and files(f, result))
}
overlay[local]
pragma[nomagic]
predicate discardFile(string file) {
hasOverlay() and
exists(@expr e | callableEnclosingExpr(e, _) and file = getRawFile(e))
}

View File

@@ -1,6 +1,8 @@
/**
* Provides classes and predicates for working with Java packages.
*/
overlay[local?]
module;
import Element
import Type

View File

@@ -2,6 +2,8 @@
* Provides pretty-printed representations of the AST, in particular top-level
* classes and interfaces.
*/
overlay[local?]
module;
import java

View File

@@ -5,6 +5,8 @@
* extend `PrintAstConfiguration` and override `shouldPrint` to hold for only the elements
* you wish to view the AST for.
*/
overlay[local?]
module;
import java
import semmle.code.java.regex.RegexTreeView as RegexTreeView

View File

@@ -1,6 +1,8 @@
/**
* Provides classes and predicates for working with Java Reflection.
*/
overlay[local?]
module;
import java
import JDKAnnotations

View File

@@ -1,6 +1,8 @@
/**
* Provides classes and predicates for working with Java Serialization.
*/
overlay[local?]
module;
import java
private import frameworks.jackson.JacksonSerializability

View File

@@ -1,6 +1,8 @@
/**
* Provides classes and predicates for working with Java statements.
*/
overlay[local?]
module;
import Expr
import metrics.MetricStmt
@@ -985,3 +987,16 @@ class SuperConstructorInvocationStmt extends Stmt, ConstructorCall, @superconstr
override string getAPrimaryQlClass() { result = "SuperConstructorInvocationStmt" }
}
overlay[local]
pragma[nomagic]
predicate discardableStmt(string file, @stmt s) {
not hasOverlay() and
file = getRawFile(s)
}
overlay[discard_entity]
pragma[nomagic]
predicate discardStmt(@stmt s) {
exists(string file | discardableStmt(file, s) and discardFile(file))
}

View File

@@ -1,6 +1,8 @@
/**
* Provides classes and predicates for reasoning about string formatting.
*/
overlay[local?]
module;
import java
import dataflow.DefUse

View File

@@ -9,6 +9,8 @@
* Classes and interfaces can also be local (`LocalClassOrInterface`, `LocalClass`) or anonymous (`AnonymousClass`).
* Enumerated types (`EnumType`) and records (`Record`) are special kinds of classes.
*/
overlay[local?]
module;
import Member
import Modifier
@@ -668,6 +670,7 @@ class RefType extends Type, Annotatable, Modifiable, @reftype {
*
* For the definition of the notion of *erasure* see JLS v8, section 4.6 (Type Erasure).
*/
overlay[caller]
pragma[inline]
RefType commonSubtype(RefType other) {
result.getASourceSupertype*() = erase(this) and
@@ -1257,6 +1260,7 @@ private Type erase(Type t) {
*
* For the definition of the notion of *erasure* see JLS v8, section 4.6 (Type Erasure).
*/
overlay[caller]
pragma[inline]
predicate haveIntersection(RefType t1, RefType t2) {
exists(RefType e1, RefType e2 | e1 = erase(t1) and e2 = erase(t2) |

View File

@@ -1,6 +1,8 @@
/**
* Provides classes and predicates for working with test classes and methods.
*/
overlay[local?]
module;
import Type
import Member

View File

@@ -1,6 +1,8 @@
/**
* Provides classes and predicates for working with Java variables and their declarations.
*/
overlay[local?]
module;
import Element
@@ -131,3 +133,16 @@ class Parameter extends Element, @param, LocalScopeVariable {
/** Holds if this is an anonymous parameter, `_` */
predicate isAnonymous() { this.getName() = "" }
}
overlay[local]
pragma[nomagic]
predicate discardableLocalVarDecl(string file, @localscopevariable l) {
not hasOverlay() and
file = getRawFile(l)
}
overlay[discard_entity]
pragma[nomagic]
predicate discardLocalVarDecl(@localscopevariable l) {
exists(string file | discardableLocalVarDecl(file, l) and discardFile(file))
}

View File

@@ -1,3 +1,6 @@
overlay[local?]
module;
import java
/** A subclass of `PrimitiveType` with width-based ordering methods. */

View File

@@ -1,3 +1,6 @@
overlay[local?]
module;
import java
/**

View File

@@ -1,6 +1,8 @@
/**
* Provides classes and predicates for working with basic blocks in Java.
*/
overlay[local?]
module;
import java
import Dominance

View File

@@ -1,6 +1,8 @@
/**
* Provides classes and predicates for control-flow graph dominance.
*/
overlay[local?]
module;
import java
@@ -93,6 +95,7 @@ predicate iDominates(ControlFlowNode dominator, ControlFlowNode node) {
}
/** Holds if `dom` strictly dominates `node`. */
overlay[caller]
pragma[inline]
predicate strictlyDominates(ControlFlowNode dom, ControlFlowNode node) {
// This predicate is gigantic, so it must be inlined.
@@ -102,6 +105,7 @@ predicate strictlyDominates(ControlFlowNode dom, ControlFlowNode node) {
}
/** Holds if `dom` dominates `node`. (This is reflexive.) */
overlay[caller]
pragma[inline]
predicate dominates(ControlFlowNode dom, ControlFlowNode node) {
// This predicate is gigantic, so it must be inlined.
@@ -111,6 +115,7 @@ predicate dominates(ControlFlowNode dom, ControlFlowNode node) {
}
/** Holds if `dom` strictly post-dominates `node`. */
overlay[caller]
pragma[inline]
predicate strictlyPostDominates(ControlFlowNode dom, ControlFlowNode node) {
// This predicate is gigantic, so it must be inlined.
@@ -120,6 +125,7 @@ predicate strictlyPostDominates(ControlFlowNode dom, ControlFlowNode node) {
}
/** Holds if `dom` post-dominates `node`. (This is reflexive.) */
overlay[caller]
pragma[inline]
predicate postDominates(ControlFlowNode dom, ControlFlowNode node) {
// This predicate is gigantic, so it must be inlined.

View File

@@ -2,6 +2,8 @@
* Provides classes and predicates for reasoning about guards and the control
* flow elements controlled by those guards.
*/
overlay[local?]
module;
import java
private import semmle.code.java.controlflow.Dominance

View File

@@ -2,6 +2,8 @@
* This library provides predicates for reasoning about the set of all paths
* through a callable.
*/
overlay[local?]
module;
import java
import semmle.code.java.dispatch.VirtualDispatch

View File

@@ -1,6 +1,8 @@
/**
* Provides different types of control flow successor types.
*/
overlay[local?]
module;
import java
private import codeql.util.Boolean

View File

@@ -1,6 +1,8 @@
/**
* Provides classes and predicates for identifying unreachable blocks under a "closed-world" assumption.
*/
overlay[local?]
module;
import java
import semmle.code.java.controlflow.Guards

View File

@@ -2,6 +2,8 @@
* Provides predicates for working with the internal logic of the `Guards`
* library.
*/
overlay[local?]
module;
import java
import semmle.code.java.controlflow.Guards

View File

@@ -3,6 +3,8 @@
* `com.google.common.base.Preconditions` and
* `org.apache.commons.lang3.Validate`.
*/
overlay[local?]
module;
import java

View File

@@ -1,4 +1,6 @@
/** Provides utility predicates relating to switch cases. */
overlay[local?]
module;
import java

View File

@@ -1,3 +1,6 @@
overlay[local?]
module;
import java
import semmle.code.java.controlflow.UnreachableBlocks

View File

@@ -1,4 +1,6 @@
/** Provides classes representing various flow sinks for data flow / taint tracking. */
overlay[local?]
module;
private import semmle.code.java.dataflow.FlowSinks as FlowSinks

View File

@@ -1,4 +1,6 @@
/** Provides classes representing various flow sources for data flow / taint tracking. */
overlay[local?]
module;
private import semmle.code.java.dataflow.FlowSources as FlowSources

View File

@@ -1,6 +1,8 @@
/**
* Provides classes for representing abstract bounds for use in, for example, range analysis.
*/
overlay[local?]
module;
private import internal.rangeanalysis.BoundSpecific

View File

@@ -2,6 +2,8 @@
* Provides classes for performing local (intra-procedural) and
* global (inter-procedural) data flow analyses.
*/
overlay[local?]
module;
import java

View File

@@ -2,6 +2,8 @@
* Provides classes and predicates for def-use and use-use pairs. Built on top of the SSA library for
* maximal precision.
*/
overlay[local?]
module;
import java
private import SSA

View File

@@ -86,6 +86,8 @@
* This information is used in a heuristic for dataflow analysis to determine, if a
* model or source code should be used for determining flow.
*/
overlay[local?]
module;
import java
private import semmle.code.java.dataflow.DataFlow::DataFlow

View File

@@ -1,4 +1,6 @@
/** Provides classes representing various flow sinks for data flow / taint tracking. */
overlay[local?]
module;
private import java
private import semmle.code.java.dataflow.ExternalFlow

View File

@@ -1,6 +1,8 @@
/**
* Provides classes representing various flow sources for taint tracking.
*/
overlay[local?]
module;
import java
import semmle.code.java.dataflow.DataFlow

View File

@@ -1,6 +1,8 @@
/**
* Provides classes representing various flow steps for taint tracking.
*/
overlay[local?]
module;
private import java
private import semmle.code.java.dataflow.DataFlow

View File

@@ -1,6 +1,8 @@
/**
* Provides classes and predicates for defining flow summaries.
*/
overlay[local?]
module;
import java
private import internal.FlowSummaryImpl as Impl

View File

@@ -2,6 +2,8 @@
* Provides classes and predicates for reasoning about explicit and implicit
* instance accesses.
*/
overlay[local?]
module;
import java

View File

@@ -1,6 +1,8 @@
/**
* Provides classes and predicates for integer guards.
*/
overlay[local?]
module;
import java
private import SSA

View File

@@ -3,6 +3,8 @@
* an expression, `b` is a `Bound` (typically zero or the value of an SSA
* variable), and `v` is an integer in the range `[0 .. m-1]`.
*/
overlay[local?]
module;
private import internal.rangeanalysis.ModulusAnalysisSpecific::Private
private import Bound

View File

@@ -1,6 +1,8 @@
/**
* Provides classes and predicates for null guards.
*/
overlay[local?]
module;
import java
import SSA

View File

@@ -6,6 +6,8 @@
* hold, so results guarded by, for example, `assert x != null;` or
* `if (x == null) { assert false; }` are excluded.
*/
overlay[local?]
module;
/*
* Implementation details:

View File

@@ -8,6 +8,8 @@
* If an inferred bound relies directly on a condition, then this condition is
* reported as the reason for the bound.
*/
overlay[local?]
module;
/*
* This library tackles range analysis as a flow problem. Consider e.g.:

View File

@@ -1,6 +1,8 @@
/**
* Provides utility predicates for range analysis.
*/
overlay[local?]
module;
import java
private import SSA

View File

@@ -10,6 +10,8 @@
* of the field in case the field is not amenable to a non-trivial SSA
* representation.
*/
overlay[local?]
module;
import java
private import internal.SsaImpl

View File

@@ -5,5 +5,7 @@
* The analysis is implemented as an abstract interpretation over the
* three-valued domain `{negative, zero, positive}`.
*/
overlay[local?]
module;
import semmle.code.java.dataflow.internal.rangeanalysis.SignAnalysisCommon

View File

@@ -25,6 +25,8 @@
* String.format("%sfoo:%s", notSuffix, suffix4);
* ```
*/
overlay[local?]
module;
import java
private import semmle.code.java.dataflow.TaintTracking

View File

@@ -2,6 +2,8 @@
* Provides classes for performing local (intra-procedural) and
* global (inter-procedural) taint-tracking analyses.
*/
overlay[local?]
module;
import semmle.code.java.dataflow.DataFlow
import semmle.code.java.dataflow.internal.TaintTrackingUtil::StringBuilderVarModule

View File

@@ -7,6 +7,8 @@
* type has a subtype or if an inferred upper bound passed through at least one
* explicit or implicit cast that lost type information.
*/
overlay[local?]
module;
import java as J
private import semmle.code.java.dispatch.VirtualDispatch

View File

@@ -10,6 +10,8 @@
* This is a restricted version of SSA.qll that only handles `LocalScopeVariable`s
* in order to not depend on virtual dispatch.
*/
overlay[local?]
module;
import java
private import codeql.ssa.Ssa as SsaImplCommon

View File

@@ -1,3 +1,6 @@
overlay[local?]
module;
import java
import semmle.code.java.Collections
import semmle.code.java.Maps

View File

@@ -1,3 +1,6 @@
overlay[local?]
module;
private import java
private import DataFlowImplSpecific
private import codeql.dataflow.internal.ContentDataFlowImpl

View File

@@ -1,3 +1,6 @@
overlay[local?]
module;
private import java
private import DataFlowPrivate
private import DataFlowUtil
@@ -210,6 +213,7 @@ private module DispatchImpl {
}
/** Holds if arguments at position `apos` match parameters at position `ppos`. */
overlay[caller]
pragma[inline]
predicate parameterMatch(ParameterPosition ppos, ArgumentPosition apos) { ppos = apos }
}

View File

@@ -1,3 +1,6 @@
overlay[local?]
module;
private import DataFlowImplSpecific
private import codeql.dataflow.internal.DataFlowImpl
private import semmle.code.Location

View File

@@ -1,3 +1,6 @@
overlay[local?]
module;
private import DataFlowImplSpecific
private import semmle.code.Location
private import codeql.dataflow.internal.DataFlowImplCommon

View File

@@ -2,6 +2,8 @@
* Provides consistency queries for checking invariants in the language-specific
* data-flow classes and predicates.
*/
overlay[local?]
module;
private import java
private import DataFlowImplSpecific

Some files were not shown because too many files have changed in this diff Show More