internal/report: add golden file tests for cveToReport v4

Change-Id: I1003cc10ca28f4e4a25f22c5e0756550b372d533
Reviewed-on: https://go-review.googlesource.com/c/vulndb/+/547555
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Damien Neil <dneil@google.com>
diff --git a/internal/report/cve_test.go b/internal/report/cve_test.go
new file mode 100644
index 0000000..add607e
--- /dev/null
+++ b/internal/report/cve_test.go
@@ -0,0 +1,143 @@
+// Copyright 2023 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 report
+
+import (
+	"context"
+	"flag"
+	"fmt"
+	"os"
+	"path/filepath"
+	"testing"
+
+	"github.com/google/go-cmp/cmp"
+	"golang.org/x/exp/maps"
+	"golang.org/x/tools/txtar"
+	"golang.org/x/vulndb/internal/cvelistrepo"
+	"golang.org/x/vulndb/internal/cveschema"
+	"golang.org/x/vulndb/internal/cveschema5"
+	"golang.org/x/vulndb/internal/gitrepo"
+	"golang.org/x/vulndb/internal/test"
+	"gopkg.in/yaml.v3"
+)
+
+var (
+	updateGolden     = flag.Bool("update", false, "update golden files")
+	updateTxtarRepos = flag.Bool("update-repo", false, "update the test repos ({v4,v5}.txtar) with real CVE data - this takes a while")
+)
+
+var (
+	testdata = filepath.Join("testdata", "cve")
+	v4txtar  = filepath.Join(testdata, "v4.txtar")
+	v5txtar  = filepath.Join(testdata, "v5.txtar")
+	testCVEs = map[string]string{
+		"CVE-2020-9283":  "golang.org/x/crypto",
+		"CVE-2022-39213": "github.com/pandatix/go-cvss",
+		"CVE-2023-44378": "github.com/Consensys/gnark",
+		"CVE-2023-45141": "github.com/gofiber/fiber",
+	}
+)
+
+func TestMain(m *testing.M) {
+	flag.Parse()
+	if *updateTxtarRepos {
+		ctx := context.Background()
+		ids := maps.Keys(testCVEs)
+		if err := cvelistrepo.WriteTxtarRepo(ctx, cvelistrepo.URLv4, v4txtar, ids); err != nil {
+			fail(err)
+		}
+		if err := cvelistrepo.WriteTxtarRepo(ctx, cvelistrepo.URLv5, v5txtar, ids); err != nil {
+			fail(err)
+		}
+	}
+	os.Exit(m.Run())
+}
+
+func fail(err error) {
+	fmt.Fprintln(os.Stderr, err)
+	os.Exit(1)
+}
+
+const placeholderID = "PLACEHOLDER-ID"
+
+func TestCVEToReport(t *testing.T) {
+	newV4 := func() cvelistrepo.CVE {
+		return new(cveschema.CVE)
+	}
+	toReportV4 := func(cve cvelistrepo.CVE, modulePath string) *Report {
+		return cveToReport(cve.(*cveschema.CVE), placeholderID, modulePath)
+	}
+	if err := run(t, v4txtar, newV4, toReportV4); err != nil {
+		t.Fatal(err)
+	}
+}
+
+func run(t *testing.T, txtarFile string, newCVE func() cvelistrepo.CVE, toReport func(cvelistrepo.CVE, string) *Report) error {
+	if *updateGolden {
+		if err := os.RemoveAll(filepath.Join(testdata, t.Name())); err != nil {
+			t.Fatal(err)
+		}
+	}
+
+	repo, commit, err := gitrepo.TxtarRepoAndHead(txtarFile)
+	if err != nil {
+		return err
+	}
+	files, err := cvelistrepo.Files(repo, commit)
+	if err != nil {
+		return err
+	}
+
+	for _, file := range files {
+		id := cveschema5.FindCVE(file.Filename)
+		t.Run(id, func(t *testing.T) {
+			cve := newCVE()
+			if err := cvelistrepo.Parse(repo, file, cve); err != nil {
+				t.Fatalf("Parse(%s)=%s", id, err)
+			}
+
+			mp, ok := testCVEs[id]
+			if !ok {
+				t.Fatalf("%s not found in testCVEs", id)
+			}
+
+			b, err := yaml.Marshal(toReport(cve, mp))
+			if err != nil {
+				t.Fatal(err)
+			}
+
+			tf := filepath.Join(testdata, t.Name()+".txtar")
+
+			if *updateGolden {
+				if err := test.WriteTxtar(tf, []txtar.File{
+					{
+						Name: id,
+						Data: b,
+					},
+				}, fmt.Sprintf("Expected output of %s.", t.Name())); err != nil {
+					t.Fatal(err)
+				}
+			}
+
+			ar, err := txtar.ParseFile(tf)
+			if err != nil {
+				t.Fatal(err)
+			}
+
+			for _, af := range ar.Files {
+				if af.Name != id {
+					t.Errorf("unexpected archive file %s", af.Name)
+					continue
+				}
+				want, got := string(b), string(af.Data)
+				if diff := cmp.Diff(want, got); diff != "" {
+					t.Errorf("%s content mismatch (-want, +got):\n%s", af.Name, diff)
+				}
+			}
+		})
+	}
+
+	return nil
+}
diff --git a/internal/report/testdata/cve/TestCVEToReport/CVE-2020-9283.txtar b/internal/report/testdata/cve/TestCVEToReport/CVE-2020-9283.txtar
new file mode 100644
index 0000000..901b9be
--- /dev/null
+++ b/internal/report/testdata/cve/TestCVEToReport/CVE-2020-9283.txtar
@@ -0,0 +1,24 @@
+Copyright 2023 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.
+
+Expected output of TestCVEToReport/CVE-2020-9283.
+
+-- CVE-2020-9283 --
+id: PLACEHOLDER-ID
+modules:
+    - module: golang.org/x/crypto
+      packages:
+        - package: n/a
+description: |
+    golang.org/x/crypto before v0.0.0-20200220183623-bac4c82f6975 for Go allows a panic during signature verification in the golang.org/x/crypto/ssh package. A client can attack an SSH server that accepts public keys. Also, a server can attack any SSH client.
+references:
+    - web: https://groups.google.com/forum/#!topic/golang-announce/3L45YRc91SY
+    - web: http://packetstormsecurity.com/files/156480/Go-SSH-0.0.2-Denial-Of-Service.html
+    - web: https://lists.debian.org/debian-lts-announce/2020/10/msg00014.html
+    - web: https://lists.debian.org/debian-lts-announce/2020/11/msg00027.html
+    - web: https://lists.debian.org/debian-lts-announce/2020/11/msg00031.html
+    - web: https://lists.debian.org/debian-lts-announce/2023/06/msg00017.html
+cve_metadata:
+    id: CVE-2020-9283
+    cwe: TODO
diff --git a/internal/report/testdata/cve/TestCVEToReport/CVE-2022-39213.txtar b/internal/report/testdata/cve/TestCVEToReport/CVE-2022-39213.txtar
new file mode 100644
index 0000000..0b76b1c
--- /dev/null
+++ b/internal/report/testdata/cve/TestCVEToReport/CVE-2022-39213.txtar
@@ -0,0 +1,20 @@
+Copyright 2023 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.
+
+Expected output of TestCVEToReport/CVE-2022-39213.
+
+-- CVE-2022-39213 --
+id: PLACEHOLDER-ID
+modules:
+    - module: github.com/pandatix/go-cvss
+      packages:
+        - package: go-cvss
+description: |
+    go-cvss is a Go module to manipulate Common Vulnerability Scoring System (CVSS). In affected versions when a full CVSS v2.0 vector string is parsed using `ParseVector`, an Out-of-Bounds Read is possible due to a lack of tests. The Go module will then panic. The problem is patched in tag `v0.4.0`, by the commit `d9d478ff0c13b8b09ace030db9262f3c2fe031f4`. Users are advised to upgrade. Users unable to upgrade may avoid this issue by parsing only CVSS v2.0 vector strings that do not have all attributes defined (e.g. `AV:N/AC:L/Au:N/C:P/I:P/A:C/E:U/RL:OF/RC:C/CDP:MH/TD:H/CR:M/IR:M/AR:M`). As stated in [SECURITY.md](https://github.com/pandatix/go-cvss/blob/master/SECURITY.md), the CPE v2.3 to refer to this Go module is `cpe:2.3:a:pandatix:go_cvss:*:*:*:*:*:*:*:*`. The entry has already been requested to the NVD CPE dictionary.
+cves:
+    - CVE-2022-39213
+references:
+    - advisory: https://github.com/pandatix/go-cvss/security/advisories/GHSA-xhmf-mmv2-4hhx
+    - fix: https://github.com/pandatix/go-cvss/commit/d9d478ff0c13b8b09ace030db9262f3c2fe031f4
+    - web: https://github.com/pandatix/go-cvss/blob/master/SECURITY.md
diff --git a/internal/report/testdata/cve/TestCVEToReport/CVE-2023-44378.txtar b/internal/report/testdata/cve/TestCVEToReport/CVE-2023-44378.txtar
new file mode 100644
index 0000000..f41d093
--- /dev/null
+++ b/internal/report/testdata/cve/TestCVEToReport/CVE-2023-44378.txtar
@@ -0,0 +1,20 @@
+Copyright 2023 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.
+
+Expected output of TestCVEToReport/CVE-2023-44378.
+
+-- CVE-2023-44378 --
+id: PLACEHOLDER-ID
+modules:
+    - module: github.com/Consensys/gnark
+      packages:
+        - package: gnark
+description: |
+    gnark is a zk-SNARK library that offers a high-level API to design circuits. Prior to version 0.9.0, for some in-circuit values, it is possible to construct two valid decomposition to bits. In addition to the canonical decomposition of `a`, for small values there exists a second decomposition for `a+r` (where `r` is the modulus the values are being reduced by). The second decomposition was possible due to overflowing the field where the values are defined. Upgrading to version 0.9.0 should fix the issue without needing to change the calls to value comparison methods.
+cves:
+    - CVE-2023-44378
+references:
+    - advisory: https://github.com/Consensys/gnark/security/advisories/GHSA-498w-5j49-vqjg
+    - report: https://github.com/zkopru-network/zkopru/issues/116
+    - fix: https://github.com/Consensys/gnark/commit/59a4087261a6c73f13e80d695c17b398c3d0934f
diff --git a/internal/report/testdata/cve/TestCVEToReport/CVE-2023-45141.txtar b/internal/report/testdata/cve/TestCVEToReport/CVE-2023-45141.txtar
new file mode 100644
index 0000000..39b25db
--- /dev/null
+++ b/internal/report/testdata/cve/TestCVEToReport/CVE-2023-45141.txtar
@@ -0,0 +1,18 @@
+Copyright 2023 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.
+
+Expected output of TestCVEToReport/CVE-2023-45141.
+
+-- CVE-2023-45141 --
+id: PLACEHOLDER-ID
+modules:
+    - module: github.com/gofiber/fiber
+      packages:
+        - package: fiber
+description: |
+    Fiber is an express inspired web framework written in Go. A Cross-Site Request Forgery (CSRF) vulnerability has been identified in the application, which allows an attacker to obtain tokens and forge malicious requests on behalf of a user. This can lead to unauthorized actions being taken on the user's behalf, potentially compromising the security and integrity of the application. The vulnerability is caused by improper validation and enforcement of CSRF tokens within the application. This vulnerability has been addressed in version 2.50.0 and users are advised to upgrade. Users should take additional security measures like captchas or Two-Factor Authentication (2FA) and set Session cookies with SameSite=Lax or SameSite=Secure, and the Secure and HttpOnly attributes.
+cves:
+    - CVE-2023-45141
+references:
+    - advisory: https://github.com/gofiber/fiber/security/advisories/GHSA-mv73-f69x-444p
diff --git a/internal/report/testdata/cve/v4.txtar b/internal/report/testdata/cve/v4.txtar
new file mode 100644
index 0000000..c1e9fb9
--- /dev/null
+++ b/internal/report/testdata/cve/v4.txtar
@@ -0,0 +1,395 @@
+Copyright 2023 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.
+
+Repo in the shape of "https://github.com/CVEProject/cvelist".
+Updated with real data 2023-12-05T19:00:00-05:00.
+Auto-generated; do not edit directly.
+
+-- README.md --
+ignore me please
+
+-- 2022/39xxx/CVE-2022-39213.json --
+{
+    "CVE_data_meta": {
+        "ASSIGNER": "security-advisories@github.com",
+        "ID": "CVE-2022-39213",
+        "STATE": "PUBLIC",
+        "TITLE": "Out-of-bounds Read in go-cvss"
+    },
+    "affects": {
+        "vendor": {
+            "vendor_data": [
+                {
+                    "product": {
+                        "product_data": [
+                            {
+                                "product_name": "go-cvss",
+                                "version": {
+                                    "version_data": [
+                                        {
+                                            "version_value": ">= 0.2.0, < 0.4.0"
+                                        }
+                                    ]
+                                }
+                            }
+                        ]
+                    },
+                    "vendor_name": "pandatix"
+                }
+            ]
+        }
+    },
+    "data_format": "MITRE",
+    "data_type": "CVE",
+    "data_version": "4.0",
+    "description": {
+        "description_data": [
+            {
+                "lang": "eng",
+                "value": "go-cvss is a Go module to manipulate Common Vulnerability Scoring System (CVSS). In affected versions when a full CVSS v2.0 vector string is parsed using `ParseVector`, an Out-of-Bounds Read is possible due to a lack of tests. The Go module will then panic. The problem is patched in tag `v0.4.0`, by the commit `d9d478ff0c13b8b09ace030db9262f3c2fe031f4`. Users are advised to upgrade. Users unable to upgrade may avoid this issue by parsing only CVSS v2.0 vector strings that do not have all attributes defined (e.g. `AV:N/AC:L/Au:N/C:P/I:P/A:C/E:U/RL:OF/RC:C/CDP:MH/TD:H/CR:M/IR:M/AR:M`). As stated in [SECURITY.md](https://github.com/pandatix/go-cvss/blob/master/SECURITY.md), the CPE v2.3 to refer to this Go module is `cpe:2.3:a:pandatix:go_cvss:*:*:*:*:*:*:*:*`. The entry has already been requested to the NVD CPE dictionary."
+            }
+        ]
+    },
+    "impact": {
+        "cvss": {
+            "attackComplexity": "LOW",
+            "attackVector": "NETWORK",
+            "availabilityImpact": "HIGH",
+            "baseScore": 7.5,
+            "baseSeverity": "HIGH",
+            "confidentialityImpact": "NONE",
+            "integrityImpact": "NONE",
+            "privilegesRequired": "NONE",
+            "scope": "UNCHANGED",
+            "userInteraction": "NONE",
+            "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
+            "version": "3.1"
+        }
+    },
+    "problemtype": {
+        "problemtype_data": [
+            {
+                "description": [
+                    {
+                        "lang": "eng",
+                        "value": "CWE-125: Out-of-bounds Read"
+                    }
+                ]
+            }
+        ]
+    },
+    "references": {
+        "reference_data": [
+            {
+                "name": "https://github.com/pandatix/go-cvss/security/advisories/GHSA-xhmf-mmv2-4hhx",
+                "refsource": "CONFIRM",
+                "url": "https://github.com/pandatix/go-cvss/security/advisories/GHSA-xhmf-mmv2-4hhx"
+            },
+            {
+                "name": "https://github.com/pandatix/go-cvss/commit/d9d478ff0c13b8b09ace030db9262f3c2fe031f4",
+                "refsource": "MISC",
+                "url": "https://github.com/pandatix/go-cvss/commit/d9d478ff0c13b8b09ace030db9262f3c2fe031f4"
+            },
+            {
+                "name": "https://github.com/pandatix/go-cvss/blob/master/SECURITY.md",
+                "refsource": "MISC",
+                "url": "https://github.com/pandatix/go-cvss/blob/master/SECURITY.md"
+            }
+        ]
+    },
+    "source": {
+        "advisory": "GHSA-xhmf-mmv2-4hhx",
+        "discovery": "UNKNOWN"
+    }
+}
+-- 2023/44xxx/CVE-2023-44378.json --
+{
+    "data_version": "4.0",
+    "data_type": "CVE",
+    "data_format": "MITRE",
+    "CVE_data_meta": {
+        "ID": "CVE-2023-44378",
+        "ASSIGNER": "security-advisories@github.com",
+        "STATE": "PUBLIC"
+    },
+    "description": {
+        "description_data": [
+            {
+                "lang": "eng",
+                "value": "gnark is a zk-SNARK library that offers a high-level API to design circuits. Prior to version 0.9.0, for some in-circuit values, it is possible to construct two valid decomposition to bits. In addition to the canonical decomposition of `a`, for small values there exists a second decomposition for `a+r` (where `r` is the modulus the values are being reduced by). The second decomposition was possible due to overflowing the field where the values are defined. Upgrading to version 0.9.0 should fix the issue without needing to change the calls to value comparison methods."
+            }
+        ]
+    },
+    "problemtype": {
+        "problemtype_data": [
+            {
+                "description": [
+                    {
+                        "lang": "eng",
+                        "value": "CWE-191: Integer Underflow (Wrap or Wraparound)",
+                        "cweId": "CWE-191"
+                    }
+                ]
+            },
+            {
+                "description": [
+                    {
+                        "lang": "eng",
+                        "value": "CWE-697: Incorrect Comparison",
+                        "cweId": "CWE-697"
+                    }
+                ]
+            }
+        ]
+    },
+    "affects": {
+        "vendor": {
+            "vendor_data": [
+                {
+                    "vendor_name": "Consensys",
+                    "product": {
+                        "product_data": [
+                            {
+                                "product_name": "gnark",
+                                "version": {
+                                    "version_data": [
+                                        {
+                                            "version_affected": "=",
+                                            "version_value": "< 0.9.0"
+                                        }
+                                    ]
+                                }
+                            }
+                        ]
+                    }
+                }
+            ]
+        }
+    },
+    "references": {
+        "reference_data": [
+            {
+                "url": "https://github.com/Consensys/gnark/security/advisories/GHSA-498w-5j49-vqjg",
+                "refsource": "MISC",
+                "name": "https://github.com/Consensys/gnark/security/advisories/GHSA-498w-5j49-vqjg"
+            },
+            {
+                "url": "https://github.com/zkopru-network/zkopru/issues/116",
+                "refsource": "MISC",
+                "name": "https://github.com/zkopru-network/zkopru/issues/116"
+            },
+            {
+                "url": "https://github.com/Consensys/gnark/commit/59a4087261a6c73f13e80d695c17b398c3d0934f",
+                "refsource": "MISC",
+                "name": "https://github.com/Consensys/gnark/commit/59a4087261a6c73f13e80d695c17b398c3d0934f"
+            }
+        ]
+    },
+    "source": {
+        "advisory": "GHSA-498w-5j49-vqjg",
+        "discovery": "UNKNOWN"
+    },
+    "impact": {
+        "cvss": [
+            {
+                "attackComplexity": "LOW",
+                "attackVector": "LOCAL",
+                "availabilityImpact": "NONE",
+                "baseScore": 7.1,
+                "baseSeverity": "HIGH",
+                "confidentialityImpact": "NONE",
+                "integrityImpact": "HIGH",
+                "privilegesRequired": "NONE",
+                "scope": "CHANGED",
+                "userInteraction": "NONE",
+                "vectorString": "CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:C/C:N/I:H/A:N",
+                "version": "3.1"
+            }
+        ]
+    }
+}
+-- 2023/45xxx/CVE-2023-45141.json --
+{
+    "data_version": "4.0",
+    "data_type": "CVE",
+    "data_format": "MITRE",
+    "CVE_data_meta": {
+        "ID": "CVE-2023-45141",
+        "ASSIGNER": "security-advisories@github.com",
+        "STATE": "PUBLIC"
+    },
+    "description": {
+        "description_data": [
+            {
+                "lang": "eng",
+                "value": "Fiber is an express inspired web framework written in Go. A Cross-Site Request Forgery (CSRF) vulnerability has been identified in the application, which allows an attacker to obtain tokens and forge malicious requests on behalf of a user. This can lead to unauthorized actions being taken on the user's behalf, potentially compromising the security and integrity of the application. The vulnerability is caused by improper validation and enforcement of CSRF tokens within the application. This vulnerability has been addressed in version 2.50.0 and users are advised to upgrade. Users should take additional security measures like captchas or Two-Factor Authentication (2FA) and set Session cookies with SameSite=Lax or SameSite=Secure, and the Secure and HttpOnly attributes."
+            }
+        ]
+    },
+    "problemtype": {
+        "problemtype_data": [
+            {
+                "description": [
+                    {
+                        "lang": "eng",
+                        "value": "CWE-352: Cross-Site Request Forgery (CSRF)",
+                        "cweId": "CWE-352"
+                    }
+                ]
+            },
+            {
+                "description": [
+                    {
+                        "lang": "eng",
+                        "value": "CWE-565: Reliance on Cookies without Validation and Integrity Checking",
+                        "cweId": "CWE-565"
+                    }
+                ]
+            }
+        ]
+    },
+    "affects": {
+        "vendor": {
+            "vendor_data": [
+                {
+                    "vendor_name": "gofiber",
+                    "product": {
+                        "product_data": [
+                            {
+                                "product_name": "fiber",
+                                "version": {
+                                    "version_data": [
+                                        {
+                                            "version_affected": "=",
+                                            "version_value": "< 2.50.0"
+                                        }
+                                    ]
+                                }
+                            }
+                        ]
+                    }
+                }
+            ]
+        }
+    },
+    "references": {
+        "reference_data": [
+            {
+                "url": "https://github.com/gofiber/fiber/security/advisories/GHSA-mv73-f69x-444p",
+                "refsource": "MISC",
+                "name": "https://github.com/gofiber/fiber/security/advisories/GHSA-mv73-f69x-444p"
+            }
+        ]
+    },
+    "source": {
+        "advisory": "GHSA-mv73-f69x-444p",
+        "discovery": "UNKNOWN"
+    },
+    "impact": {
+        "cvss": [
+            {
+                "attackComplexity": "LOW",
+                "attackVector": "NETWORK",
+                "availabilityImpact": "LOW",
+                "baseScore": 8.6,
+                "baseSeverity": "HIGH",
+                "confidentialityImpact": "LOW",
+                "integrityImpact": "HIGH",
+                "privilegesRequired": "NONE",
+                "scope": "UNCHANGED",
+                "userInteraction": "NONE",
+                "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:H/A:L",
+                "version": "3.1"
+            }
+        ]
+    }
+}
+-- 2020/9xxx/CVE-2020-9283.json --
+{
+    "CVE_data_meta": {
+        "ASSIGNER": "cve@mitre.org",
+        "ID": "CVE-2020-9283",
+        "STATE": "PUBLIC"
+    },
+    "affects": {
+        "vendor": {
+            "vendor_data": [
+                {
+                    "product": {
+                        "product_data": [
+                            {
+                                "product_name": "n/a",
+                                "version": {
+                                    "version_data": [
+                                        {
+                                            "version_value": "n/a"
+                                        }
+                                    ]
+                                }
+                            }
+                        ]
+                    },
+                    "vendor_name": "n/a"
+                }
+            ]
+        }
+    },
+    "data_format": "MITRE",
+    "data_type": "CVE",
+    "data_version": "4.0",
+    "description": {
+        "description_data": [
+            {
+                "lang": "eng",
+                "value": "golang.org/x/crypto before v0.0.0-20200220183623-bac4c82f6975 for Go allows a panic during signature verification in the golang.org/x/crypto/ssh package. A client can attack an SSH server that accepts public keys. Also, a server can attack any SSH client."
+            }
+        ]
+    },
+    "problemtype": {
+        "problemtype_data": [
+            {
+                "description": [
+                    {
+                        "lang": "eng",
+                        "value": "n/a"
+                    }
+                ]
+            }
+        ]
+    },
+    "references": {
+        "reference_data": [
+            {
+                "refsource": "CONFIRM",
+                "name": "https://groups.google.com/forum/#!topic/golang-announce/3L45YRc91SY",
+                "url": "https://groups.google.com/forum/#!topic/golang-announce/3L45YRc91SY"
+            },
+            {
+                "refsource": "MISC",
+                "name": "http://packetstormsecurity.com/files/156480/Go-SSH-0.0.2-Denial-Of-Service.html",
+                "url": "http://packetstormsecurity.com/files/156480/Go-SSH-0.0.2-Denial-Of-Service.html"
+            },
+            {
+                "refsource": "MLIST",
+                "name": "[debian-lts-announce] 20201007 [SECURITY] [DLA 2402-1] golang-go.crypto security update",
+                "url": "https://lists.debian.org/debian-lts-announce/2020/10/msg00014.html"
+            },
+            {
+                "refsource": "MLIST",
+                "name": "[debian-lts-announce] 20201116 [SECURITY] [DLA 2453-1] restic security update",
+                "url": "https://lists.debian.org/debian-lts-announce/2020/11/msg00027.html"
+            },
+            {
+                "refsource": "MLIST",
+                "name": "[debian-lts-announce] 20201118 [SECURITY] [DLA 2455-1] packer security update",
+                "url": "https://lists.debian.org/debian-lts-announce/2020/11/msg00031.html"
+            },
+            {
+                "refsource": "MLIST",
+                "name": "[debian-lts-announce] 20230616 [SECURITY] [DLA 3455-1] golang-go.crypto security update",
+                "url": "https://lists.debian.org/debian-lts-announce/2023/06/msg00017.html"
+            }
+        ]
+    }
+}
diff --git a/internal/report/testdata/cve/v5.txtar b/internal/report/testdata/cve/v5.txtar
new file mode 100644
index 0000000..b512a18
--- /dev/null
+++ b/internal/report/testdata/cve/v5.txtar
@@ -0,0 +1,492 @@
+Copyright 2023 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.
+
+Repo in the shape of "https://github.com/CVEProject/cvelistV5".
+Updated with real data 2023-12-05T19:00:00-05:00.
+Auto-generated; do not edit directly.
+
+-- README.md --
+ignore me please
+
+-- cves/2022/39xxx/CVE-2022-39213.json --
+{
+    "containers": {
+        "cna": {
+            "affected": [
+                {
+                    "product": "go-cvss",
+                    "vendor": "pandatix",
+                    "versions": [
+                        {
+                            "status": "affected",
+                            "version": ">= 0.2.0, < 0.4.0"
+                        }
+                    ]
+                }
+            ],
+            "descriptions": [
+                {
+                    "lang": "en",
+                    "value": "go-cvss is a Go module to manipulate Common Vulnerability Scoring System (CVSS). In affected versions when a full CVSS v2.0 vector string is parsed using `ParseVector`, an Out-of-Bounds Read is possible due to a lack of tests. The Go module will then panic. The problem is patched in tag `v0.4.0`, by the commit `d9d478ff0c13b8b09ace030db9262f3c2fe031f4`. Users are advised to upgrade. Users unable to upgrade may avoid this issue by parsing only CVSS v2.0 vector strings that do not have all attributes defined (e.g. `AV:N/AC:L/Au:N/C:P/I:P/A:C/E:U/RL:OF/RC:C/CDP:MH/TD:H/CR:M/IR:M/AR:M`). As stated in [SECURITY.md](https://github.com/pandatix/go-cvss/blob/master/SECURITY.md), the CPE v2.3 to refer to this Go module is `cpe:2.3:a:pandatix:go_cvss:*:*:*:*:*:*:*:*`. The entry has already been requested to the NVD CPE dictionary."
+                }
+            ],
+            "metrics": [
+                {
+                    "cvssV3_1": {
+                        "attackComplexity": "LOW",
+                        "attackVector": "NETWORK",
+                        "availabilityImpact": "HIGH",
+                        "baseScore": 7.5,
+                        "baseSeverity": "HIGH",
+                        "confidentialityImpact": "NONE",
+                        "integrityImpact": "NONE",
+                        "privilegesRequired": "NONE",
+                        "scope": "UNCHANGED",
+                        "userInteraction": "NONE",
+                        "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
+                        "version": "3.1"
+                    }
+                }
+            ],
+            "problemTypes": [
+                {
+                    "descriptions": [
+                        {
+                            "cweId": "CWE-125",
+                            "description": "CWE-125: Out-of-bounds Read",
+                            "lang": "en",
+                            "type": "CWE"
+                        }
+                    ]
+                }
+            ],
+            "providerMetadata": {
+                "dateUpdated": "2022-09-15T21:45:12",
+                "orgId": "a0819718-46f1-4df5-94e2-005712e83aaa",
+                "shortName": "GitHub_M"
+            },
+            "references": [
+                {
+                    "tags": [
+                        "x_refsource_CONFIRM"
+                    ],
+                    "url": "https://github.com/pandatix/go-cvss/security/advisories/GHSA-xhmf-mmv2-4hhx"
+                },
+                {
+                    "tags": [
+                        "x_refsource_MISC"
+                    ],
+                    "url": "https://github.com/pandatix/go-cvss/commit/d9d478ff0c13b8b09ace030db9262f3c2fe031f4"
+                },
+                {
+                    "tags": [
+                        "x_refsource_MISC"
+                    ],
+                    "url": "https://github.com/pandatix/go-cvss/blob/master/SECURITY.md"
+                }
+            ],
+            "source": {
+                "advisory": "GHSA-xhmf-mmv2-4hhx",
+                "discovery": "UNKNOWN"
+            },
+            "title": "Out-of-bounds Read in go-cvss",
+            "x_legacyV4Record": {
+                "CVE_data_meta": {
+                    "ASSIGNER": "security-advisories@github.com",
+                    "ID": "CVE-2022-39213",
+                    "STATE": "PUBLIC",
+                    "TITLE": "Out-of-bounds Read in go-cvss"
+                },
+                "affects": {
+                    "vendor": {
+                        "vendor_data": [
+                            {
+                                "product": {
+                                    "product_data": [
+                                        {
+                                            "product_name": "go-cvss",
+                                            "version": {
+                                                "version_data": [
+                                                    {
+                                                        "version_value": ">= 0.2.0, < 0.4.0"
+                                                    }
+                                                ]
+                                            }
+                                        }
+                                    ]
+                                },
+                                "vendor_name": "pandatix"
+                            }
+                        ]
+                    }
+                },
+                "data_format": "MITRE",
+                "data_type": "CVE",
+                "data_version": "4.0",
+                "description": {
+                    "description_data": [
+                        {
+                            "lang": "eng",
+                            "value": "go-cvss is a Go module to manipulate Common Vulnerability Scoring System (CVSS). In affected versions when a full CVSS v2.0 vector string is parsed using `ParseVector`, an Out-of-Bounds Read is possible due to a lack of tests. The Go module will then panic. The problem is patched in tag `v0.4.0`, by the commit `d9d478ff0c13b8b09ace030db9262f3c2fe031f4`. Users are advised to upgrade. Users unable to upgrade may avoid this issue by parsing only CVSS v2.0 vector strings that do not have all attributes defined (e.g. `AV:N/AC:L/Au:N/C:P/I:P/A:C/E:U/RL:OF/RC:C/CDP:MH/TD:H/CR:M/IR:M/AR:M`). As stated in [SECURITY.md](https://github.com/pandatix/go-cvss/blob/master/SECURITY.md), the CPE v2.3 to refer to this Go module is `cpe:2.3:a:pandatix:go_cvss:*:*:*:*:*:*:*:*`. The entry has already been requested to the NVD CPE dictionary."
+                        }
+                    ]
+                },
+                "impact": {
+                    "cvss": {
+                        "attackComplexity": "LOW",
+                        "attackVector": "NETWORK",
+                        "availabilityImpact": "HIGH",
+                        "baseScore": 7.5,
+                        "baseSeverity": "HIGH",
+                        "confidentialityImpact": "NONE",
+                        "integrityImpact": "NONE",
+                        "privilegesRequired": "NONE",
+                        "scope": "UNCHANGED",
+                        "userInteraction": "NONE",
+                        "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H",
+                        "version": "3.1"
+                    }
+                },
+                "problemtype": {
+                    "problemtype_data": [
+                        {
+                            "description": [
+                                {
+                                    "lang": "eng",
+                                    "value": "CWE-125: Out-of-bounds Read"
+                                }
+                            ]
+                        }
+                    ]
+                },
+                "references": {
+                    "reference_data": [
+                        {
+                            "name": "https://github.com/pandatix/go-cvss/security/advisories/GHSA-xhmf-mmv2-4hhx",
+                            "refsource": "CONFIRM",
+                            "url": "https://github.com/pandatix/go-cvss/security/advisories/GHSA-xhmf-mmv2-4hhx"
+                        },
+                        {
+                            "name": "https://github.com/pandatix/go-cvss/commit/d9d478ff0c13b8b09ace030db9262f3c2fe031f4",
+                            "refsource": "MISC",
+                            "url": "https://github.com/pandatix/go-cvss/commit/d9d478ff0c13b8b09ace030db9262f3c2fe031f4"
+                        },
+                        {
+                            "name": "https://github.com/pandatix/go-cvss/blob/master/SECURITY.md",
+                            "refsource": "MISC",
+                            "url": "https://github.com/pandatix/go-cvss/blob/master/SECURITY.md"
+                        }
+                    ]
+                },
+                "source": {
+                    "advisory": "GHSA-xhmf-mmv2-4hhx",
+                    "discovery": "UNKNOWN"
+                }
+            }
+        }
+    },
+    "cveMetadata": {
+        "assignerOrgId": "a0819718-46f1-4df5-94e2-005712e83aaa",
+        "assignerShortName": "GitHub_M",
+        "cveId": "CVE-2022-39213",
+        "datePublished": "2022-09-15T21:45:12",
+        "dateReserved": "2022-09-02T00:00:00",
+        "dateUpdated": "2022-09-15T21:45:12",
+        "state": "PUBLISHED"
+    },
+    "dataType": "CVE_RECORD",
+    "dataVersion": "5.0"
+}
+-- cves/2023/44xxx/CVE-2023-44378.json --
+{
+    "dataType": "CVE_RECORD",
+    "dataVersion": "5.0",
+    "cveMetadata": {
+        "cveId": "CVE-2023-44378",
+        "assignerOrgId": "a0819718-46f1-4df5-94e2-005712e83aaa",
+        "state": "PUBLISHED",
+        "assignerShortName": "GitHub_M",
+        "dateReserved": "2023-09-28T17:56:32.612Z",
+        "datePublished": "2023-10-09T13:33:54.973Z",
+        "dateUpdated": "2023-10-09T13:33:54.973Z"
+    },
+    "containers": {
+        "cna": {
+            "title": "gnark vulnerable to unsoundness in variable comparison/non-unique binary decomposition",
+            "problemTypes": [
+                {
+                    "descriptions": [
+                        {
+                            "cweId": "CWE-191",
+                            "lang": "en",
+                            "description": "CWE-191: Integer Underflow (Wrap or Wraparound)",
+                            "type": "CWE"
+                        }
+                    ]
+                },
+                {
+                    "descriptions": [
+                        {
+                            "cweId": "CWE-697",
+                            "lang": "en",
+                            "description": "CWE-697: Incorrect Comparison",
+                            "type": "CWE"
+                        }
+                    ]
+                }
+            ],
+            "metrics": [
+                {
+                    "cvssV3_1": {
+                        "attackComplexity": "LOW",
+                        "attackVector": "LOCAL",
+                        "availabilityImpact": "NONE",
+                        "baseScore": 7.1,
+                        "baseSeverity": "HIGH",
+                        "confidentialityImpact": "NONE",
+                        "integrityImpact": "HIGH",
+                        "privilegesRequired": "NONE",
+                        "scope": "CHANGED",
+                        "userInteraction": "NONE",
+                        "vectorString": "CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:C/C:N/I:H/A:N",
+                        "version": "3.1"
+                    }
+                }
+            ],
+            "references": [
+                {
+                    "name": "https://github.com/Consensys/gnark/security/advisories/GHSA-498w-5j49-vqjg",
+                    "tags": [
+                        "x_refsource_CONFIRM"
+                    ],
+                    "url": "https://github.com/Consensys/gnark/security/advisories/GHSA-498w-5j49-vqjg"
+                },
+                {
+                    "name": "https://github.com/zkopru-network/zkopru/issues/116",
+                    "tags": [
+                        "x_refsource_MISC"
+                    ],
+                    "url": "https://github.com/zkopru-network/zkopru/issues/116"
+                },
+                {
+                    "name": "https://github.com/Consensys/gnark/commit/59a4087261a6c73f13e80d695c17b398c3d0934f",
+                    "tags": [
+                        "x_refsource_MISC"
+                    ],
+                    "url": "https://github.com/Consensys/gnark/commit/59a4087261a6c73f13e80d695c17b398c3d0934f"
+                }
+            ],
+            "affected": [
+                {
+                    "vendor": "Consensys",
+                    "product": "gnark",
+                    "versions": [
+                        {
+                            "version": "< 0.9.0",
+                            "status": "affected"
+                        }
+                    ]
+                }
+            ],
+            "providerMetadata": {
+                "orgId": "a0819718-46f1-4df5-94e2-005712e83aaa",
+                "shortName": "GitHub_M",
+                "dateUpdated": "2023-10-09T13:33:54.973Z"
+            },
+            "descriptions": [
+                {
+                    "lang": "en",
+                    "value": "gnark is a zk-SNARK library that offers a high-level API to design circuits. Prior to version 0.9.0, for some in-circuit values, it is possible to construct two valid decomposition to bits. In addition to the canonical decomposition of `a`, for small values there exists a second decomposition for `a+r` (where `r` is the modulus the values are being reduced by). The second decomposition was possible due to overflowing the field where the values are defined. Upgrading to version 0.9.0 should fix the issue without needing to change the calls to value comparison methods."
+                }
+            ],
+            "source": {
+                "advisory": "GHSA-498w-5j49-vqjg",
+                "discovery": "UNKNOWN"
+            }
+        }
+    }
+}
+-- cves/2023/45xxx/CVE-2023-45141.json --
+{
+    "dataType": "CVE_RECORD",
+    "dataVersion": "5.0",
+    "cveMetadata": {
+        "cveId": "CVE-2023-45141",
+        "assignerOrgId": "a0819718-46f1-4df5-94e2-005712e83aaa",
+        "state": "PUBLISHED",
+        "assignerShortName": "GitHub_M",
+        "dateReserved": "2023-10-04T16:02:46.329Z",
+        "datePublished": "2023-10-16T20:48:55.590Z",
+        "dateUpdated": "2023-10-16T20:48:55.590Z"
+    },
+    "containers": {
+        "cna": {
+            "title": "CSRF Token Validation Vulnerability in fiber",
+            "problemTypes": [
+                {
+                    "descriptions": [
+                        {
+                            "cweId": "CWE-352",
+                            "lang": "en",
+                            "description": "CWE-352: Cross-Site Request Forgery (CSRF)",
+                            "type": "CWE"
+                        }
+                    ]
+                },
+                {
+                    "descriptions": [
+                        {
+                            "cweId": "CWE-565",
+                            "lang": "en",
+                            "description": "CWE-565: Reliance on Cookies without Validation and Integrity Checking",
+                            "type": "CWE"
+                        }
+                    ]
+                }
+            ],
+            "metrics": [
+                {
+                    "cvssV3_1": {
+                        "attackComplexity": "LOW",
+                        "attackVector": "NETWORK",
+                        "availabilityImpact": "LOW",
+                        "baseScore": 8.6,
+                        "baseSeverity": "HIGH",
+                        "confidentialityImpact": "LOW",
+                        "integrityImpact": "HIGH",
+                        "privilegesRequired": "NONE",
+                        "scope": "UNCHANGED",
+                        "userInteraction": "NONE",
+                        "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:H/A:L",
+                        "version": "3.1"
+                    }
+                }
+            ],
+            "references": [
+                {
+                    "name": "https://github.com/gofiber/fiber/security/advisories/GHSA-mv73-f69x-444p",
+                    "tags": [
+                        "x_refsource_CONFIRM"
+                    ],
+                    "url": "https://github.com/gofiber/fiber/security/advisories/GHSA-mv73-f69x-444p"
+                }
+            ],
+            "affected": [
+                {
+                    "vendor": "gofiber",
+                    "product": "fiber",
+                    "versions": [
+                        {
+                            "version": "< 2.50.0",
+                            "status": "affected"
+                        }
+                    ]
+                }
+            ],
+            "providerMetadata": {
+                "orgId": "a0819718-46f1-4df5-94e2-005712e83aaa",
+                "shortName": "GitHub_M",
+                "dateUpdated": "2023-10-16T20:48:55.590Z"
+            },
+            "descriptions": [
+                {
+                    "lang": "en",
+                    "value": "Fiber is an express inspired web framework written in Go. A Cross-Site Request Forgery (CSRF) vulnerability has been identified in the application, which allows an attacker to obtain tokens and forge malicious requests on behalf of a user. This can lead to unauthorized actions being taken on the user's behalf, potentially compromising the security and integrity of the application. The vulnerability is caused by improper validation and enforcement of CSRF tokens within the application. This vulnerability has been addressed in version 2.50.0 and users are advised to upgrade. Users should take additional security measures like captchas or Two-Factor Authentication (2FA) and set Session cookies with SameSite=Lax or SameSite=Secure, and the Secure and HttpOnly attributes."
+                }
+            ],
+            "source": {
+                "advisory": "GHSA-mv73-f69x-444p",
+                "discovery": "UNKNOWN"
+            }
+        }
+    }
+}
+-- cves/2020/9xxx/CVE-2020-9283.json --
+{
+    "dataType": "CVE_RECORD",
+    "dataVersion": "5.0",
+    "cveMetadata": {
+        "state": "PUBLISHED",
+        "cveId": "CVE-2020-9283",
+        "assignerOrgId": "8254265b-2729-46b6-b9e3-3dfca2d5bfca",
+        "assignerShortName": "mitre",
+        "dateUpdated": "2023-06-16T00:00:00",
+        "dateReserved": "2020-02-19T00:00:00",
+        "datePublished": "2020-02-20T00:00:00"
+    },
+    "containers": {
+        "cna": {
+            "providerMetadata": {
+                "orgId": "8254265b-2729-46b6-b9e3-3dfca2d5bfca",
+                "shortName": "mitre",
+                "dateUpdated": "2023-06-16T00:00:00"
+            },
+            "descriptions": [
+                {
+                    "lang": "en",
+                    "value": "golang.org/x/crypto before v0.0.0-20200220183623-bac4c82f6975 for Go allows a panic during signature verification in the golang.org/x/crypto/ssh package. A client can attack an SSH server that accepts public keys. Also, a server can attack any SSH client."
+                }
+            ],
+            "affected": [
+                {
+                    "vendor": "n/a",
+                    "product": "n/a",
+                    "versions": [
+                        {
+                            "version": "n/a",
+                            "status": "affected"
+                        }
+                    ]
+                }
+            ],
+            "references": [
+                {
+                    "url": "https://groups.google.com/forum/#%21topic/golang-announce/3L45YRc91SY"
+                },
+                {
+                    "url": "http://packetstormsecurity.com/files/156480/Go-SSH-0.0.2-Denial-Of-Service.html"
+                },
+                {
+                    "name": "[debian-lts-announce] 20201007 [SECURITY] [DLA 2402-1] golang-go.crypto security update",
+                    "tags": [
+                        "mailing-list"
+                    ],
+                    "url": "https://lists.debian.org/debian-lts-announce/2020/10/msg00014.html"
+                },
+                {
+                    "name": "[debian-lts-announce] 20201116 [SECURITY] [DLA 2453-1] restic security update",
+                    "tags": [
+                        "mailing-list"
+                    ],
+                    "url": "https://lists.debian.org/debian-lts-announce/2020/11/msg00027.html"
+                },
+                {
+                    "name": "[debian-lts-announce] 20201118 [SECURITY] [DLA 2455-1] packer security update",
+                    "tags": [
+                        "mailing-list"
+                    ],
+                    "url": "https://lists.debian.org/debian-lts-announce/2020/11/msg00031.html"
+                },
+                {
+                    "name": "[debian-lts-announce] 20230616 [SECURITY] [DLA 3455-1] golang-go.crypto security update",
+                    "tags": [
+                        "mailing-list"
+                    ],
+                    "url": "https://lists.debian.org/debian-lts-announce/2023/06/msg00017.html"
+                }
+            ],
+            "problemTypes": [
+                {
+                    "descriptions": [
+                        {
+                            "type": "text",
+                            "lang": "en",
+                            "description": "n/a"
+                        }
+                    ]
+                }
+            ]
+        }
+    }
+}
diff --git a/internal/test/txtar.go b/internal/test/txtar.go
index 6397c96..f5d6dd0 100644
--- a/internal/test/txtar.go
+++ b/internal/test/txtar.go
@@ -23,7 +23,7 @@
 			Comment: []byte(addCopyright(comment)),
 			Files:   files,
 		},
-	), os.ModePerm); err != nil {
+	), 0666); err != nil {
 		return err
 	}