mirror of
https://github.com/github/codeql.git
synced 2026-02-11 20:51:06 +01:00
Merge pull request #21226 from owen-mc/java/update-qhelp-unrelease-lock
Java: Improve qhelp for `java/unreleased-lock` and add lock type exclusion
This commit is contained in:
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* The query `java/unreleased-lock` no longer applies to lock types with names ending in "Pool", as these typically manage a collection of resources and the `lock` and `unlock` methods typically only lock one resource at a time. This may lead to a reduction in false positives.
|
||||
@@ -6,12 +6,16 @@ import semmle.code.java.frameworks.Mockito
|
||||
|
||||
/**
|
||||
* A Java type representing a lock.
|
||||
* We identify a lock type as one that has both `lock` and `unlock` methods.
|
||||
*
|
||||
* We exclude types with a name ending in "Pool" as they typically manage a
|
||||
* collection of resources and the `lock` and `unlock` methods typically only
|
||||
* lock one resource at a time.
|
||||
*/
|
||||
class LockType extends RefType {
|
||||
LockType() {
|
||||
this.getAMethod().hasName("lock") and
|
||||
this.getAMethod().hasName("unlock")
|
||||
this.getAMethod().hasName("unlock") and
|
||||
not this.getName().matches("%Pool")
|
||||
}
|
||||
|
||||
/** Gets a method that is locking this lock type. */
|
||||
|
||||
@@ -6,18 +6,23 @@
|
||||
<overview>
|
||||
<p>
|
||||
When a thread acquires a lock it must make sure to unlock it again;
|
||||
failing to do so can lead to deadlocks. If a lock allows a thread to acquire
|
||||
failing to do so can lead to deadlocks. If a lock allows a thread to acquire
|
||||
it multiple times, for example <code>java.util.concurrent.locks.ReentrantLock</code>,
|
||||
then the number of locks must match the number of unlocks in order to fully
|
||||
release the lock.
|
||||
</p>
|
||||
<p>
|
||||
Any class that has both <code>lock</code> and <code>unlock</code> methods is
|
||||
considered a lock type. However, classes with names ending in "Pool" are excluded,
|
||||
as they typically manage a collection of resources.
|
||||
</p>
|
||||
</overview>
|
||||
|
||||
<recommendation>
|
||||
<p>
|
||||
It is recommended practice always to immediately follow a call to <code>lock</code>
|
||||
with a <code>try</code> block and place the call to <code>unlock</code> inside the
|
||||
<code>finally</code> block. Beware of calls inside the <code>finally</code> block
|
||||
<code>finally</code> block. Beware of calls inside the <code>finally</code> block
|
||||
that could cause exceptions, as this may result in skipping the call to <code>unlock</code>.
|
||||
</p>
|
||||
</recommendation>
|
||||
|
||||
@@ -120,4 +120,16 @@ class Test {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static class TestPool {
|
||||
void lock() {}
|
||||
void unlock() {}
|
||||
}
|
||||
|
||||
void good11() {
|
||||
TestPool pool = new TestPool();
|
||||
pool.lock(); // Should be excluded because of "Pool" suffix
|
||||
f();
|
||||
pool.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user