diff --git a/changes/17170-hyphen-delimiter b/changes/17170-hyphen-delimiter new file mode 100644 index 0000000000..032612fc97 --- /dev/null +++ b/changes/17170-hyphen-delimiter @@ -0,0 +1 @@ +- fixed issue where resolved_in_version was not returning if the version number differed by a 4th part \ No newline at end of file diff --git a/server/vulnerabilities/nvd/cve.go b/server/vulnerabilities/nvd/cve.go index 906c3b7485..f7bc5fa49c 100644 --- a/server/vulnerabilities/nvd/cve.go +++ b/server/vulnerabilities/nvd/cve.go @@ -718,29 +718,36 @@ func buildConstraintString(startIncluding, startExcluding, endExcluding string) } // Products using 4 part versioning scheme (ie. docker desktop) -// need to be converted to 3 part versioning scheme (2.3.0.2 -> 2.3.0+3) for use with +// need to be converted to 3 part versioning scheme (2.3.0.2 -> 2.3.0-3) for use with // the semver library. func preprocessVersion(version string) string { - // If "+" is already present, validate the part before "+" as a semver - if strings.Contains(version, "+") { - parts := strings.Split(version, "+") + // If "-" is already present, validate the part before "-" as a semver + if strings.Contains(version, "-") { + parts := strings.Split(version, "-") if semverPattern.MatchString(parts[0]) { return version } } + if strings.Contains(version, "+") { + part := strings.Split(version, "+")[0] + if semverPattern.MatchString(part) { + return version + } + } + // If the version string contains more than 3 parts, convert it to 3 parts parts := strings.Split(version, ".") if len(parts) > 3 { - return parts[0] + "." + parts[1] + "." + parts[2] + "+" + strings.Join(parts[3:], ".") + return parts[0] + "." + parts[1] + "." + parts[2] + "-" + strings.Join(parts[3:], ".") } // If the version string ends with a non-numeric character (like '1.0.0b'), replace - // it with '+' (like '1.0.0+b') + // it with '-' (like '1.0.0-b') if len(parts) == 3 { matches := nonNumericPartRegex.FindStringSubmatch(parts[2]) if len(matches) > 2 { - parts[2] = matches[1] + "+" + matches[2] + parts[2] = matches[1] + "-" + matches[2] } } diff --git a/server/vulnerabilities/nvd/cve_test.go b/server/vulnerabilities/nvd/cve_test.go index 0123d1835d..7d398f035a 100644 --- a/server/vulnerabilities/nvd/cve_test.go +++ b/server/vulnerabilities/nvd/cve_test.go @@ -635,6 +635,17 @@ func TestGetMatchingVersionEndExcluding(t *testing.T) { want: "", wantErr: false, }, + { + name: "Can compare 4th version part", + cve: "CVE-2022-45889", + meta: &wfn.Attributes{ + Vendor: "planetestream", + Product: "planet_estream", + Version: "6.72.10.06", + }, + want: "6.72.10.07", + wantErr: false, + }, } for _, tt := range tests { @@ -645,7 +656,7 @@ func TestGetMatchingVersionEndExcluding(t *testing.T) { return } if got != tt.want { - t.Errorf("getMatchingVersionEndExcluding() = %v, want %v", got, tt.want) + t.Errorf("got %q, want %q", got, tt.want) } }) } @@ -656,23 +667,24 @@ func TestPreprocessVersion(t *testing.T) { input string expected string }{ - {"2.3.0.2", "2.3.0+2"}, + {"2.3.0.2", "2.3.0-2"}, {"2.3.0+2", "2.3.0+2"}, - {"v2.3.0+2", "v2.3.0+2"}, - {"2.3.0.2.5", "2.3.0+2.5"}, + {"v5.3.0.2", "v5.3.0-2"}, + {"5.3.0-2", "5.3.0-2"}, + {"2.3.0.2.5", "2.3.0-2.5"}, {"2.3.0", "2.3.0"}, {"2.3", "2.3"}, {"v2.3.0", "v2.3.0"}, {"notAVersion", "notAVersion"}, {"2.0.0+svn315-7fakesync1ubuntu0.22.04.1", "2.0.0+svn315-7fakesync1ubuntu0.22.04.1"}, - {"1.21.1ubuntu2", "1.21.1+ubuntu2"}, + {"1.21.1ubuntu2", "1.21.1-ubuntu2"}, } for _, tc := range testCases { t.Run(tc.input, func(t *testing.T) { output := preprocessVersion(tc.input) if output != tc.expected { - t.Fatalf("expected: %s, got: %s", tc.expected, output) + t.Fatalf("input: %s, expected: %s, got: %s", tc.input, tc.expected, output) } }) }