Skip to content

Commit dc1dc2a

Browse files
committed
parse the uses field in the getters instead of the charpred
1 parent 9ea0f71 commit dc1dc2a

File tree

1 file changed

+17
-18
lines changed

1 file changed

+17
-18
lines changed

javascript/ql/lib/semmle/javascript/Actions.qll

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,15 @@ module Actions {
144144
Step getStep() { result = step }
145145
}
146146

147+
/**
148+
* Gets a regular expression that parses an `owner/repo@version` reference within a `uses` field in an Actions job step.
149+
* The capture groups are:
150+
* 1: The owner of the repository where the Action comes from, e.g. `actions` in `actions/checkout@v2`
151+
* 2: The name of the repository where the Action comes from, e.g. `checkout` in `actions/checkout@v2`.
152+
* 3: The version reference used when checking out the Action, e.g. `v2` in `actions/checkout@v2`.
153+
*/
154+
private string usesParser() { result = "([^/]+)/([^/@]+)@(.+)" }
155+
147156
/**
148157
* A `uses` field within an Actions job step, which references an action as a reusable unit of code.
149158
* See https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobsjob_idstepsuses.
@@ -157,31 +166,21 @@ module Actions {
157166
*/
158167
class Uses extends YAMLNode, YAMLScalar {
159168
Step step;
160-
/** The owner of the repository where the Action comes from, e.g. `actions` in `actions/checkout@v2`. */
161-
string repositoryOwner;
162-
/** The name of the repository where the Action comes from, e.g. `checkout` in `actions/checkout@v2`. */
163-
string repositoryName;
164-
/** The version reference used when checking out the Action, e.g. `v2` in `actions/checkout@v2`. */
165-
string version;
166-
167-
Uses() {
168-
step.lookup("uses") = this and
169-
// Simple regular expression to split up an Action reference `owner/repo@version` into its components.
170-
exists(string regexp | regexp = "([^/]+)/([^/@]+)@(.+)" |
171-
repositoryOwner = this.getValue().regexpCapture(regexp, 1) and
172-
repositoryName = this.getValue().regexpCapture(regexp, 2) and
173-
version = this.getValue().regexpCapture(regexp, 3)
174-
)
175-
}
169+
170+
Uses() { step.lookup("uses") = this }
176171

177172
/** Gets the step this field belongs to. */
178173
Step getStep() { result = step }
179174

180175
/** Gets the owner and name of the repository where the Action comes from, e.g. `actions/checkout` in `actions/checkout@v2`. */
181-
string getGitHubRepository() { result = repositoryOwner + "/" + repositoryName }
176+
string getGitHubRepository() {
177+
result =
178+
this.getValue().regexpCapture(usesParser(), 1) + "/" +
179+
this.getValue().regexpCapture(usesParser(), 2)
180+
}
182181

183182
/** Gets the version reference used when checking out the Action, e.g. `v2` in `actions/checkout@v2`. */
184-
string getVersion() { result = version }
183+
string getVersion() { result = this.getValue().regexpCapture(usesParser(), 3) }
185184
}
186185

187186
/**

0 commit comments

Comments
 (0)