Skip to content

Commit 9777cb1

Browse files
Merge pull request #3464 from github/robertbrignull/token-not-used
Create token-not-used.ql to catch cases where we aren't using the progress bar token correctly
2 parents d9ac874 + fffb034 commit 9777cb1

File tree

3 files changed

+74
-0
lines changed

3 files changed

+74
-0
lines changed
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import javascript
2+
3+
abstract class ProgressBar extends CallExpr {
4+
ProgressBar() { any() }
5+
6+
abstract Function getCallback();
7+
8+
abstract ObjectExpr getOptions();
9+
10+
predicate usesToken() { exists(this.getTokenParameter()) }
11+
12+
Parameter getTokenParameter() { result = this.getCallback().getParameter(1) }
13+
14+
Property getCancellableProperty() { result = this.getOptions().getPropertyByName("cancellable") }
15+
16+
predicate isCancellable() {
17+
this.getCancellableProperty().getInit().(BooleanLiteral).getBoolValue() =
18+
true
19+
}
20+
}
21+
22+
class WithProgressCall extends ProgressBar {
23+
WithProgressCall() { this.getCalleeName() = "withProgress" }
24+
25+
override Function getCallback() { result = this.getArgument(0) }
26+
27+
override ObjectExpr getOptions() { result = this.getArgument(1) }
28+
}
29+
30+
class WithInheritedProgressCall extends ProgressBar {
31+
WithInheritedProgressCall() { this.getCalleeName() = "withInheritedProgress" }
32+
33+
override Function getCallback() { result = this.getArgument(1) }
34+
35+
override ObjectExpr getOptions() { result = this.getArgument(2) }
36+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/**
2+
* @name Using token for non-cancellable progress bar
3+
* @kind problem
4+
* @problem.severity warning
5+
* @id vscode-codeql/progress-not-cancellable
6+
* @description If we call `withProgress` without `cancellable: true` then the
7+
* token that is given to us should be ignored because it won't ever be cancelled.
8+
* This makes the code more confusing as it tries to account for cases that can't
9+
* happen. The fix is to either not use the token or make the progress bar cancellable.
10+
*/
11+
12+
import javascript
13+
import ProgressBar
14+
15+
from ProgressBar t
16+
where not t.isCancellable() and t.usesToken()
17+
select t,
18+
"The $@ should not be used when the progress bar is not cancellable. Either stop using the $@ or mark the progress bar as cancellable.",
19+
t.getTokenParameter(), t.getTokenParameter().getName(), t.getTokenParameter(),
20+
t.getTokenParameter().getName()
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/**
2+
* @name Don't ignore the token for a cancellable progress bar
3+
* @kind problem
4+
* @problem.severity warning
5+
* @id vscode-codeql/token-not-used
6+
* @description If we call `withProgress` with `cancellable: true` but then
7+
* ignore the token that is given to us, it will lead to a poor user experience
8+
* because the progress bar will appear to be canceled but it will not actually
9+
* affect the background process. Either check the token and respect when it
10+
* has been cancelled, or mark the progress bar as not cancellable.
11+
*/
12+
13+
import javascript
14+
import ProgressBar
15+
16+
from ProgressBar t
17+
where t.isCancellable() and not t.usesToken()
18+
select t, "This progress bar is $@ but the token is not used. Either use the token or mark the progress bar as not cancellable.", t.getCancellableProperty(), "cancellable"

0 commit comments

Comments
 (0)