-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Java: Add java/javautilconcurrentscheduledthreadpoolexecutor
query for zero thread pool size
#19844
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
base: main
Are you sure you want to change the base?
Conversation
java/ql/src/Likely Bugs/Concurrency/ScheduledThreadPoolExecutorZeroThread.ql
Fixed
Show fixed
Hide fixed
...uery-tests/ScheduledThreadPoolExecutorZeroThread/ScheduledThreadPoolExecutorZeroThread.qlref
Fixed
Show fixed
Hide fixed
e2b0faa
to
c6a4221
Compare
…for zero thread pool size
c6a4221
to
60e726b
Compare
|
||
from IntegerLiteral zero, Sink set | ||
where | ||
DataFlow::localFlow(DataFlow::exprNode(zero), DataFlow::exprNode(set.getArgument(0))) and |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there any particular reason why only local flow is used (instead of making a data flow configuration and using global flow)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know if there's any reason. I simply migrated the query as is from the private repo.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just tried the below:
private module FlowConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source.asExpr().(IntegerLiteral).getIntValue() = 0 }
predicate isSink(DataFlow::Node sink) { exists(Sink s | s.getArgument(0) = sink.asExpr()) }
}
private module Flow = DataFlow::Global<FlowConfig>;
from DataFlow::Node sinkNode, Sink s
where Flow::flow(_, sinkNode) and s.getArgument(0) = sinkNode.asExpr()
select s, "ScheduledThreadPoolExecutor.corePoolSize is set to have 0 threads."
It resulted in some new findings, for example this, which is a FP.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Where is the source of the FP located?
- Are you categorising it as an FP due to the
threads > 0
check?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I haven't checked the source, only saw the threads > 0
check.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For some reason the global dataflow doesn't properly use the guard check threads > 0
in this case. Not sure why that happens (it works fine in a local flow example). Let's keep it as it is then (as you also mentioned offline - the most relevant usecase is probably immediate initialisation with 0
or something that can be picked up by local flow).
@@ -0,0 +1,35 @@ | |||
/** | |||
* @id java/javautilconcurrentscheduledthreadpoolexecutor |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe put some hyphens in the id for readability?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changing the ID would be a breaking change for customers already using this query. Do you think improving the readability of the ID is worth doing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
@@ -0,0 +1,24 @@ | |||
## Overview | |||
|
|||
According the Java documentation on `ScheduledThreadPoolExecutor`, it is not a good idea to set `corePoolSize` to zero, since doing so indicates the executor to keep 0 threads in its pool and the executor will serve no purpose. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
According the Java documentation on `ScheduledThreadPoolExecutor`, it is not a good idea to set `corePoolSize` to zero, since doing so indicates the executor to keep 0 threads in its pool and the executor will serve no purpose. | |
According to the Java documentation on `ScheduledThreadPoolExecutor`, it is not a good idea to set `corePoolSize` to zero, since doing so indicates the executor to keep 0 threads in its pool and the executor will serve no purpose. |
This pull request introduces a new query to identify potential issues with setting the
corePoolSize
ofScheduledThreadPoolExecutor
to zero, which may lead to unintended behavior and programmer error. The changes include adding the query logic, documentation, test cases, and integration into the query suite.MRVA top 100 only reports 4 alerts. I checked autofix on 3 of these. Two autofix suggestions completely removed the
executor.setCorePoolSize(0)
calls, the third one changed the 0 value toSchedulers.DEFAULT_POOL_SIZE
, which is the value used insetMaximumPoolSize
.