@@ -15,6 +15,9 @@ import (
1515"gopkg.in/yaml.v3"
1616)
1717
18+ // by default, all rules are valid
19+ var defaultInvalidRules = []string {}
20+
1821type FileFilter struct {
1922path string
2023defaultRules []string
@@ -179,10 +182,10 @@ func (fw *FileFilter) parseDotSnykFile(content []byte, filePath string) []string
179182
180183var globs []string
181184for _ ,codeRule := range rules .Exclude .Code {
182- globs = append (globs ,parseIgnoreRuleToGlobs (codeRule ,filePath )... )
185+ globs = append (globs ,parseIgnoreRuleToGlobs (codeRule ,filePath , defaultInvalidRules )... )
183186}
184187for _ ,codeRule := range rules .Exclude .Global {
185- globs = append (globs ,parseIgnoreRuleToGlobs (codeRule ,filePath )... )
188+ globs = append (globs ,parseIgnoreRuleToGlobs (codeRule ,filePath , defaultInvalidRules )... )
186189}
187190
188191return globs
@@ -193,23 +196,52 @@ func parseIgnoreFile(content []byte, filePath string) []string {
193196var ignores []string
194197lines := strings .Split (string (content ),"\n " )
195198
199+ // Invalid .gitignore style patterns
200+ invalidRules := []string {"." }
201+
196202for _ ,line := range lines {
197203if strings .HasPrefix (line ,"#" )|| strings .TrimSpace (line )== "" {
198204continue
199205}
200- globs := parseIgnoreRuleToGlobs (line ,filePath )
206+ globs := parseIgnoreRuleToGlobs (line ,filePath , invalidRules )
201207ignores = append (ignores ,globs ... )
202208}
203209return ignores
204210}
205211
212+ // escapeSpecialGlobChars escapes special characters that should be treated literally in glob patterns.
213+ // Special Characters to escape: $
214+ func escapeSpecialGlobChars (rule string )string {
215+ var result strings.Builder
216+ for i := 0 ;i < len (rule );i ++ {
217+ ch := rule [i ]
218+ switch ch {
219+ case '$' :
220+ result .WriteByte ('\\' )
221+ result .WriteByte (ch )
222+ default :
223+ result .WriteByte (ch )
224+ }
225+ }
226+ return result .String ()
227+ }
228+
206229// parseIgnoreRuleToGlobs contains the business logic to build glob patterns from a given ignore file
207- func parseIgnoreRuleToGlobs (rule string ,filePath string ) (globs []string ) {
230+ // we try to implement the same logic as gitignore pattern format - https://git-scm.com/docs/gitignore#_pattern_format
231+ func parseIgnoreRuleToGlobs (rule string ,filePath string ,invalidRules []string ) (globs []string ) {
208232// Mappings from .gitignore format to glob format:
209233// `/foo/` => `/foo/**` (meaning: Ignore root (not sub) foo dir and its paths underneath.)
210234// `/foo`=> `/foo/**`, `/foo` (meaning: Ignore root (not sub) file and dir and its paths underneath.)
211235// `foo/` => `**/foo/**` (meaning: Ignore (root/sub) foo dirs and their paths underneath.)
212236// `foo` => `**/foo/**`, `foo` (meaning: Ignore (root/sub) foo filesToFilter and dirs and their paths underneath.)
237+
238+ // If a rule is invalid, we skip it
239+ for _ ,invalidRule := range invalidRules {
240+ if strings .TrimSpace (rule )== invalidRule {
241+ return globs
242+ }
243+ }
244+
213245prefix := ""
214246const negation = "!"
215247const slash = "/"
@@ -235,24 +267,28 @@ func parseIgnoreRuleToGlobs(rule string, filePath string) (globs []string) {
235267// case `/foo/`, `/foo` => `{baseDir}/foo/**`
236268// case `**/foo/`, `**/foo` => `{baseDir}/**/foo/**`
237269if ! endingGlobstar {
238- globs = append (globs ,filepath .ToSlash (prefix + filepath .Join (baseDir ,rule ,all )))
270+ glob := filepath .ToSlash (prefix + filepath .Join (baseDir ,rule ,all ))
271+ globs = append (globs ,escapeSpecialGlobChars (glob ))
239272}
240273// case `/foo` => `{baseDir}/foo`
241274// case `**/foo` => `{baseDir}/**/foo`
242275// case `/foo/**` => `{baseDir}/foo/**`
243276// case `**/foo/**` => `{baseDir}/**/foo/**`
244277if ! endingSlash {
245- globs = append (globs ,filepath .ToSlash (prefix + filepath .Join (baseDir ,rule )))
278+ glob := filepath .ToSlash (prefix + filepath .Join (baseDir ,rule ))
279+ globs = append (globs ,escapeSpecialGlobChars (glob ))
246280}
247281}else {
248282// case `foo/`, `foo` => `{baseDir}/**/foo/**`
249283if ! endingGlobstar {
250- globs = append (globs ,filepath .ToSlash (prefix + filepath .Join (baseDir ,all ,rule ,all )))
284+ glob := filepath .ToSlash (prefix + filepath .Join (baseDir ,all ,rule ,all ))
285+ globs = append (globs ,escapeSpecialGlobChars (glob ))
251286}
252287// case `foo` => `{baseDir}/**/foo`
253288// case `foo/**` => `{baseDir}/**/foo/**`
254289if ! endingSlash {
255- globs = append (globs ,filepath .ToSlash (prefix + filepath .Join (baseDir ,all ,rule )))
290+ glob := filepath .ToSlash (prefix + filepath .Join (baseDir ,all ,rule ))
291+ globs = append (globs ,escapeSpecialGlobChars (glob ))
256292}
257293}
258294return globs