From d90fca396a8c2971e72efdb96e26b4b462d098c4 Mon Sep 17 00:00:00 2001 From: Robert Date: Fri, 24 Apr 2020 17:15:22 +0100 Subject: [PATCH 1/2] Create undeclared-action-input.ql --- queries/undeclared-action-input.ql | 63 ++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 queries/undeclared-action-input.ql diff --git a/queries/undeclared-action-input.ql b/queries/undeclared-action-input.ql new file mode 100644 index 000000000..23627205b --- /dev/null +++ b/queries/undeclared-action-input.ql @@ -0,0 +1,63 @@ +/** + * @name Undeclared action input + * @description Code tries to use an input parameter that is not defined for this action. + Perhaps this code is shared by multiple actions. + * @kind problem + * @problem.severity error + * @id javascript/codeql-action/undeclared-action-input + */ + +import javascript + +class ActionDeclaration extends File { + ActionDeclaration() { + getRelativePath().matches("%/action.yml") + } + + string getName() { + result = getRelativePath().regexpCapture("(.*)/action.yml", 1) + } + + YAMLDocument getRootNode() { + result.getFile() = this + } + + string getAnInput() { + result = getRootNode().(YAMLMapping).lookup("inputs").(YAMLMapping).getKey(_).(YAMLString).getValue() + } + + FunctionDeclStmt getEntrypoint() { + result.getFile().getRelativePath() = getRootNode(). + (YAMLMapping).lookup("runs"). + (YAMLMapping).lookup("main"). + (YAMLString).getValue().regexpReplaceAll("\\.\\./lib/(.*)\\.js", "src/$1.ts") and + result.getName() = "run" + } +} + +Expr getAFunctionChildExpr(Function f) { + result = f.getBody().getAChildStmt*().getAChildExpr*() +} + +/* + * Result is a function that is called from the body of the given function `f` + */ +Function calledBy(Function f) { + result = getAFunctionChildExpr(f).(InvokeExpr).getResolvedCallee() +} + +class GetInputMethodCallExpr extends MethodCallExpr { + GetInputMethodCallExpr() { + getMethodName() = "getInput" + } + + string getInputName() { + result = getArgument(0).(StringLiteral).getValue() + } +} + +from ActionDeclaration action, GetInputMethodCallExpr getInputCall, string inputName +where getAFunctionChildExpr(calledBy*(action.getEntrypoint())) = getInputCall and + inputName = getInputCall.getInputName() and + not inputName = action.getAnInput() +select getInputCall, "The $@ input is not defined for the $@ action", inputName, inputName, action, action.getName() From dcd81b5847b81489052bf4eb6e7accdc2d6df8ab Mon Sep 17 00:00:00 2001 From: Robert Brignull Date: Mon, 4 May 2020 15:16:23 +0100 Subject: [PATCH 2/2] Make use of getContainer --- queries/undeclared-action-input.ql | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/queries/undeclared-action-input.ql b/queries/undeclared-action-input.ql index 23627205b..a8ec7c3f4 100644 --- a/queries/undeclared-action-input.ql +++ b/queries/undeclared-action-input.ql @@ -36,7 +36,7 @@ class ActionDeclaration extends File { } Expr getAFunctionChildExpr(Function f) { - result = f.getBody().getAChildStmt*().getAChildExpr*() + result.getContainer() = f } /* @@ -44,6 +44,8 @@ Expr getAFunctionChildExpr(Function f) { */ Function calledBy(Function f) { result = getAFunctionChildExpr(f).(InvokeExpr).getResolvedCallee() + or + result.getEnclosingContainer() = f // assume outer function causes inner function to be called } class GetInputMethodCallExpr extends MethodCallExpr {