Skip to content

Commit

Permalink
fix: detection of changed files that might cause failure on some paths
Browse files Browse the repository at this point in the history
By using `-z` option of `git diff` we can get the file paths without
extra spaces, newlines and quotes. Previously this caused issues like:

```sh
+ head -n1 '"test/fuzz/fuzz-unit-file/dm-back\\x2dslash.swap"'
head: cannot open '"test/fuzz/fuzz-unit-file/dm-back\\x2dslash.swap"' for reading: No such file or directory
```
  • Loading branch information
jamacku committed Aug 10, 2023
1 parent 73d3e0a commit ac11e6a
Show file tree
Hide file tree
Showing 8 changed files with 34 additions and 42 deletions.
1 change: 1 addition & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## Next release

* Fix detection of changed files that might cause failure on paths with special characters.
* Drop support for `shell-scripts` input
* Drop support for `ignored-codes` input

Expand Down
18 changes: 11 additions & 7 deletions src/functions.sh
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ get_scripts_for_scanning () {

# Find modified shell scripts
local list_of_changes=()
file_to_array "${1}" "list_of_changes" 0
file_to_array "${1}" "list_of_changes"

# Create a list of scripts for testing
local scripts_for_scanning=()
Expand Down Expand Up @@ -212,17 +212,21 @@ is_matched_by_path () {
return 2
}

# Function to get rid of comments represented by '#'
# Function that reads a file of paths and stores them in an array
# https://stackoverflow.com/a/28109890/10221282
# $1 - file path
# $2 - name of a variable where the result array will be stored
# $3 - value 1|0 - does the file contain inline comments?
# $? - return value - 0 on success
file_to_array () {
[[ $# -le 2 ]] && return 1
[[ $# -le 1 ]] && return 1
local output=()

[[ "$3" -eq 0 ]] && readarray output < <(grep -v "^#.*" "$1") # fetch the array with lines from the file while excluding '#' comments
[[ "$3" -eq 1 ]] && readarray output < <(cut -d ' ' -f 1 < <(grep -v "^#.*" "$1")) # fetch the array with lines from the file while excluding '#' comments
while IFS= read -r -d '' file; do
output+=("${file}")
done < "${1}"

[[ ${UNIT_TESTS:-1} -eq 0 ]] && echo "${output[@]}"

clean_array "$2" "${output[@]}" && return 0
}

Expand Down Expand Up @@ -250,7 +254,7 @@ clean_array () {
local cleaned_item=""
cleaned_item=$(printf '%s' "${i##+([[:space:]])}") \
&& cleaned_item=$(printf '%s' "${cleaned_item%%+([[:space:]])}")
eval $output+=\("$(printf '%q' "${cleaned_item}")"\)
eval "${output}"+=\("$(printf '%q' "${cleaned_item}")"\)
done

[[ ${extglob_state} -ne 0 ]] && shopt -u extglob
Expand Down
4 changes: 2 additions & 2 deletions src/index.sh
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ is_full_scan_demanded
FULL_SCAN=$?

if [[ ${FULL_SCAN} -eq 0 ]]; then
git ls-tree -r --name-only "${GITHUB_REF_NAME-"main"}" > ../files.txt
git ls-tree -r --name-only -z "${GITHUB_REF_NAME-"main"}" > ../files.txt

all_scripts=()
get_scripts_for_scanning "../files.txt" "all_scripts"
Expand All @@ -37,7 +37,7 @@ if ! [[ ${FULL_SCAN} -eq 0 ]] || ! is_strict_check_on_push_demanded; then
# https://github.com/actions/runner/issues/342
# Get the names of files from range of commits (excluding deleted files)
# BASE and HEAD are always set, it is checked inside pick_base_and_head_hash function
git diff --name-only --diff-filter=db "${BASE}".."${HEAD}" > ../changed-files.txt
git diff --name-only -z --diff-filter=db "${BASE}".."${HEAD}" > ../changed-files.txt

only_changed_scripts=()
get_scripts_for_scanning "../changed-files.txt" "only_changed_scripts"
Expand Down
39 changes: 8 additions & 31 deletions test/file_to_array.bats
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ setup () {
touch file.txt

file_array=()
run file_to_array "file.txt" "file_array"
run file_to_array "file.txt"
assert_failure 1
assert_equal "${file_array[*]}" ""
}
Expand All @@ -28,43 +28,20 @@ setup () {
touch file.txt

file_array=()
run file_to_array "file.txt" "file_array" 0
run file_to_array "file.txt" "file_array"
# assert_success
assert_equal "${file_array[*]}" ""
}

@test "file_to_array() - in-line comments" {
source "${PROJECT_ROOT}/src/functions.sh"

echo -e "\
# comment
#comment
Something1\t # comment
# comment
\rSomething2\r #comment
Something3" > file.txt

local file_array=()
file_to_array "file.txt" "file_array" 1
assert_equal "${file_array[*]}" "Something1 Something2 Something3"
}

@test "file_to_array() - no in-line comments" {
@test "file_to_array() - general" {
source "${PROJECT_ROOT}/src/functions.sh"

echo -e "\
# comment
#comment
Something1\t
# comment
\rSomething2\r
Something3
Something 4 \r
\r Something5&Something6 conf \r" > file.txt
UNIT_TESTS=0

local file_array=()
file_to_array "file.txt" "file_array" 0
assert_equal "${file_array[*]}" "Something1 Something2 Something3 Something 4 Something5&Something6 conf"
file_array=()
run file_to_array "./test/fixtures/file_to_array/files.txt" "file_array"
assert_success
assert_output "test/fixtures/get_scripts_for_scanning/files.txt test/fixtures/get_scripts_for_scanning/non-script.md test/fixtures/get_scripts_for_scanning/script1.sh test/fixtures/get_scripts_for_scanning/script2 test/fixtures/get_scripts_for_scanning/script 2.sh test/fixtures/get_scripts_for_scanning/script&3.sh test/fixtures/get_scripts_for_scanning/\$script4.sh test/fixtures/get_scripts_for_scanning/dm-back\\x2dslash.swap"
}

teardown () {
Expand Down
Binary file added test/fixtures/file_to_array/files.txt
Binary file not shown.
10 changes: 10 additions & 0 deletions test/fixtures/get_scripts_for_scanning/dm-back\x2dslash.swap
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
swap
[Unit]
SourcePath=/etc/fstab
Documentation=man:fstab(5) man:systemd-fstab-generator(8)

[Swap]
What=/dev/mapper/fedora_krowka-swap
Options=defaults,x-systemd.device-timeout=0
Priority=11
TimeoutSec=123h 5min 2y
Binary file modified test/fixtures/get_scripts_for_scanning/files.txt
Binary file not shown.
4 changes: 2 additions & 2 deletions test/get_scripts_for_scanning.bats
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ setup () {
load 'test_helper/bats-support/load'
}

@test "get_scripts_for_scanning()" {
@test "get_scripts_for_scanning() - general" {
source "${PROJECT_ROOT}/src/functions.sh"

UNIT_TESTS=0
Expand All @@ -24,7 +24,7 @@ setup () {
shell_scripts=()
run get_scripts_for_scanning "./test/fixtures/get_scripts_for_scanning/files.txt" "shell_scripts"
assert_success
assert_output "'./test/fixtures/get_scripts_for_scanning/script1.sh' './test/fixtures/get_scripts_for_scanning/script2' './test/fixtures/get_scripts_for_scanning/script 2.sh' './test/fixtures/get_scripts_for_scanning/script&3.sh' './test/fixtures/get_scripts_for_scanning/\$script4.sh'"
assert_output --partial "'./test/fixtures/get_scripts_for_scanning/script1.sh' './test/fixtures/get_scripts_for_scanning/script2' './test/fixtures/get_scripts_for_scanning/script 2.sh' './test/fixtures/get_scripts_for_scanning/script&3.sh' './test/fixtures/get_scripts_for_scanning/\$script4.sh'"
}

teardown () {
Expand Down

0 comments on commit ac11e6a

Please sign in to comment.