| // 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...) + `)$`) | |
| } |