Skip to content

Commit 58a0034

Browse files
Merge pull request #112 from github/undeclared-action-input
Fix undeclared action inputs
2 parents b673c57 + c7c1aa8 commit 58a0034

File tree

2 files changed

+44
-2
lines changed

2 files changed

+44
-2
lines changed

analyze/action.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ inputs:
2020
description: The number of threads to be used by CodeQL.
2121
required: false
2222
default: "1"
23+
checkout_path:
24+
description: "The path at which the analyzed repository was checked out. Used to relativeize any absolute paths in the uploaded SARIF file."
25+
required: false
26+
default: ${{ github.workspace }}
2327
token:
2428
default: ${{ github.token }}
2529
matrix:

queries/undeclared-action-input.ql

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,17 @@
99

1010
import javascript
1111

12+
/**
13+
* A declaration of a github action, including its inputs and entrypoint.
14+
*/
1215
class ActionDeclaration extends File {
1316
ActionDeclaration() {
1417
getRelativePath().matches("%/action.yml")
1518
}
1619

20+
/**
21+
* The name of the action.
22+
*/
1723
string getName() {
1824
result = getRelativePath().regexpCapture("(.*)/action.yml", 1)
1925
}
@@ -22,10 +28,16 @@ class ActionDeclaration extends File {
2228
result.getFile() = this
2329
}
2430

31+
/**
32+
* The name of any input to this action.
33+
*/
2534
string getAnInput() {
2635
result = getRootNode().(YAMLMapping).lookup("inputs").(YAMLMapping).getKey(_).(YAMLString).getValue()
2736
}
2837

38+
/**
39+
* The function that is the entrypoint to this action.
40+
*/
2941
FunctionDeclStmt getEntrypoint() {
3042
result.getFile().getRelativePath() = getRootNode().
3143
(YAMLMapping).lookup("runs").
@@ -35,6 +47,21 @@ class ActionDeclaration extends File {
3547
}
3648
}
3749

50+
/**
51+
* A function declared on CodeQL interface from codeql.ts
52+
*/
53+
class CodeQLFunction extends Function {
54+
CodeQLFunction() {
55+
exists(Function getCodeQLForCmd, ObjectExpr obj |
56+
getCodeQLForCmd.getName() = "getCodeQLForCmd" and
57+
obj = getCodeQLForCmd.getAStmt().(ReturnStmt).getExpr() and
58+
obj.getAProperty().getInit() = this)
59+
}
60+
}
61+
62+
/**
63+
* Any expr that is a transitive child of the given function.
64+
*/
3865
Expr getAFunctionChildExpr(Function f) {
3966
result.getContainer() = f
4067
}
@@ -45,14 +72,25 @@ Expr getAFunctionChildExpr(Function f) {
4572
Function calledBy(Function f) {
4673
result = getAFunctionChildExpr(f).(InvokeExpr).getResolvedCallee()
4774
or
48-
result.getEnclosingContainer() = f // assume outer function causes inner function to be called
75+
// Assume outer function causes inner function to be called,
76+
// except for the special case of the CodeQL functions.
77+
(result.getEnclosingContainer() = f and not result instanceof CodeQLFunction)
78+
or
79+
// Handle calls to CodeQL functions by name
80+
getAFunctionChildExpr(f).(InvokeExpr).getCalleeName() = result.(CodeQLFunction).getName()
4981
}
5082

83+
/**
84+
* A call to the core.getInput method.
85+
*/
5186
class GetInputMethodCallExpr extends MethodCallExpr {
5287
GetInputMethodCallExpr() {
5388
getMethodName() = "getInput"
5489
}
5590

91+
/**
92+
* The name of the input being accessed.
93+
*/
5694
string getInputName() {
5795
result = getArgument(0).(StringLiteral).getValue()
5896
}
@@ -62,4 +100,4 @@ from ActionDeclaration action, GetInputMethodCallExpr getInputCall, string input
62100
where getAFunctionChildExpr(calledBy*(action.getEntrypoint())) = getInputCall and
63101
inputName = getInputCall.getInputName() and
64102
not inputName = action.getAnInput()
65-
select getInputCall, "The $@ input is not defined for the $@ action", inputName, inputName, action, action.getName()
103+
select getInputCall, "The $@ input is not defined for the $@ action", inputName, inputName, action, action.getName()

0 commit comments

Comments
 (0)