blob: 8ca52c40c5759f657f12007552fe41de01350455 [file] [log] [blame]
// Copyright 2024 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package idstr
import (
"regexp"
"strings"
)
var (
nistPrefix = "https://nvd.nist.gov/vuln/detail/"
mitrePrefixMatch = "https://.*cve.*org/.*"
ghsaGlobalPrefix = "https://github.com/advisories/"
ghsaRepoPrefixMatch = "https://github.com/.+/advisories/"
godevPrefix = "https://pkg.go.dev/vuln/"
cveLink = strictRE(oneOf(mitrePrefixMatch, nistPrefix), cveStr)
ghsaLink = strictRE(oneOf(ghsaGlobalPrefix, ghsaRepoPrefixMatch), ghsaStr)
ghsaGlobalLink = strictRE(ghsaGlobalPrefix, ghsaStr)
ghsaRepoLink = strictRE(ghsaRepoPrefixMatch, ghsaStr)
goAdvisoryLink = strictRE(godevPrefix, goIDStr)
)
var (
advisoryPrefixes = []string{nistPrefix, mitrePrefixMatch, ghsaGlobalPrefix, ghsaRepoPrefixMatch, godevPrefix}
advisoryREs = []*regexp.Regexp{cveLink, ghsaLink, goAdvisoryLink}
)
func IsGoAdvisory(u string) bool {
return goAdvisoryLink.MatchString(u)
}
func GoAdvisory(id string) string {
return godevPrefix + id
}
func IsAdvisory(u string) bool {
for _, re := range advisoryREs {
if re.MatchString(u) {
return true
}
}
return false
}
func IsAdvisoryFor(u, alias string) bool {
_, is := IsAdvisoryForOneOf(u, []string{alias})
return is
}
func IsAdvisoryForOneOf(u string, aliases []string) (string, bool) {
for _, prefix := range advisoryPrefixes {
re := strictRE(prefix, aliases...)
if m := re.FindStringSubmatch(u); len(m) == 2 {
return m[1], true
}
}
return "", false
}
func AdvisoryLink(id string) string {
switch {
case IsCVE(id):
return nistPrefix + id
case IsGHSA(id):
return ghsaGlobalPrefix + id
case IsGoID(id):
return GoAdvisory(id)
default:
return ""
}
}
func IsCVELink(u string) bool {
return cveLink.MatchString(u)
}
func IsGHSAGlobalLink(u string) bool {
return ghsaGlobalLink.MatchString(u)
}
func IsGHSARepoLink(u string) bool {
return ghsaRepoLink.MatchString(u)
}
func oneOf(strs ...string) string {
return strings.Join(strs, `|`)
}
func strictRE(prefix string, ids ...string) *regexp.Regexp {
return regexp.MustCompile(`^` + prefix + `(` + oneOf(ids...) + `)$`)
}