github.com/anchore/syft@v1.38.2/syft/license/license.go (about) 1 // package license provides common methods for working with SPDX license data 2 package license 3 4 import ( 5 "fmt" 6 "runtime/debug" 7 "strings" 8 9 "github.com/github/go-spdx/v2/spdxexp" 10 11 "github.com/anchore/syft/internal/spdxlicense" 12 ) 13 14 type Type string 15 16 const ( 17 Declared Type = "declared" 18 Concluded Type = "concluded" 19 ) 20 21 // trimFileSuffix removes common file extensions from the end of a string 22 func trimFileSuffix(s string) string { 23 suffixes := []string{".txt", ".pdf", ".html", ".htm", ".md", ".markdown", ".rst", ".doc", ".docx", ".rtf", ".tex", ".xml", ".json"} 24 lower := strings.ToLower(s) 25 for _, suffix := range suffixes { 26 if strings.HasSuffix(lower, suffix) { 27 return s[:len(s)-len(suffix)] 28 } 29 } 30 return s 31 } 32 33 func ParseExpression(expression string) (ex string, err error) { 34 // https://github.com/anchore/syft/issues/1837 35 // The current spdx library can panic when parsing some expressions 36 // This is a temporary fix to recover and patch until we can investigate and contribute 37 // a fix to the upstream github library 38 defer func() { 39 if r := recover(); r != nil { 40 err = fmt.Errorf("recovered from panic while parsing license expression at: \n%s", string(debug.Stack())) 41 } 42 }() 43 44 // Try with the original expression first 45 licenseID, exists := spdxlicense.ID(expression) 46 if exists { 47 return licenseID, nil 48 } 49 50 // Check if the expression is a URL and try to look it up 51 if info, found := spdxlicense.LicenseByURL(expression); found { 52 return info.ID, nil 53 } 54 55 // Try with trimmed file suffix 56 trimmed := trimFileSuffix(expression) 57 if trimmed != expression { 58 // Try as a URL with the trimmed version 59 if info, found := spdxlicense.LicenseByURL(trimmed); found { 60 return info.ID, nil 61 } 62 } 63 64 // If it doesn't exist initially in the SPDX list it might be a more complex expression 65 // ignored variable is any invalid expressions 66 // TODO: contribute to spdxexp to expose deprecated license IDs 67 // https://github.com/anchore/syft/issues/1814 68 valid, _ := spdxexp.ValidateLicenses([]string{expression}) 69 if !valid { 70 return "", fmt.Errorf("invalid SPDX expression: %s", expression) 71 } 72 73 return expression, nil 74 }