internal/report: handle more cases for CVE version parsing

Adds special-case handling for some strange version encoding
methods seen in the wild in CVEs. This will make CVE ingestion
more automatic.

Change-Id: I09907f36b365f302c1be06a93e039ec24ed56297
Reviewed-on: https://go-review.googlesource.com/c/vulndb/+/577000
Reviewed-by: Damien Neil <dneil@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
diff --git a/internal/report/cve.go b/internal/report/cve.go
index 4850200..6f2050e 100644
--- a/internal/report/cve.go
+++ b/internal/report/cve.go
@@ -250,8 +250,33 @@
 	return vs, uvs
 }
 
+var (
+	// Regex for matching version strings like "<= X, < Y".
+	introducedFixedRE = regexp.MustCompile(`^>= (.+), < (.+)$`)
+	// Regex for matching version strings like "< Y".
+	fixedRE = regexp.MustCompile(`^< (.+)$`)
+)
+
 func toVersionRange(cvr *cveschema5.VersionRange, defaultStatus cveschema5.VersionStatus) (*VersionRange, bool) {
-	// For now, we only support version ranges that are easy to convert to our format.
+	// Handle special cases where the info is not quite correctly encoded but
+	// we can still figure out the intent.
+
+	// Case one: introduced version is of the form "<= X, < Y".
+	if m := introducedFixedRE.FindStringSubmatch(string(cvr.Introduced)); len(m) == 3 {
+		return &VersionRange{
+			Introduced: m[1],
+			Fixed:      m[2],
+		}, true
+	}
+
+	// Case two: introduced version is of the form "< Y".
+	if m := fixedRE.FindStringSubmatch(string(cvr.Introduced)); len(m) == 2 {
+		return &VersionRange{
+			Fixed: m[1],
+		}, true
+	}
+
+	// For now, don't attempt to fix any other messed up cases.
 	if cvr.VersionType != typeSemver ||
 		cvr.LessThanOrEqual != "" ||
 		!version.IsValid(string(cvr.Introduced)) ||
diff --git a/internal/report/testdata/cve/TestCVE5ToReport/CVE-2022-39213.txtar b/internal/report/testdata/cve/TestCVE5ToReport/CVE-2022-39213.txtar
index 1534e17..c301030 100644
--- a/internal/report/testdata/cve/TestCVE5ToReport/CVE-2022-39213.txtar
+++ b/internal/report/testdata/cve/TestCVE5ToReport/CVE-2022-39213.txtar
@@ -8,9 +8,9 @@
 id: PLACEHOLDER-ID
 modules:
     - module: github.com/pandatix/go-cvss
-      unsupported_versions:
-        - version: affected at >= 0.2.0, < 0.4.0
-          type: cve_version_range
+      versions:
+        - introduced: 0.2.0
+          fixed: 0.4.0
       packages:
         - package: github.com/pandatix/go-cvss
 summary: Out-of-bounds Read in go-cvss
diff --git a/internal/report/testdata/cve/TestCVE5ToReport/CVE-2023-44378.txtar b/internal/report/testdata/cve/TestCVE5ToReport/CVE-2023-44378.txtar
index 6a11881..11efcfa 100644
--- a/internal/report/testdata/cve/TestCVE5ToReport/CVE-2023-44378.txtar
+++ b/internal/report/testdata/cve/TestCVE5ToReport/CVE-2023-44378.txtar
@@ -8,9 +8,8 @@
 id: PLACEHOLDER-ID
 modules:
     - module: github.com/Consensys/gnark
-      unsupported_versions:
-        - version: affected at < 0.9.0
-          type: cve_version_range
+      versions:
+        - fixed: 0.9.0
       packages:
         - package: github.com/Consensys/gnark
 summary: gnark vulnerable to unsoundness in variable comparison/non-unique binary decomposition
diff --git a/internal/report/testdata/cve/TestCVE5ToReport/CVE-2023-45141.txtar b/internal/report/testdata/cve/TestCVE5ToReport/CVE-2023-45141.txtar
index 10f3840..22cb878 100644
--- a/internal/report/testdata/cve/TestCVE5ToReport/CVE-2023-45141.txtar
+++ b/internal/report/testdata/cve/TestCVE5ToReport/CVE-2023-45141.txtar
@@ -8,9 +8,8 @@
 id: PLACEHOLDER-ID
 modules:
     - module: github.com/gofiber/fiber
-      unsupported_versions:
-        - version: affected at < 2.50.0
-          type: cve_version_range
+      versions:
+        - fixed: 2.50.0
       packages:
         - package: github.com/gofiber/fiber
 summary: CSRF Token Validation Vulnerability in fiber