Skip to content

Commit

Permalink
Merge branch 'main' into fix_faulty_shell_file_handling
Browse files Browse the repository at this point in the history
  • Loading branch information
azeemshaikh38 authored Nov 22, 2021
2 parents cb8da73 + 9b600bd commit 5d6f0d4
Show file tree
Hide file tree
Showing 7 changed files with 224 additions and 1 deletion.
21 changes: 21 additions & 0 deletions checks/fileparser/github_workflow.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,14 @@ func getJobStrategyMatrixRows(job *actionlint.Job) map[string]*actionlint.Matrix
return nil
}

func getJobStrategyMatrixIncludeCombinations(job *actionlint.Job) []*actionlint.MatrixCombination {
if job != nil && job.Strategy != nil && job.Strategy.Matrix != nil && job.Strategy.Matrix.Include != nil &&
job.Strategy.Matrix.Include.Combinations != nil {
return job.Strategy.Matrix.Include.Combinations
}
return nil
}

// FormatActionlintError combines the errors into a single one.
func FormatActionlintError(errs []*actionlint.Error) error {
if len(errs) == 0 {
Expand Down Expand Up @@ -125,6 +133,19 @@ func GetOSesForJob(job *actionlint.Job) ([]string, error) {
}
}

matrixCombinations := getJobStrategyMatrixIncludeCombinations(job)
for _, combination := range matrixCombinations {
if combination.Assigns == nil {
continue
}
for _, assign := range combination.Assigns {
if assign.Key == nil || assign.Key.Value != os || assign.Value == nil {
continue
}
jobOSes = append(jobOSes, strings.Trim(assign.Value.String(), "'\""))
}
}

if len(jobOSes) == 0 {
return jobOSes, sce.WithMessage(sce.ErrScorecardInternal,
fmt.Sprintf("unable to determine OS for job: %v", GetJobName(job)))
Expand Down
10 changes: 10 additions & 0 deletions checks/fileparser/github_workflow_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,16 @@ func TestGitHubWorkflowShell(t *testing.T) {
filename: "../testdata/github-workflow-shells-all-windows-matrix.yaml",
expectedShells: []string{"pwsh"},
},
{
name: "all windows, OSes listed in matrix.include",
filename: "../testdata/github-workflow-shells-all-windows-matrix-include.yaml",
expectedShells: []string{"pwsh"},
},
{
name: "all windows, empty matrix.include",
filename: "../testdata/github-workflow-shells-all-windows-matrix-include-empty.yaml",
expectedShells: []string{"pwsh"},
},
{
name: "all windows",
filename: "../testdata/github-workflow-shells-all-windows.yaml",
Expand Down
19 changes: 19 additions & 0 deletions checks/fileparser/listing.go
Original file line number Diff line number Diff line change
Expand Up @@ -222,3 +222,22 @@ func CheckFileContainsCommands(content []byte, comment string) bool {
}
return false
}

// IsTemplateFile returns true if the file name contains a string commonly used in template files.
func IsTemplateFile(pathfn string) bool {
parts := strings.FieldsFunc(path.Base(pathfn), func(r rune) bool {
switch r {
case '.', '-', '_':
return true
default:
return false
}
})
for _, part := range parts {
switch strings.ToLower(part) {
case "template", "tmpl", "tpl":
return true
}
}
return false
}
122 changes: 122 additions & 0 deletions checks/fileparser/listing_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
// Copyright 2021 Security Scorecard Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package fileparser

import (
"testing"
)

func TestIsTemplateFile(t *testing.T) {
t.Parallel()

tests := []struct {
filename string
isTemplate bool
}{
{
filename: "Dockerfile.template",
isTemplate: true,
},
{
filename: "Dockerfile.tmpl",
isTemplate: true,
},
{
filename: "Dockerfile.template-debian",
isTemplate: true,
},
{
filename: "Dockerfile.tmpl.",
isTemplate: true,
},
{
filename: "Dockerfile-template",
isTemplate: true,
},
{
filename: "tmpl.Dockerfile",
isTemplate: true,
},
{
filename: "template.Dockerfile",
isTemplate: true,
},
{
filename: "Dockerfile_template",
isTemplate: true,
},
{
filename: "Dockerfile.tmpl.prod",
isTemplate: true,
},
{
filename: "Dockerfile.Template",
isTemplate: true,
},
{
filename: "dockerfile.tpl",
isTemplate: true,
},
{
filename: "build/Dockerfile.tpl",
isTemplate: true,
},
{
filename: "build/tpl.Dockerfile",
isTemplate: true,
},
{
filename: "DockerfileTemplate",
isTemplate: false,
},
{
filename: "Dockerfile.linux",
isTemplate: false,
},
{
filename: "tmp.Dockerfile",
isTemplate: false,
},
{
filename: "Dockerfile",
isTemplate: false,
},
{
filename: "Dockerfile.temp.late",
isTemplate: false,
},
{
filename: "Dockerfile.temp",
isTemplate: false,
},
{
filename: "template/Dockerfile",
isTemplate: false,
},
{
filename: "linux.Dockerfile",
isTemplate: false,
},
}
for _, tt := range tests {
tt := tt // Re-initializing variable so it is not changed while executing the closure below
t.Run(tt.filename, func(t *testing.T) {
t.Parallel()
if got := IsTemplateFile(tt.filename); got != tt.isTemplate {
t.Errorf("%v: Got (%v) expected (%v)", tt.filename, got, tt.isTemplate)
}
})
}
}
6 changes: 5 additions & 1 deletion checks/pinned_dependencies.go
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,6 @@ func validateDockerfileIsPinned(pathfn string, content []byte,
dl checker.DetailLogger, data fileparser.FileCbData) (bool, error) {
// Users may use various names, e.g.,
// Dockerfile.aarch64, Dockerfile.template, Dockerfile_template, dockerfile, Dockerfile-name.template
// Templates may trigger false positives, e.g. FROM { NAME }.

pdata := dataAsResultPointer(data)
// Return early if this is a script, e.g. script_dockerfile_something.sh
Expand All @@ -350,6 +349,11 @@ func validateDockerfileIsPinned(pathfn string, content []byte,
return true, nil
}

if fileparser.IsTemplateFile(pathfn) {
addPinnedResult(pdata, true)
return true, nil
}

// We have what looks like a docker file.
// Let's interpret the content as utf8-encoded strings.
contentReader := strings.NewReader(string(content))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Copyright 2021 Security Scorecard Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

jobs:
Job1:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [windows-2019, windows-latest]
include:
steps:
- run: echo "hello, github"
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Copyright 2021 Security Scorecard Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

jobs:
Job1:
runs-on: ${{ matrix.os }}
strategy:
matrix:
include:
- {name: Windows, python: '3.9', os: windows-latest}
- {name: Windows, python: '3.8', os: windows-2019}
steps:
- run: echo "hello, github"

0 comments on commit 5d6f0d4

Please sign in to comment.