|
| 1 | +/** |
| 2 | + * @name Undeclared action input |
| 3 | + * @description Code tries to use an input parameter that is not defined for this action. |
| 4 | + Perhaps this code is shared by multiple actions. |
| 5 | + * @kind problem |
| 6 | + * @problem.severity error |
| 7 | + * @id javascript/codeql-action/undeclared-action-input |
| 8 | + */ |
| 9 | + |
| 10 | +import javascript |
| 11 | + |
| 12 | +class ActionDeclaration extends File { |
| 13 | + ActionDeclaration() { |
| 14 | + getRelativePath().matches("%/action.yml") |
| 15 | + } |
| 16 | + |
| 17 | + string getName() { |
| 18 | + result = getRelativePath().regexpCapture("(.*)/action.yml", 1) |
| 19 | + } |
| 20 | + |
| 21 | + YAMLDocument getRootNode() { |
| 22 | + result.getFile() = this |
| 23 | + } |
| 24 | + |
| 25 | + string getAnInput() { |
| 26 | + result = getRootNode().(YAMLMapping).lookup("inputs").(YAMLMapping).getKey(_).(YAMLString).getValue() |
| 27 | + } |
| 28 | + |
| 29 | + FunctionDeclStmt getEntrypoint() { |
| 30 | + result.getFile().getRelativePath() = getRootNode(). |
| 31 | + (YAMLMapping).lookup("runs"). |
| 32 | + (YAMLMapping).lookup("main"). |
| 33 | + (YAMLString).getValue().regexpReplaceAll("\\.\\./lib/(.*)\\.js", "src/$1.ts") and |
| 34 | + result.getName() = "run" |
| 35 | + } |
| 36 | +} |
| 37 | + |
| 38 | +Expr getAFunctionChildExpr(Function f) { |
| 39 | + result.getContainer() = f |
| 40 | +} |
| 41 | + |
| 42 | +/* |
| 43 | + * Result is a function that is called from the body of the given function `f` |
| 44 | + */ |
| 45 | +Function calledBy(Function f) { |
| 46 | + result = getAFunctionChildExpr(f).(InvokeExpr).getResolvedCallee() |
| 47 | + or |
| 48 | + result.getEnclosingContainer() = f // assume outer function causes inner function to be called |
| 49 | +} |
| 50 | + |
| 51 | +class GetInputMethodCallExpr extends MethodCallExpr { |
| 52 | + GetInputMethodCallExpr() { |
| 53 | + getMethodName() = "getInput" |
| 54 | + } |
| 55 | + |
| 56 | + string getInputName() { |
| 57 | + result = getArgument(0).(StringLiteral).getValue() |
| 58 | + } |
| 59 | +} |
| 60 | + |
| 61 | +from ActionDeclaration action, GetInputMethodCallExpr getInputCall, string inputName |
| 62 | +where getAFunctionChildExpr(calledBy*(action.getEntrypoint())) = getInputCall and |
| 63 | + inputName = getInputCall.getInputName() and |
| 64 | + not inputName = action.getAnInput() |
| 65 | +select getInputCall, "The $@ input is not defined for the $@ action", inputName, inputName, action, action.getName() |
0 commit comments