Skip to content

Commit 0102c07

Browse files
authored
Merge pull request from GHSA-mcph-m25j-8j63
* feat: add `safe_output` input enabled by default * fix: migrate README to safe uses of interpolation * fix: README `uses` typo * fix: README examples to account for newlines * fix: README examples missing `safe_output` * fix: remove sanitization of `'` * fix: also sanitize `|&;`
1 parent 089842a commit 0102c07

File tree

6 files changed

+110
-29
lines changed

6 files changed

+110
-29
lines changed

README.md

Lines changed: 69 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -123,14 +123,19 @@ jobs:
123123
- name: Get changed files
124124
id: changed-files
125125
uses: tj-actions/changed-files@v40
126+
with:
127+
safe_output: false # true by default, set to false because we are using an environment variable to store the output and avoid command injection.
126128

127129
# To compare changes between the current commit and the last pushed remote commit set `since_last_remote_commit: true`. e.g
128130
# with:
129131
# since_last_remote_commit: true
130132

131133
- name: List all changed files
134+
env:
135+
ALL_CHANGED_FILES: |-
136+
${{ steps.changed-files.outputs.all_changed_files }}
132137
run: |
133-
for file in ${{ steps.changed-files.outputs.all_changed_files }}; do
138+
for file in "$ALL_CHANGED_FILES"; do
134139
echo "$file was changed"
135140
done
136141
@@ -139,14 +144,18 @@ jobs:
139144
id: changed-markdown-files
140145
uses: tj-actions/changed-files@v40
141146
with:
147+
safe_output: false # true by default, set to false because we are using an environment variable to store the output and avoid command injection.
142148
# Avoid using single or double quotes for multiline patterns
143149
files: |
144150
**.md
145151
146152
- name: List all changed files markdown files
147153
if: steps.changed-markdown-files.outputs.any_changed == 'true'
154+
env:
155+
ALL_CHANGED_FILES: |-
156+
${{ steps.changed-markdown-files.outputs.all_changed_files }}
148157
run: |
149-
for file in ${{ steps.changed-markdown-files.outputs.all_changed_files }}; do
158+
for file in "$ALL_CHANGED_FILES"; do
150159
echo "$file was changed"
151160
done
152161
@@ -155,6 +164,7 @@ jobs:
155164
id: changed-files-yaml
156165
uses: tj-actions/changed-files@v40
157166
with:
167+
safe_output: false # true by default, set to false because we are using an environment variable to store the output and avoid command injection.
158168
files_yaml: |
159169
doc:
160170
- '**.md'
@@ -170,29 +180,39 @@ jobs:
170180
- name: Run step if test file(s) change
171181
# NOTE: Ensure all outputs are prefixed by the same key used above e.g. `test_(...)` | `doc_(...)` | `src_(...)` when trying to access the `any_changed` output.
172182
if: steps.changed-files-yaml.outputs.test_any_changed == 'true'
183+
env:
184+
TEST_ALL_CHANGED_FILES: |-
185+
${{ steps.changed-files-yaml.outputs.test_all_changed_files }}
173186
run: |
174187
echo "One or more test file(s) has changed."
175-
echo "List all the files that have changed: ${{ steps.changed-files-yaml.outputs.test_all_changed_files }}"
188+
echo "List all the files that have changed: $TEST_ALL_CHANGED_FILES"
176189
177190
- name: Run step if doc file(s) change
178191
if: steps.changed-files-yaml.outputs.doc_any_changed == 'true'
192+
env:
193+
DOC_ALL_CHANGED_FILES: |-
194+
${{ steps.changed-files-yaml.outputs.doc_all_changed_files }}
179195
run: |
180196
echo "One or more doc file(s) has changed."
181-
echo "List all the files that have changed: ${{ steps.changed-files-yaml.outputs.doc_all_changed_files }}"
197+
echo "List all the files that have changed: $DOC_ALL_CHANGED_FILES"
182198
183199
# Example 3
184200
- name: Get changed files in the docs folder
185201
id: changed-files-specific
186202
uses: tj-actions/changed-files@v40
187203
with:
204+
safe_output: false # true by default, set to false because we are using an environment variable to store the output and avoid command injection.
188205
files: docs/*.{js,html} # Alternatively using: `docs/**`
189206
files_ignore: docs/static.js
190207

191208
- name: Run step if any file(s) in the docs folder change
192209
if: steps.changed-files-specific.outputs.any_changed == 'true'
210+
env:
211+
ALL_CHANGED_FILES: |-
212+
${{ steps.changed-files-specific.outputs.all_changed_files }}
193213
run: |
194214
echo "One or more files in the docs folder has changed."
195-
echo "List all the files that have changed: ${{ steps.changed-files-specific.outputs.all_changed_files }}"
215+
echo "List all the files that have changed: $ALL_CHANGED_FILES"
196216
```
197217
198218
#### Using Github's API :octocat:
@@ -224,10 +244,15 @@ jobs:
224244
- name: Get changed files
225245
id: changed-files
226246
uses: tj-actions/changed-files@v40
247+
with:
248+
safe_output: false # true by default, set to false because we are using an environment variable to store the output and avoid command injection.
227249

228250
- name: List all changed files
251+
env:
252+
ALL_CHANGED_FILES: |-
253+
${{ steps.changed-files.outputs.all_changed_files }}
229254
run: |
230-
for file in ${{ steps.changed-files.outputs.all_changed_files }}; do
255+
for file in "$ALL_CHANGED_FILES"; do
231256
echo "$file was changed"
232257
done
233258
```
@@ -265,12 +290,17 @@ jobs:
265290
- name: Get changed files
266291
id: changed-files
267292
uses: tj-actions/changed-files@v40
293+
with:
294+
safe_output: false # true by default, set to false because we are using an environment variable to store the output and avoid command injection.
268295

269296
# NOTE: `since_last_remote_commit: true` is implied by default and falls back to the previous local commit.
270297

271298
- name: List all changed files
299+
env:
300+
ALL_CHANGED_FILES: |-
301+
${{ steps.changed-files.outputs.all_changed_files }}
272302
run: |
273-
for file in ${{ steps.changed-files.outputs.all_changed_files }}; do
303+
for file in "$ALL_CHANGED_FILES"; do
274304
echo "$file was changed"
275305
done
276306
...
@@ -715,10 +745,15 @@ See [inputs](#inputs) for more information.
715745
- name: Get changed files
716746
id: changed-files
717747
uses: tj-actions/changed-files@v40
748+
with:
749+
safe_output: false
718750

719751
- name: List all added files
752+
env:
753+
ADDED_FILES: |-
754+
${{ steps.changed-files.outputs.added_files }}
720755
run: |
721-
for file in ${{ steps.changed-files.outputs.added_files }}; do
756+
for file in "$ADDED_FILES"; do
722757
echo "$file was added"
723758
done
724759
...
@@ -736,6 +771,8 @@ See [outputs](#outputs) for a list of all available outputs.
736771
- name: Get changed files
737772
id: changed-files
738773
uses: tj-actions/changed-files@v40
774+
with:
775+
safe_output: false
739776

740777
- name: Run a step if my-file.txt was modified
741778
if: contains(steps.changed-files.outputs.modified_files, 'my-file.txt')
@@ -756,8 +793,9 @@ See [outputs](#outputs) for a list of all available outputs.
756793

757794
- name: Get changed files and write the outputs to a Txt file
758795
id: changed-files-write-output-files-txt
759-
uses: ./
796+
uses: tj-actions/changed-files@v40
760797
with:
798+
safe_output: false
761799
write_output_files: true
762800

763801
- name: Verify the contents of the .github/outputs/added_files.txt file
@@ -775,8 +813,9 @@ See [outputs](#outputs) for a list of all available outputs.
775813
...
776814
- name: Get changed files and write the outputs to a JSON file
777815
id: changed-files-write-output-files-json
778-
uses: ./
816+
uses: tj-actions/changed-files@v40
779817
with:
818+
safe_output: false
780819
json: true
781820
write_output_files: true
782821

@@ -820,6 +859,7 @@ See [inputs](#inputs) for more information.
820859
id: changed-files-specific
821860
uses: tj-actions/changed-files@v40
822861
with:
862+
safe_output: false
823863
files: |
824864
my-file.txt
825865
*.sh
@@ -840,15 +880,21 @@ See [inputs](#inputs) for more information.
840880
841881
- name: Run step if any of the listed files above is deleted
842882
if: steps.changed-files-specific.outputs.any_deleted == 'true'
883+
env:
884+
DELETED_FILES: |-
885+
${{ steps.changed-files-specific.outputs.deleted_files }}
843886
run: |
844-
for file in ${{ steps.changed-files-specific.outputs.deleted_files }}; do
887+
for file in "$DELETED_FILES"; do
845888
echo "$file was deleted"
846889
done
847890
848891
- name: Run step if all listed files above have been deleted
849892
if: steps.changed-files-specific.outputs.only_deleted == 'true'
893+
env:
894+
DELETED_FILES: |-
895+
${{ steps.changed-files-specific.outputs.deleted_files }}
850896
run: |
851-
for file in ${{ steps.changed-files-specific.outputs.deleted_files }}; do
897+
for file in "$DELETED_FILES"; do
852898
echo "$file was deleted"
853899
done
854900
...
@@ -958,14 +1004,18 @@ jobs:
9581004
id: changed-files-specific
9591005
uses: tj-actions/changed-files@v40
9601006
with:
1007+
safe_output: false
9611008
base_sha: ${{ steps.get-base-sha.outputs.base_sha }}
9621009
files: .github/**
9631010

9641011
- name: Run step if any file(s) in the .github folder change
9651012
if: steps.changed-files-specific.outputs.any_changed == 'true'
1013+
env:
1014+
ALL_CHANGED_FILES: |-
1015+
${{ steps.changed-files-specific.outputs.all_changed_files }}
9661016
run: |
9671017
echo "One or more files in the .github folder has changed."
968-
echo "List all the files that have changed: ${{ steps.changed-files-specific.outputs.all_changed_files }}"
1018+
echo "List all the files that have changed: $ALL_CHANGED_FILES"
9691019
...
9701020
```
9711021

@@ -988,11 +1038,15 @@ See [inputs](#inputs) for more information.
9881038
id: changed-files-for-dir1
9891039
uses: tj-actions/changed-files@v40
9901040
with:
1041+
safe_output: false
9911042
path: dir1
9921043

9931044
- name: List all added files in dir1
1045+
env:
1046+
ADDED_FILES: |-
1047+
${{ steps.changed-files-for-dir1.outputs.added_files }}
9941048
run: |
995-
for file in ${{ steps.changed-files-for-dir1.outputs.added_files }}; do
1049+
for file in "$ADDED_FILES"; do
9961050
echo "$file was added"
9971051
done
9981052
...
@@ -1015,7 +1069,7 @@ See [inputs](#inputs) for more information.
10151069

10161070
- name: Run changed-files with quotepath disabled for a specified list of file(s)
10171071
id: changed-files-quotepath-specific
1018-
uses: ./
1072+
uses: tj-actions/changed-files@v40
10191073
with:
10201074
files: test/test-è.txt
10211075
quotepath: "false"

action.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,10 @@ inputs:
134134
description: "Escape JSON output."
135135
required: false
136136
default: "true"
137+
safe_output:
138+
description: "Apply sanitization to output filenames before being set as output."
139+
required: false
140+
default: "true"
137141
fetch_depth:
138142
description: "Depth of additional branch history fetched. NOTE: This can be adjusted to resolve errors with insufficient history."
139143
required: false

src/changedFilesOutput.ts

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@ export const setOutputsAndGetModifiedAndChangedFilesStatus = async ({
4343
writeOutputFiles: inputs.writeOutputFiles,
4444
outputDir: inputs.outputDir,
4545
json: inputs.json,
46-
shouldEscape: inputs.escapeJson
46+
shouldEscape: inputs.escapeJson,
47+
safeOutput: inputs.safeOutput
4748
})
4849
await setOutput({
4950
key: getOutputKey('added_files_count', outputPrefix),
@@ -64,7 +65,8 @@ export const setOutputsAndGetModifiedAndChangedFilesStatus = async ({
6465
writeOutputFiles: inputs.writeOutputFiles,
6566
outputDir: inputs.outputDir,
6667
json: inputs.json,
67-
shouldEscape: inputs.escapeJson
68+
shouldEscape: inputs.escapeJson,
69+
safeOutput: inputs.safeOutput
6870
})
6971

7072
await setOutput({
@@ -86,7 +88,8 @@ export const setOutputsAndGetModifiedAndChangedFilesStatus = async ({
8688
writeOutputFiles: inputs.writeOutputFiles,
8789
outputDir: inputs.outputDir,
8890
json: inputs.json,
89-
shouldEscape: inputs.escapeJson
91+
shouldEscape: inputs.escapeJson,
92+
safeOutput: inputs.safeOutput
9093
})
9194

9295
await setOutput({
@@ -108,7 +111,8 @@ export const setOutputsAndGetModifiedAndChangedFilesStatus = async ({
108111
writeOutputFiles: inputs.writeOutputFiles,
109112
outputDir: inputs.outputDir,
110113
json: inputs.json,
111-
shouldEscape: inputs.escapeJson
114+
shouldEscape: inputs.escapeJson,
115+
safeOutput: inputs.safeOutput
112116
})
113117

114118
await setOutput({
@@ -130,7 +134,8 @@ export const setOutputsAndGetModifiedAndChangedFilesStatus = async ({
130134
writeOutputFiles: inputs.writeOutputFiles,
131135
outputDir: inputs.outputDir,
132136
json: inputs.json,
133-
shouldEscape: inputs.escapeJson
137+
shouldEscape: inputs.escapeJson,
138+
safeOutput: inputs.safeOutput
134139
})
135140

136141
await setOutput({
@@ -152,7 +157,8 @@ export const setOutputsAndGetModifiedAndChangedFilesStatus = async ({
152157
writeOutputFiles: inputs.writeOutputFiles,
153158
outputDir: inputs.outputDir,
154159
json: inputs.json,
155-
shouldEscape: inputs.escapeJson
160+
shouldEscape: inputs.escapeJson,
161+
safeOutput: inputs.safeOutput
156162
})
157163

158164
await setOutput({
@@ -174,7 +180,8 @@ export const setOutputsAndGetModifiedAndChangedFilesStatus = async ({
174180
writeOutputFiles: inputs.writeOutputFiles,
175181
outputDir: inputs.outputDir,
176182
json: inputs.json,
177-
shouldEscape: inputs.escapeJson
183+
shouldEscape: inputs.escapeJson,
184+
safeOutput: inputs.safeOutput
178185
})
179186

180187
await setOutput({
@@ -199,7 +206,8 @@ export const setOutputsAndGetModifiedAndChangedFilesStatus = async ({
199206
writeOutputFiles: inputs.writeOutputFiles,
200207
outputDir: inputs.outputDir,
201208
json: inputs.json,
202-
shouldEscape: inputs.escapeJson
209+
shouldEscape: inputs.escapeJson,
210+
safeOutput: inputs.safeOutput
203211
})
204212

205213
await setOutput({
@@ -226,7 +234,8 @@ export const setOutputsAndGetModifiedAndChangedFilesStatus = async ({
226234
writeOutputFiles: inputs.writeOutputFiles,
227235
outputDir: inputs.outputDir,
228236
json: inputs.json,
229-
shouldEscape: inputs.escapeJson
237+
shouldEscape: inputs.escapeJson,
238+
safeOutput: inputs.safeOutput
230239
})
231240

232241
await setOutput({
@@ -314,7 +323,8 @@ export const setOutputsAndGetModifiedAndChangedFilesStatus = async ({
314323
writeOutputFiles: inputs.writeOutputFiles,
315324
outputDir: inputs.outputDir,
316325
json: inputs.json,
317-
shouldEscape: inputs.escapeJson
326+
shouldEscape: inputs.escapeJson,
327+
safeOutput: inputs.safeOutput
318328
})
319329

320330
await setOutput({
@@ -419,7 +429,8 @@ export const setOutputsAndGetModifiedAndChangedFilesStatus = async ({
419429
writeOutputFiles: inputs.writeOutputFiles,
420430
outputDir: inputs.outputDir,
421431
json: inputs.json,
422-
shouldEscape: inputs.escapeJson
432+
shouldEscape: inputs.escapeJson,
433+
safeOutput: inputs.safeOutput
423434
})
424435

425436
await setOutput({

src/inputs.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ export type Inputs = {
3434
dirNamesDeletedFilesIncludeOnlyDeletedDirs: boolean
3535
json: boolean
3636
escapeJson: boolean
37+
safeOutput: boolean
3738
fetchDepth?: number
3839
fetchSubmoduleHistory: boolean
3940
sinceLastRemoteCommit: boolean
@@ -154,6 +155,7 @@ export const getInputs = (): Inputs => {
154155
)
155156
const json = core.getBooleanInput('json', {required: false})
156157
const escapeJson = core.getBooleanInput('escape_json', {required: false})
158+
const safeOutput = core.getBooleanInput('safe_output', {required: false})
157159
const fetchDepth = core.getInput('fetch_depth', {required: false})
158160
const sinceLastRemoteCommit = core.getBooleanInput(
159161
'since_last_remote_commit',
@@ -272,6 +274,7 @@ export const getInputs = (): Inputs => {
272274
dirNamesIncludeFilesSeparator,
273275
json,
274276
escapeJson,
277+
safeOutput,
275278
writeOutputFiles,
276279
outputDir,
277280
outputRenamedFilesAsDeletedAndAdded,

0 commit comments

Comments
 (0)