Skip to content

Commit c66e843

Browse files
authored
#454 Fix - Malformed talismanrc should not be ignored and raise error (#458)
1 parent 666644d commit c66e843

File tree

7 files changed

+151
-59
lines changed

7 files changed

+151
-59
lines changed

cmd/acceptance_test.go

+65
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,13 @@ fileignoreconfig:
4242
checksum: 1db800b79e6e9695adc451f77be974dc47bcd84d42873560d7767bfca30db8b1
4343
ignore_detectors: []
4444
`
45+
const invalidTalismanRC = `
46+
fileignoreconfig:
47+
- filename:
48+
private.pem
49+
checksum: checksum_value
50+
ignore_detectors: []
51+
`
4552

4653
func init() {
4754
git_testing.Logger = logrus.WithField("Environment", "Debug")
@@ -297,6 +304,64 @@ func TestIgnoreHistoryDetectsExistingIssuesOnHead(t *testing.T) {
297304
})
298305
}
299306

307+
func TestTalismanFailsIfTalismanrcIsInvalidYamlInPrePushMode(t *testing.T) {
308+
withNewTmpGitRepo(func(git *git_testing.GitTesting) {
309+
git.SetupBaselineFiles("simple-file")
310+
git.CreateFileWithContents(".talismanrc", invalidTalismanRC)
311+
git.AddAndcommit("*", "Incorrect Talismanrc commit")
312+
313+
assert.Equal(t, 1, runTalismanInPrePushMode(git), "Expected run() to return 1 and fails as talismanrc is invalid")
314+
})
315+
}
316+
317+
func TestTalismanFailsIfTalismanrcIsInvalidYamlInPreCommitMode(t *testing.T) {
318+
withNewTmpGitRepo(func(git *git_testing.GitTesting) {
319+
options.Debug = true
320+
options.GitHook = PreCommit
321+
git.SetupBaselineFiles("simple-file")
322+
git.CreateFileWithContents(".talismanrc", invalidTalismanRC)
323+
git.AddAndcommit("*", "Incorrect Talismanrc commit")
324+
325+
assert.Equal(t, 1, runTalisman(git), "Expected run() to return 0 and pass as pem file was ignored")
326+
})
327+
}
328+
329+
func TestTalismanFailsIfTalismanrcIsInvalidYamlInScanMode(t *testing.T) {
330+
withNewTmpGitRepo(func(git *git_testing.GitTesting) {
331+
options.Debug = true
332+
options.Scan = true
333+
git.SetupBaselineFiles("simple-file")
334+
git.CreateFileWithContents(".talismanrc", invalidTalismanRC)
335+
git.AddAndcommit("*", "Incorrect Talismanrc commit")
336+
337+
assert.Equal(t, 1, runTalisman(git), "Expected run() to return 0 and pass as pem file was ignored")
338+
})
339+
}
340+
341+
func TestTalismanFailsIfTalismanrcIsInvalidYamlInScanWithHTMLMode(t *testing.T) {
342+
withNewTmpGitRepo(func(git *git_testing.GitTesting) {
343+
options.Debug = true
344+
options.ScanWithHtml = true
345+
git.SetupBaselineFiles("simple-file")
346+
git.CreateFileWithContents(".talismanrc", invalidTalismanRC)
347+
git.AddAndcommit("*", "Incorrect Talismanrc commit")
348+
349+
assert.Equal(t, 1, runTalisman(git), "Expected run() to return 0 and pass as pem file was ignored")
350+
})
351+
}
352+
353+
func TestTalismanFailsIfTalismanrcIsInvalidYamlInPatternMode(t *testing.T) {
354+
withNewTmpGitRepo(func(git *git_testing.GitTesting) {
355+
options.Debug = false
356+
options.Pattern = "./*.*"
357+
358+
git.SetupBaselineFiles("simple-file")
359+
git.CreateFileWithContents(".talismanrc", invalidTalismanRC)
360+
361+
assert.Equal(t, 1, runTalisman(git), "Expected run() to return 1 and fail as pem file was present in the repo")
362+
})
363+
}
364+
300365
func runTalismanInPrePushMode(git *git_testing.GitTesting) int {
301366
options.Debug = true
302367
options.GitHook = PrePush

cmd/talisman.go

+26-6
Original file line numberDiff line numberDiff line change
@@ -143,25 +143,45 @@ func run(promptContext prompt.PromptContext) (returnCode int) {
143143
fields := make(map[string]interface{})
144144
_ = json.Unmarshal(optionsBytes, &fields)
145145
log.WithFields(fields).Debug("Talisman execution environment")
146-
defer utility.DestroyHashers()
146+
defer utility.DestroyHashers()
147147
if options.Checksum != "" {
148148
log.Infof("Running %s patterns against checksum calculator", options.Checksum)
149149
return NewChecksumCmd(strings.Fields(options.Checksum)).Run()
150150
} else if options.Scan {
151151
log.Infof("Running scanner")
152-
return NewScannerCmd(options.IgnoreHistory, options.ReportDirectory).Run(talismanrc.ForScan(options.IgnoreHistory))
152+
talismanrcForScan, err := talismanrc.ForScan(options.IgnoreHistory)
153+
if err != nil {
154+
return EXIT_FAILURE
155+
}
156+
return NewScannerCmd(options.IgnoreHistory, options.ReportDirectory).Run(talismanrcForScan)
153157
} else if options.ScanWithHtml {
154158
log.Infof("Running scanner with html report")
155-
return NewScannerCmd(options.IgnoreHistory, "talisman_html_report").Run(talismanrc.ForScan(options.IgnoreHistory))
159+
talismanrcForScan, err := talismanrc.ForScan(options.IgnoreHistory)
160+
if err != nil {
161+
return EXIT_FAILURE
162+
}
163+
return NewScannerCmd(options.IgnoreHistory, "talisman_html_report").Run(talismanrcForScan)
156164
} else if options.Pattern != "" {
157165
log.Infof("Running scan for %s", options.Pattern)
158-
return NewPatternCmd(options.Pattern).Run(talismanrc.For(talismanrc.HookMode), promptContext)
166+
talismanrcForScan, err := talismanrc.For(talismanrc.HookMode)
167+
if err != nil {
168+
return EXIT_FAILURE
169+
}
170+
return NewPatternCmd(options.Pattern).Run(talismanrcForScan, promptContext)
159171
} else if options.GitHook == PreCommit {
160172
log.Infof("Running %s hook", options.GitHook)
161-
return NewPreCommitHook().Run(talismanrc.For(talismanrc.HookMode), promptContext)
173+
talismanrcForScan, err := talismanrc.For(talismanrc.HookMode)
174+
if err != nil {
175+
return EXIT_FAILURE
176+
}
177+
return NewPreCommitHook().Run(talismanrcForScan, promptContext)
162178
} else {
163179
log.Infof("Running %s hook", options.GitHook)
164-
return NewPrePushHook(talismanInput).Run(talismanrc.For(talismanrc.HookMode), promptContext)
180+
talismanrcForScan, err := talismanrc.For(talismanrc.HookMode)
181+
if err != nil {
182+
return EXIT_FAILURE
183+
}
184+
return NewPrePushHook(talismanInput).Run(talismanrcForScan, promptContext)
165185
}
166186
}
167187

detector/filename/filename_detector_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ func shouldNotFailWithDefaultDetectorAndIgnores(fileName, ignore string, thresho
169169
fileIgnoreConfig := &talismanrc.FileIgnoreConfig{}
170170
fileIgnoreConfig.FileName = ignore
171171
fileIgnoreConfig.IgnoreDetectors = []string{"filename"}
172-
talismanRC := talismanrc.For(talismanrc.HookMode)
172+
talismanRC, _ := talismanrc.For(talismanrc.HookMode)
173173
talismanRC.IgnoreConfigs = []talismanrc.IgnoreConfig{fileIgnoreConfig}
174174

175175
DefaultFileNameDetector(threshold).

detector/helpers/detection_results.go

+18-17
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,10 @@ type ResultsSummary struct {
4545
Types FailureTypes `json:"types"`
4646
}
4747

48-
//DetectionResults represents all interesting information collected during a detection run.
49-
//It serves as a collecting parameter for the tests performed by the various Detectors in the DetectorChain
50-
//Currently, it keeps track of failures and ignored files.
51-
//The results are grouped by FilePath for easy reporting of all detected problems with individual files.
48+
// DetectionResults represents all interesting information collected during a detection run.
49+
// It serves as a collecting parameter for the tests performed by the various Detectors in the DetectorChain
50+
// Currently, it keeps track of failures and ignored files.
51+
// The results are grouped by FilePath for easy reporting of all detected problems with individual files.
5252
type DetectionResults struct {
5353
mode talismanrc.Mode
5454
Summary ResultsSummary `json:"summary"`
@@ -64,7 +64,7 @@ func (r *DetectionResults) getResultDetailsForFilePath(fileName gitrepo.FilePath
6464
return nil
6565
}
6666

67-
//NewDetectionResults is a new DetectionResults struct. It represents the pre-run state of a Detection run.
67+
// NewDetectionResults is a new DetectionResults struct. It represents the pre-run state of a Detection run.
6868
func NewDetectionResults(mode talismanrc.Mode) *DetectionResults {
6969
return &DetectionResults{
7070
mode,
@@ -76,9 +76,9 @@ func NewDetectionResults(mode talismanrc.Mode) *DetectionResults {
7676

7777
}
7878

79-
//Fail is used to mark the supplied FilePath as failing a detection for a supplied reason.
80-
//Detectors are encouraged to provide context sensitive messages so that fixing the errors is made simple for the end user
81-
//Fail may be called multiple times for each FilePath and the calls accumulate the provided reasons
79+
// Fail is used to mark the supplied FilePath as failing a detection for a supplied reason.
80+
// Detectors are encouraged to provide context sensitive messages so that fixing the errors is made simple for the end user
81+
// Fail may be called multiple times for each FilePath and the calls accumulate the provided reasons
8282
func (r *DetectionResults) Fail(filePath gitrepo.FilePath, category string, message string, commits []string, severity severity.Severity) {
8383
isFilePresentInResults := false
8484
for resultIndex := 0; resultIndex < len(r.Results); resultIndex++ {
@@ -131,8 +131,8 @@ func (r *DetectionResults) Warn(filePath gitrepo.FilePath, category string, mess
131131
r.Summary.Types.Warnings++
132132
}
133133

134-
//Ignore is used to mark the supplied FilePath as being ignored.
135-
//The most common reason for this is that the FilePath is Denied by the Ignores supplied to the Detector, however, Detectors may use more sophisticated reasons to ignore files.
134+
// Ignore is used to mark the supplied FilePath as being ignored.
135+
// The most common reason for this is that the FilePath is Denied by the Ignores supplied to the Detector, however, Detectors may use more sophisticated reasons to ignore files.
136136
func (r *DetectionResults) Ignore(filePath gitrepo.FilePath, category string) {
137137

138138
isFilePresentInResults := false
@@ -176,12 +176,12 @@ func (r *DetectionResults) updateResultsSummary(category string, decr bool) {
176176
}
177177
}
178178

179-
//HasFailures answers if any Failures were detected for any FilePath in the current run
179+
// HasFailures answers if any Failures were detected for any FilePath in the current run
180180
func (r *DetectionResults) HasFailures() bool {
181181
return r.Summary.Types.Filesize > 0 || r.Summary.Types.Filename > 0 || r.Summary.Types.Filecontent > 0
182182
}
183183

184-
//HasIgnores answers if any FilePaths were ignored in the current run
184+
// HasIgnores answers if any FilePaths were ignored in the current run
185185
func (r *DetectionResults) HasIgnores() bool {
186186
return r.Summary.Types.Ignores > 0
187187
}
@@ -194,12 +194,12 @@ func (r *DetectionResults) HasDetectionMessages() bool {
194194
return r.HasWarnings() || r.HasFailures() || r.HasIgnores()
195195
}
196196

197-
//Successful answers if no detector was able to find any possible result to fail the run
197+
// Successful answers if no detector was able to find any possible result to fail the run
198198
func (r *DetectionResults) Successful() bool {
199199
return !r.HasFailures()
200200
}
201201

202-
//GetFailures returns the various reasons that a given FilePath was marked as failing by all the detectors in the current run
202+
// GetFailures returns the various reasons that a given FilePath was marked as failing by all the detectors in the current run
203203
func (r *DetectionResults) GetFailures(fileName gitrepo.FilePath) []Details {
204204
results := r.getResultDetailsForFilePath(fileName)
205205
if results == nil {
@@ -232,7 +232,7 @@ func (r *DetectionResults) ReportWarnings() string {
232232
return results.String()
233233
}
234234

235-
//Report returns a string documenting the various failures and ignored files for the current run
235+
// Report returns a string documenting the various failures and ignored files for the current run
236236
func (r *DetectionResults) Report(promptContext prompt.PromptContext, mode string) string {
237237
var result string
238238
var filePathsForFailures []string
@@ -273,7 +273,8 @@ func (r *DetectionResults) suggestTalismanRC(filePaths []string, promptContext p
273273

274274
if promptContext.Interactive && runtime.GOOS != "windows" {
275275
confirmedEntries := getUserConfirmation(entriesToAdd, promptContext)
276-
talismanrc.ConfigFromFile().AddIgnores(r.mode, confirmedEntries)
276+
talismanrcConfig, _ := talismanrc.ConfigFromFile()
277+
talismanrcConfig.AddIgnores(r.mode, confirmedEntries)
277278

278279
for _, confirmedEntry := range confirmedEntries {
279280
resultsDetails := r.getResultDetailsForFilePath(gitrepo.FilePath(confirmedEntry.GetFileName()))
@@ -329,7 +330,7 @@ func confirm(config talismanrc.IgnoreConfig, promptContext prompt.PromptContext)
329330
return promptContext.Prompt.Confirm(confirmationString)
330331
}
331332

332-
//ReportFileFailures adds a string to table documenting the various failures detected on the supplied FilePath by all detectors in the current run
333+
// ReportFileFailures adds a string to table documenting the various failures detected on the supplied FilePath by all detectors in the current run
333334
func (r *DetectionResults) ReportFileFailures(filePath gitrepo.FilePath) [][]string {
334335
failureList := r.getResultDetailsForFilePath(filePath).FailureList
335336
var data [][]string

talismanrc/entry-point.go

+7-5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package talismanrc
22

33
import (
4+
"fmt"
45
"regexp"
56
"talisman/utility"
67

@@ -16,25 +17,26 @@ var (
1617
currentRCFileName = DefaultRCFileName
1718
)
1819

19-
func ReadConfigFromRCFile(fileReader func(string) ([]byte, error)) *persistedRC {
20+
func ReadConfigFromRCFile(fileReader func(string) ([]byte, error)) (*persistedRC, error) {
2021
fileContents, err := fileReader(currentRCFileName)
2122
if err != nil {
2223
panic(err)
2324
}
2425
return newPersistedRC(fileContents)
2526
}
2627

27-
func newPersistedRC(fileContents []byte) *persistedRC {
28+
func newPersistedRC(fileContents []byte) (*persistedRC, error) {
2829
talismanRCFromFile := persistedRC{}
2930
err := yaml.Unmarshal(fileContents, &talismanRCFromFile)
3031
if err != nil {
3132
logr.Errorf("Unable to parse .talismanrc : %v", err)
32-
return &persistedRC{}
33+
fmt.Println(fmt.Errorf("\n\x1b[1m\x1b[31mUnable to parse .talismanrc %s. Please ensure it is following the right YAML structure\x1b[0m\x1b[0m\n", err))
34+
return &persistedRC{}, err
3335
}
3436
if talismanRCFromFile.Version == "" {
3537
talismanRCFromFile.Version = DefaultRCVersion
3638
}
37-
return &talismanRCFromFile
39+
return &talismanRCFromFile, nil
3840
}
3941

4042
const (
@@ -68,7 +70,7 @@ func setRepoFileReader(rfr RepoFileReader) {
6870
repoFileReader = func() RepoFileReader { return rfr }
6971
}
7072

71-
func ConfigFromFile() *persistedRC {
73+
func ConfigFromFile() (*persistedRC, error) {
7274
return ReadConfigFromRCFile(repoFileReader())
7375
}
7476

talismanrc/talismanrc.go

+12-12
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ type persistedRC struct {
4444
Version string `default:"2.0" yaml:"version"`
4545
}
4646

47-
//SuggestRCFor returns the talismanRC file content corresponding to input ignore configs
47+
// SuggestRCFor returns the talismanRC file content corresponding to input ignore configs
4848
func SuggestRCFor(configs []IgnoreConfig) string {
4949
fileIgnoreConfigs := []FileIgnoreConfig{}
5050
for _, config := range configs {
@@ -61,17 +61,17 @@ func SuggestRCFor(configs []IgnoreConfig) string {
6161
return string(result)
6262
}
6363

64-
//AcceptsAll returns true if there are no rules specified
64+
// AcceptsAll returns true if there are no rules specified
6565
func (tRC *TalismanRC) AcceptsAll() bool {
6666
return len(tRC.effectiveRules("any-detector")) == 0
6767
}
6868

69-
//Accept answers true if the Addition.Path is configured to be checked by the detectors
69+
// Accept answers true if the Addition.Path is configured to be checked by the detectors
7070
func (tRC *TalismanRC) Accept(addition gitrepo.Addition, detectorName string) bool {
7171
return !tRC.Deny(addition, detectorName)
7272
}
7373

74-
//FilterAdditions removes scope files from additions
74+
// FilterAdditions removes scope files from additions
7575
func (tRC *TalismanRC) FilterAdditions(additions []gitrepo.Addition) []gitrepo.Addition {
7676
var applicableScopeFileNames []string
7777
if tRC.ScopeConfig != nil {
@@ -100,7 +100,7 @@ func (tRC *TalismanRC) FilterAdditions(additions []gitrepo.Addition) []gitrepo.A
100100
func (tRC *persistedRC) AddIgnores(mode Mode, entriesToAdd []IgnoreConfig) {
101101
if len(entriesToAdd) > 0 {
102102
logr.Debugf("Adding entries: %v", entriesToAdd)
103-
talismanRCConfig := ConfigFromFile()
103+
talismanRCConfig, _ := ConfigFromFile()
104104
if mode == HookMode {
105105
fileIgnoreEntries := make([]FileIgnoreConfig, len(entriesToAdd))
106106
for idx, entry := range entriesToAdd {
@@ -154,7 +154,7 @@ func combineFileIgnores(exsiting, incoming []FileIgnoreConfig) []FileIgnoreConfi
154154
return result
155155
}
156156

157-
//Deny answers true if the Addition.Path is configured to be ignored and not checked by the detectors
157+
// Deny answers true if the Addition.Path is configured to be ignored and not checked by the detectors
158158
func (tRC *TalismanRC) Deny(addition gitrepo.Addition, detectorName string) bool {
159159
for _, pattern := range tRC.effectiveRules(detectorName) {
160160
if addition.Matches(pattern) {
@@ -164,8 +164,8 @@ func (tRC *TalismanRC) Deny(addition gitrepo.Addition, detectorName string) bool
164164
return false
165165
}
166166

167-
//Strip git addition
168-
func(tRC *TalismanRC) FilterAllowedPatternsFromAddition(addition gitrepo.Addition) string {
167+
// Strip git addition
168+
func (tRC *TalismanRC) FilterAllowedPatternsFromAddition(addition gitrepo.Addition) string {
169169
additionPathAsString := string(addition.Path)
170170
// Processing global allowed patterns
171171
for _, pattern := range tRC.AllowedPatterns {
@@ -223,13 +223,13 @@ func fromPersistedRC(configFromTalismanRCFile *persistedRC, mode Mode) *Talisman
223223
return &tRC
224224
}
225225

226-
func For(mode Mode) *TalismanRC {
227-
configFromTalismanRCFile := ConfigFromFile()
226+
func For(mode Mode) (*TalismanRC, error) {
227+
configFromTalismanRCFile, err := ConfigFromFile()
228228
talismanRC := fromPersistedRC(configFromTalismanRCFile, mode)
229-
return talismanRC
229+
return talismanRC, err
230230
}
231231

232-
func ForScan(ignoreHistory bool) *TalismanRC {
232+
func ForScan(ignoreHistory bool) (*TalismanRC, error) {
233233
if ignoreHistory {
234234
return For(HookMode)
235235
}

0 commit comments

Comments
 (0)