Skip to content

Commit 3e2dffc

Browse files
author
Alvaro Muñoz
committed
Rename ContextExpression to SimpleReferenceExpression
1 parent e726f9f commit 3e2dffc

File tree

3 files changed

+42
-27
lines changed

3 files changed

+42
-27
lines changed

ql/lib/codeql/actions/Ast.qll

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -226,20 +226,20 @@ class Run extends Step instanceof RunImpl {
226226
Expression getAnScriptExpr() { result = super.getAnScriptExpr() }
227227
}
228228

229-
abstract class ContextExpression extends AstNode instanceof ContextExpressionImpl {
229+
abstract class SimpleReferenceExpression extends AstNode instanceof SimpleReferenceExpressionImpl {
230230
string getFieldName() { result = super.getFieldName() }
231231

232232
AstNode getTarget() { result = super.getTarget() }
233233
}
234234

235-
class StepsExpression extends ContextExpression instanceof StepsExpressionImpl { }
235+
class StepsExpression extends SimpleReferenceExpression instanceof StepsExpressionImpl { }
236236

237-
class NeedsExpression extends ContextExpression instanceof NeedsExpressionImpl { }
237+
class NeedsExpression extends SimpleReferenceExpression instanceof NeedsExpressionImpl { }
238238

239-
class JobsExpression extends ContextExpression instanceof JobsExpressionImpl { }
239+
class JobsExpression extends SimpleReferenceExpression instanceof JobsExpressionImpl { }
240240

241-
class InputsExpression extends ContextExpression instanceof InputsExpressionImpl { }
241+
class InputsExpression extends SimpleReferenceExpression instanceof InputsExpressionImpl { }
242242

243-
class EnvExpression extends ContextExpression instanceof EnvExpressionImpl { }
243+
class EnvExpression extends SimpleReferenceExpression instanceof EnvExpressionImpl { }
244244

245-
class MatrixExpression extends ContextExpression instanceof MatrixExpressionImpl { }
245+
class MatrixExpression extends SimpleReferenceExpression instanceof MatrixExpressionImpl { }

ql/lib/codeql/actions/ast/internal/Ast.qll

Lines changed: 34 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -19,24 +19,18 @@ int partialLineLengthSum(string text, int i) {
1919
result = sum(int j, int length | j in [0 .. i] and length = lineLength(text, j) | length)
2020
}
2121

22-
/**
23-
* Holds if `${{ e }}` is a GitHub Actions expression evaluated within this YAML string.
24-
* See https://docs.github.com/en/free-pro-team@latest/actions/reference/context-and-expression-syntax-for-github-actions.
25-
* Only finds simple expressions like `${{ github.event.comment.body }}`, where the expression contains only alphanumeric characters, underscores, dots, or dashes.
26-
* Does not identify more complicated expressions like `${{ fromJSON(env.time) }}`, or ${{ format('{{Hello {0}!}}', github.event.head_commit.author.name) }}
27-
*/
28-
string getASimpleReferenceExpression(YamlString s, int offset) {
22+
string getADelimitedExpression(YamlString s, int offset) {
2923
// We use `regexpFind` to obtain *all* matches of `${{...}}`,
3024
// not just the last (greedy match) or first (reluctant match).
3125
result =
3226
s.getValue()
33-
.regexpFind("\\$\\{\\{\\s*[A-Za-z0-9'\"_\\[\\]\\*\\(\\)\\.\\-]+\\s*\\}\\}", _, offset)
34-
.regexpCapture("(\\$\\{\\{\\s*[A-Za-z0-9'\"_\\[\\]\\*\\((\\)\\.\\-]+\\s*\\}\\})", 1)
27+
.regexpFind("\\$\\{\\{\\s*.*\\s*\\}\\}", _, offset)
28+
.regexpCapture("(\\$\\{\\{\\s*.*\\s*\\}\\})", 1)
3529
}
3630

3731
private newtype TAstNode =
3832
TExpressionNode(YamlNode key, YamlScalar value, string raw, int exprOffset) {
39-
raw = getASimpleReferenceExpression(value, exprOffset) and
33+
raw = getADelimitedExpression(value, exprOffset) and
4034
exists(YamlMapping m |
4135
(
4236
exists(int i | value = m.getValueNode(i) and key = m.getKeyNode(i))
@@ -789,11 +783,29 @@ class RunImpl extends StepImpl {
789783
}
790784
}
791785

786+
/**
787+
* Holds if `${{ e }}` is a GitHub Actions expression evaluated within this YAML string.
788+
* See https://docs.github.com/en/free-pro-team@latest/actions/reference/context-and-expression-syntax-for-github-actions.
789+
* Only finds simple expressions like `${{ github.event.comment.body }}`, where the expression contains only alphanumeric characters, underscores, dots, or dashes.
790+
* Does not identify more complicated expressions like `${{ fromJSON(env.time) }}`, or ${{ format('{{Hello {0}!}}', github.event.head_commit.author.name) }}
791+
*/
792+
bindingset[s]
793+
string getASimpleReferenceExpression(string s, int offset) {
794+
// We use `regexpFind` to obtain *all* matches of `${{...}}`,
795+
// not just the last (greedy match) or first (reluctant match).
796+
result =
797+
s.trim()
798+
.regexpFind("[A-Za-z0-9'\"_\\[\\]\\*\\(\\)\\.\\-]+", _, offset)
799+
.regexpCapture("([A-Za-z0-9'\"_\\[\\]\\*\\(\\)\\.\\-]+)", 1)
800+
}
801+
792802
/**
793803
* A ${{}} expression accessing a context variable such as steps, needs, jobs, env, inputs, or matrix.
794804
* https://docs.github.com/en/actions/learn-github-actions/contexts#context-availability
795805
*/
796-
abstract class ContextExpressionImpl extends ExpressionImpl {
806+
abstract class SimpleReferenceExpressionImpl extends ExpressionImpl {
807+
SimpleReferenceExpressionImpl() { exists(getASimpleReferenceExpression(expression, _)) }
808+
797809
abstract string getFieldName();
798810

799811
abstract AstNodeImpl getTarget();
@@ -829,7 +841,7 @@ private string wrapRegexp(string regex) {
829841
* https://docs.github.com/en/actions/learn-github-actions/contexts#context-availability
830842
* e.g. `${{ steps.changed-files.outputs.all_changed_files }}`
831843
*/
832-
class StepsExpressionImpl extends ContextExpressionImpl {
844+
class StepsExpressionImpl extends SimpleReferenceExpressionImpl {
833845
string stepId;
834846
string fieldName;
835847

@@ -842,7 +854,7 @@ class StepsExpressionImpl extends ContextExpressionImpl {
842854
override string getFieldName() { result = fieldName }
843855

844856
override AstNodeImpl getTarget() {
845-
this.getLocation().getFile() = result.getLocation().getFile() and
857+
this.getEnclosingJob() = result.getEnclosingJob() and
846858
result.(StepImpl).getId() = stepId
847859
}
848860
}
@@ -852,7 +864,7 @@ class StepsExpressionImpl extends ContextExpressionImpl {
852864
* https://docs.github.com/en/actions/learn-github-actions/contexts#context-availability
853865
* e.g. `${{ needs.job1.outputs.foo}}`
854866
*/
855-
class NeedsExpressionImpl extends ContextExpressionImpl {
867+
class NeedsExpressionImpl extends SimpleReferenceExpressionImpl {
856868
JobImpl neededJob;
857869
string fieldName;
858870

@@ -866,7 +878,10 @@ class NeedsExpressionImpl extends ContextExpressionImpl {
866878
override string getFieldName() { result = fieldName }
867879

868880
override AstNodeImpl getTarget() {
869-
this.getEnclosingJob().getANeededJob() = neededJob and
881+
(
882+
this.getEnclosingJob().getANeededJob() = neededJob or
883+
this.getEnclosingJob() = neededJob
884+
) and
870885
(
871886
// regular jobs
872887
neededJob.getOutputs() = result
@@ -882,7 +897,7 @@ class NeedsExpressionImpl extends ContextExpressionImpl {
882897
* https://docs.github.com/en/actions/learn-github-actions/contexts#context-availability
883898
* e.g. `${{ jobs.job1.outputs.foo}}` (within reusable workflows)
884899
*/
885-
class JobsExpressionImpl extends ContextExpressionImpl {
900+
class JobsExpressionImpl extends SimpleReferenceExpressionImpl {
886901
string jobId;
887902
string fieldName;
888903

@@ -908,7 +923,7 @@ class JobsExpressionImpl extends ContextExpressionImpl {
908923
* https://docs.github.com/en/actions/learn-github-actions/contexts#context-availability
909924
* e.g. `${{ inputs.foo }}`
910925
*/
911-
class InputsExpressionImpl extends ContextExpressionImpl {
926+
class InputsExpressionImpl extends SimpleReferenceExpressionImpl {
912927
string fieldName;
913928

914929
InputsExpressionImpl() {
@@ -933,7 +948,7 @@ class InputsExpressionImpl extends ContextExpressionImpl {
933948
* https://docs.github.com/en/actions/learn-github-actions/contexts#context-availability
934949
* e.g. `${{ env.foo }}`
935950
*/
936-
class EnvExpressionImpl extends ContextExpressionImpl {
951+
class EnvExpressionImpl extends SimpleReferenceExpressionImpl {
937952
string fieldName;
938953

939954
EnvExpressionImpl() {
@@ -956,7 +971,7 @@ class EnvExpressionImpl extends ContextExpressionImpl {
956971
* https://docs.github.com/en/actions/learn-github-actions/contexts#context-availability
957972
* e.g. `${{ matrix.foo }}`
958973
*/
959-
class MatrixExpressionImpl extends ContextExpressionImpl {
974+
class MatrixExpressionImpl extends SimpleReferenceExpressionImpl {
960975
string fieldName;
961976

962977
MatrixExpressionImpl() {

ql/lib/codeql/actions/dataflow/internal/DataFlowPrivate.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,7 @@ predicate jumpStep(Node nodeFrom, Node nodeTo) { none() }
271271
* Holds if a Expression reads a field from a job (needs/jobs), step (steps) output via a read of `c` (fieldname)
272272
*/
273273
predicate ctxFieldReadStep(Node node1, Node node2, ContentSet c) {
274-
exists(ContextExpression access |
274+
exists(SimpleReferenceExpression access |
275275
(
276276
access instanceof NeedsExpression or
277277
access instanceof StepsExpression or

0 commit comments

Comments
 (0)