Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 23 additions & 20 deletions vulnfeeds/cves/versions.go
Original file line number Diff line number Diff line change
Expand Up @@ -515,44 +515,47 @@ func ValidateAndCanonicalizeLink(link string, httpClient *http.Client) (canonica
}

// For URLs referencing commits in supported Git repository hosts, return a cloneable AffectedCommit.
func ExtractGitCommit(link string, commitType models.CommitType, httpClient *http.Client) (ac models.AffectedCommit, err error) {
r, err := Repo(link)
func ExtractGitAffectedCommit(link string, commitType models.CommitType, httpClient *http.Client) (ac models.AffectedCommit, err error) {
c, r, err := ExtractGitCommit(link, httpClient)
if err != nil {
return ac, err
}

ac.SetRepo(r)

models.SetCommitByType(&ac, commitType, c)

return ac, nil
}

func ExtractGitCommit(link string, httpClient *http.Client) (string, string, error) {
var commit string
r, err := Repo(link)
if err != nil {
return "", "", err
}

c, err := Commit(link)
if err != nil {
return ac, err
return "", "", err
}

commit = c

// If URL doesn't validate, treat it as linkrot.
possiblyDifferentLink, err := ValidateAndCanonicalizeLink(link, httpClient)
if err != nil {
return ac, err
return "", "", err
}

// restart the entire extraction process when the URL changes (i.e. handle a
// redirect to a completely different host, instead of a redirect within
// GitHub)
if possiblyDifferentLink != link {
return ExtractGitCommit(possiblyDifferentLink, commitType, httpClient)
return ExtractGitCommit(possiblyDifferentLink, httpClient)
}

ac.SetRepo(r)

switch commitType {
case models.Introduced:
ac.SetIntroduced(c)
case models.LastAffected:
ac.SetLastAffected(c)
case models.Limit:
ac.SetLimit(c)
case models.Fixed:
ac.SetFixed(c)
}

return ac, nil
return commit, r, nil
}

func HasVersion(validVersions []string, version string) bool {
Expand Down Expand Up @@ -676,7 +679,7 @@ func deduplicateAffectedCommits(commits []models.AffectedCommit) []models.Affect
func ExtractVersionInfo(cve CVE, validVersions []string, httpClient *http.Client) (v models.VersionInfo, notes []string) {
for _, reference := range cve.References {
// (Potentially faulty) Assumption: All viable Git commit reference links are fix commits.
if commit, err := ExtractGitCommit(reference.URL, models.Fixed, httpClient); err == nil {
if commit, err := ExtractGitAffectedCommit(reference.URL, models.Fixed, httpClient); err == nil {
v.AffectedCommits = append(v.AffectedCommits, commit)
}
}
Expand Down
2 changes: 1 addition & 1 deletion vulnfeeds/cves/versions_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -691,7 +691,7 @@ func TestExtractGitCommit(t *testing.T) {
if !tc.disableExpiryDate.IsZero() && time.Now().After(tc.disableExpiryDate) {
t.Logf("test %q: extractGitCommit(%q, %q) has been enabled on %s.", tc.description, tc.inputLink, tc.inputCommitType, tc.disableExpiryDate)
}
got, err := ExtractGitCommit(tc.inputLink, tc.inputCommitType, client)
got, err := ExtractGitAffectedCommit(tc.inputLink, tc.inputCommitType, client)
if err != nil && !tc.expectFailure {
t.Errorf("test %q: extractGitCommit for %q (%q) errored unexpectedly: %#v", tc.description, tc.inputLink, tc.inputCommitType, err)
}
Expand Down
16 changes: 1 addition & 15 deletions vulnfeeds/git/versions.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,6 @@ import (

var versionRangeRegex = regexp.MustCompile(`^(>=|<=|~|\^|>|<|=)\s*([0-9a-zA-Z\.\-]+)(?:,\s*(>=|<=|~|\^|>|<|=)\s*([0-9a-zA-Z\.\-]+))?$`) // Used to parse version strings from the GitHub CNA.

// setCommitByType sets the appropriate commit field on an AffectedCommit based on the CommitType.
func setCommitByType(ac *models.AffectedCommit, commitType models.CommitType, commitHash string) {
switch commitType {
case models.Introduced:
ac.SetIntroduced(commitHash)
case models.LastAffected:
ac.SetLastAffected(commitHash)
case models.Limit:
ac.SetLimit(commitHash)
case models.Fixed:
ac.SetFixed(commitHash)
}
}

// findFuzzyCommit takes an already normalized version and the mapping of repo tags to
// normalized tags and commits, and performs fuzzy matching to find a commit hash.
func findFuzzyCommit(normalizedVersion string, normalizedTags map[string]NormalizedTag) (string, bool) {
Expand Down Expand Up @@ -87,7 +73,7 @@ func VersionToAffectedCommit(version string, repo string, commitType models.Comm
return ac, err
}
ac.SetRepo(repo)
setCommitByType(&ac, commitType, commitHash)
models.SetCommitByType(&ac, commitType, commitHash)

return ac, nil
}
Expand Down
14 changes: 14 additions & 0 deletions vulnfeeds/models/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,20 @@ type AffectedCommit struct {
LastAffected string `json:"last_affected,omitempty" yaml:"last_affected,omitempty"`
}

// SetCommitByType sets the appropriate commit field on an AffectedCommit based on the CommitType.
func SetCommitByType(ac *AffectedCommit, commitType CommitType, commitHash string) {
switch commitType {
case Introduced:
ac.SetIntroduced(commitHash)
case LastAffected:
ac.SetLastAffected(commitHash)
case Limit:
ac.SetLimit(commitHash)
case Fixed:
ac.SetFixed(commitHash)
}
}

func (ac *AffectedCommit) SetRepo(repo string) {
// GitHub.com repos are demonstrably case-insensitive, and frequently
// expressed in URLs with varying cases, so normalize them to lowercase.
Expand Down
Loading