Skip to content

EXPERIMENT: Test overlay fixes #19937

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 6 commits into
base: main
Choose a base branch
from
Draft
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
1 change: 1 addition & 0 deletions java/ql/lib/qlpack.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,4 @@ dataExtensions:
- ext/generated/*.model.yml
- ext/experimental/*.model.yml
warnOnImplicitThis: true
compileForOverlayEval: true
9 changes: 9 additions & 0 deletions java/ql/lib/semmle/code/java/Type.qll
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,15 @@ class RefType extends Type, Annotatable, Modifiable, @reftype {
*/
RefType getAStrictAncestor() { result = this.getASupertype().getAnAncestor() }

/**
* Gets a direct or indirect supertype of this type.
* This does not include itself, unless this type is part of a cycle
* in the type hierarchy.
*/
overlay[caller?]
pragma[inline]
RefType getAStrictAncestorI() { result = this.getASupertype().getAnAncestor() }

/**
* Gets the source declaration of a direct supertype of this type, excluding itself.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ module TempDirSystemGetPropertyDirectlyToMkdir =
/**
* A `MethodCall` against a method that creates a temporary file or directory in a shared temporary directory.
*/
overlay[local?]
abstract class MethodCallInsecureFileCreation extends MethodCall {
/**
* Gets the type of entity created (e.g. `file`, `directory`, ...).
Expand All @@ -218,6 +219,7 @@ abstract class MethodCallInsecureFileCreation extends MethodCall {
/**
* An insecure call to `java.io.File.createTempFile`.
*/
overlay[local?]
class MethodCallInsecureFileCreateTempFile extends MethodCallInsecureFileCreation {
MethodCallInsecureFileCreateTempFile() {
this.getMethod() instanceof MethodFileCreateTempFile and
Expand Down Expand Up @@ -246,6 +248,7 @@ class MethodGuavaFilesCreateTempFile extends Method {
/**
* A call to the `com.google.common.io.Files.createTempDir` method.
*/
overlay[local?]
class MethodCallInsecureGuavaFilesCreateTempFile extends MethodCallInsecureFileCreation {
MethodCallInsecureGuavaFilesCreateTempFile() {
this.getMethod() instanceof MethodGuavaFilesCreateTempFile
Expand Down
2 changes: 1 addition & 1 deletion java/ql/src/Language Abuse/UselessTypeTest.ql
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ from InstanceOfExpr ioe, RefType t, RefType ct
where
t = ioe.getExpr().getType() and
ct = ioe.getCheckedType() and
ct = t.getAStrictAncestor()
ct = t.getAStrictAncestorI()
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()
2 changes: 1 addition & 1 deletion java/ql/src/Language Abuse/UselessUpcast.ql
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ where
src = cse.getExpr().getType() and
dest = cse.getType()
) and
dest = src.getAStrictAncestor() and
dest = src.getAStrictAncestorI() 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()
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ from FinalizeMethod m, Class c, FinalizeMethod mSuper, Class cSuper
where
m.getDeclaringType() = c and
mSuper.getDeclaringType() = cSuper and
c.getAStrictAncestor() = cSuper and
c.getAStrictAncestorI() = cSuper and
not cSuper instanceof TypeObject and
not exists(m.getBody().getAChild())
select m, "Finalize in " + c.getName() + " nullifies finalize in " + cSuper.getName() + "."
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,13 @@ where
ma = unqualifiedCallToNonAbstractMethod(c, m) and
// ... there exists an overriding method in a subtype,
n.overrides+(m) and
n.getDeclaringType().getAStrictAncestor() = c.getDeclaringType() and
n.getDeclaringType().getAStrictAncestorI() = c.getDeclaringType() and
// ... the method is in a supertype of c,
m.getDeclaringType() = c.getDeclaringType().getAnAncestor() and
// ... `n` reads a non-final field `f`,
fa = nonFinalFieldRead(n, f) and
// ... which is declared in a subtype of `c`,
f.getDeclaringType().getAStrictAncestor() = c.getDeclaringType() and
f.getDeclaringType().getAStrictAncestorI() = c.getDeclaringType() and
// ... `f` is written only in the subtype constructor, and
fw = fieldWriteOnlyIn(d, f) and
// ... the subtype constructor calls (possibly indirectly) the offending super constructor.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,5 @@ where
not f.isStatic() or
not f.getType().hasName("long")
) and
f.getDeclaringType().getAStrictAncestor() instanceof TypeSerializable
f.getDeclaringType().getAStrictAncestorI() instanceof TypeSerializable
select f, "'serialVersionUID' should be final, static, and of type long."
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ predicate exceptions(Class c, Field f) {
f.isStatic()
or
// Classes that implement `Externalizable` completely take over control during serialization.
externalizable(c.getAStrictAncestor())
externalizable(c.getAStrictAncestorI())
or
// Stateless session beans are not normally serialized during their usual life-cycle
// but are forced by their expected supertype to be serializable.
Expand All @@ -93,7 +93,7 @@ predicate exceptions(Class c, Field f) {
from Class c, Field f, string reason
where
c.fromSource() and
c.getAStrictAncestor() instanceof TypeSerializable and
c.getAStrictAncestorI() instanceof TypeSerializable and
f.getDeclaringType() = c and
not exceptions(c, f) and
reason = nonSerialReason(f.getType())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ from TryStmt try, int first, int second, RefType masking, RefType masked, string
where
try.getFile().isJavaSourceFile() and
masking = caughtType(try, first) and
masking.getAStrictAncestor() = masked and
masking.getAStrictAncestorI() = masked and
masked = caughtType(try, second) and
forall(RefType thrownType |
thrownType = getAThrownExceptionType(try) and
Expand Down
2 changes: 1 addition & 1 deletion java/ql/src/Performance/InnerClassCouldBeStatic.ql
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ pragma[nomagic]
predicate inherits(Class c, Field f) {
f = c.getAField()
or
not f.isPrivate() and c.getAStrictAncestor().getAField() = f
not f.isPrivate() and c.getAStrictAncestorI().getAField() = f
}

/**
Expand Down
2 changes: 2 additions & 0 deletions java/ql/src/Security/CWE/CWE-113/NettyResponseSplitting.ql
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
* external/cwe/cwe-093
* external/cwe/cwe-113
*/
overlay[local?]
module;

import java
import semmle.code.java.dataflow.FlowSources
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ predicate inDifferentBranches(MethodCall ma1, MethodCall ma2) {
/** The method access `ma` occurs in method `runnable`, which is an implementation of `Runnable.run()`. */
predicate inRunnable(MethodCall ma, Method runnable) {
runnable.getName() = "run" and
runnable.getDeclaringType().getAStrictAncestor().hasQualifiedName("java.lang", "Runnable") and
runnable.getDeclaringType().getAStrictAncestorI().hasQualifiedName("java.lang", "Runnable") and
ma.getEnclosingCallable() = runnable
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ predicate trivialContext(Literal e) {
or
// Message in an exception.
exists(ClassInstanceExpr constr |
constr.getType().(RefType).getAStrictAncestor().hasName("Exception") and
constr.getType().(RefType).getAStrictAncestorI().hasName("Exception") and
e = constr.getArgument(0)
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ where
) and
not exists(Method mid |
confusing(m1, mid) and
mid.getDeclaringType().getAStrictAncestor() = m2.getDeclaringType()
mid.getDeclaringType().getAStrictAncestorI() = m2.getDeclaringType()
) and
not exists(Method notConfusing |
notConfusing.getDeclaringType() = m1.getDeclaringType() and
Expand Down