CVE-2022-39213 (Go, published 2022-09-15T22:15Z)
Description: 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.
Severity: nan (CVSS v3 base score: 7.5)
Weakness: CWE-125 \u2014 Out-of-bounds Read
The product reads data past the end, or before the beginning, of the intended buffer.
Repository: https://github.com/pandatix/go-cvss
Files changed:
20/cvss20.go
20/cvss20_bench_test.go
20/cvss20_fuzz_test.go
20/cvss20_test.go
20/errors.go
README.md
Commit message: Improve CVSS v2.0 implementation (0/1 allocs/op)


Vulnerable code:
	pts := strings.Split(vector, "/")
	if len(pts) != 6 && len(pts) != 9 && len(pts) != 14 {
		Base: Base{},
		Temporal: Temporal{
			Exploitability:   "ND",
			RemediationLevel: "ND",
			ReportConfidence: "ND",
		Environmental: Environmental{
			CollateralDamagePotential:  "ND",
			TargetDistribution:         "ND",
			ConfidentialityRequirement: "ND",
			IntegrityRequirement:       "ND",
			AvailabilityRequirement:    "ND",
	// Parse metrics in order
	slcs := [][]string{
		{"AV", "AC", "Au", "C", "I", "A"}, // Base metrics
		{"E", "RL", "RC"},                 // Temporal metrics
		{"CDP", "TD", "CR", "IR", "AR"},   // Environmental metrics
	}
	currSlc := slcs[slci]
		if abv != currSlc[i] {
		if i == len(currSlc) {
			currSlc = slcs[slci]
	s := ""
	s += "AV:" + cvss20.AccessVector
	s += "/AC:" + cvss20.AccessComplexity
	s += "/Au:" + cvss20.Authentication
	s += "/C:" + cvss20.ConfidentialityImpact
	s += "/I:" + cvss20.IntegrityImpact
	s += "/A:" + cvss20.AvailabilityImpact
	// Temporal, if any is defined
	if cvss20.Exploitability != "ND" || cvss20.RemediationLevel != "ND" || cvss20.ReportConfidence != "ND" {
		s += "/E:" + cvss20.Exploitability
		s += "/RL:" + cvss20.RemediationLevel
		s += "/RC:" + cvss20.ReportConfidence
	// Environmental, if any is defined
	if cvss20.CollateralDamagePotential != "ND" || cvss20.TargetDistribution != "ND" || cvss20.ConfidentialityRequirement != "ND" || cvss20.IntegrityRequirement != "ND" || cvss20.AvailabilityRequirement != "ND" {
		s += "/CDP:" + cvss20.CollateralDamagePotential
		s += "/TD:" + cvss20.TargetDistribution
		s += "/CR:" + cvss20.ConfidentialityRequirement
		s += "/IR:" + cvss20.IntegrityRequirement
		s += "/AR:" + cvss20.AvailabilityRequirement
	return s
	Base
	Temporal
	Environmental
// Base is the group of metrics defined with such name by the
type Base struct {
	AccessVector string
	AccessComplexity string
	Authentication string
	ConfidentialityImpact string
	IntegrityImpact string
	AvailabilityImpact string
// Temporal is the group of metrics defined with such name by the
type Temporal struct {
	Exploitability string
	RemediationLevel string
	ReportConfidence string
// Environmental is the group of metrics defined with such name by the
type Environmental struct {
	CollateralDamagePotential string
	TargetDistribution string
	ConfidentialityRequirement string
	IntegrityRequirement       string
	AvailabilityRequirement    string
		return cvss20.AccessVector, nil
		return cvss20.AccessComplexity, nil
		return cvss20.Authentication, nil
		return cvss20.ConfidentialityImpact, nil
		return cvss20.IntegrityImpact, nil
		return cvss20.AvailabilityImpact, nil
		return cvss20.Exploitability, nil
		return cvss20.RemediationLevel, nil
		return cvss20.ReportConfidence, nil
		return cvss20.CollateralDamagePotential, nil
		return cvss20.TargetDistribution, nil
		return cvss20.ConfidentialityRequirement, nil
		return cvss20.IntegrityRequirement, nil
		return cvss20.AvailabilityRequirement, nil
		cvss20.AccessVector = value
		cvss20.AccessComplexity = value
		cvss20.Authentication = value
		cvss20.ConfidentialityImpact = value
		cvss20.IntegrityImpact = value
		cvss20.AvailabilityImpact = value
		cvss20.Exploitability = value
		cvss20.RemediationLevel = value
		cvss20.ReportConfidence = value
		cvss20.CollateralDamagePotential = value
		cvss20.TargetDistribution = value
		cvss20.ConfidentialityRequirement = value
		cvss20.IntegrityRequirement = value
		cvss20.AvailabilityRequirement = value
	impact := 10.41 * (1 - (1-cia(cvss20.ConfidentialityImpact))*(1-cia(cvss20.IntegrityImpact))*(1-cia(cvss20.AvailabilityImpact)))
	exploitability := 20 * accessVector(cvss20.AccessVector) * accessComplexity(cvss20.AccessComplexity) * authentication(cvss20.Authentication)
	return roundTo1Decimal(cvss20.BaseScore() * exploitability(cvss20.Exploitability) * remediationLevel(cvss20.RemediationLevel) * reportConfidence(cvss20.ReportConfidence))
	adjustedImpact := math.Min(10, 10.41*(1-(1-cia(cvss20.ConfidentialityImpact)*ciar(cvss20.ConfidentialityRequirement))*(1-cia(cvss20.IntegrityImpact)*ciar(cvss20.IntegrityRequirement))*(1-cia(cvss20.AvailabilityImpact)*ciar(cvss20.AvailabilityRequirement))))
	expltBase := 20 * accessVector(cvss20.AccessVector) * accessComplexity(cvss20.AccessComplexity) * authentication(cvss20.Authentication)
	adjustedTemporal := roundTo1Decimal(recBase * exploitability(cvss20.Exploitability) * remediationLevel(cvss20.RemediationLevel) * reportConfidence(cvss20.ReportConfidence))
	return roundTo1Decimal((adjustedTemporal + (10-adjustedTemporal)*collateralDamagePotential(cvss20.CollateralDamagePotential)) * targetDistribution(cvss20.TargetDistribution))
package gocvss20_test

	gocvss20 "github.com/pandatix/go-cvss/20"
		cvss20, err := gocvss20.ParseVector(vector)
package gocvss20_test
	gocvss20 "github.com/pandatix/go-cvss/20"
	ExpectedCVSS20 *gocvss20.CVSS20
		ExpectedCVSS20: &gocvss20.CVSS20{
			Base: gocvss20.Base{
				AccessVector:          "N",
				AccessComplexity:      "L",
				Authentication:        "N",
				ConfidentialityImpact: "N",
				IntegrityImpact:       "N",
				AvailabilityImpact:    "C",
			Temporal: gocvss20.Temporal{
				Exploitability:   "F",
				RemediationLevel: "OF",
				ReportConfidence: "C",
			Environmental: gocvss20.Environmental{
				CollateralDamagePotential:  "ND",
				TargetDistribution:         "ND",
				ConfidentialityRequirement: "ND",
				IntegrityRequirement:       "ND",
				AvailabilityRequirement:    "ND",
		ExpectedCVSS20: &gocvss20.CVSS20{
			Base: gocvss20.Base{
				AccessVector:          "N",
				AccessComplexity:      "L",
				Authentication:        "N",
				ConfidentialityImpact: "C",
				IntegrityImpact:       "C",
				AvailabilityImpact:    "C",
			Temporal: gocvss20.Temporal{
				Exploitability:   "F",
				RemediationLevel: "OF",
				ReportConfidence: "C",
			Environmental: gocvss20.Environmental{
				CollateralDamagePotential:  "ND",
				TargetDistribution:         "ND",
				ConfidentialityRequirement: "ND",
				IntegrityRequirement:       "ND",
				AvailabilityRequirement:    "ND",
		ExpectedCVSS20: &gocvss20.CVSS20{
			Base: gocvss20.Base{
				AccessVector:          "L",
				AccessComplexity:      "H",
				Authentication:        "N",
				ConfidentialityImpact: "C",
				IntegrityImpact:       "C",
				AvailabilityImpact:    "C",
			Temporal: gocvss20.Temporal{
				Exploitability:   "POC",
				RemediationLevel: "OF",
				ReportConfidence: "C",
			Environmental: gocvss20.Environmental{
				CollateralDamagePotential:  "ND",
				TargetDistribution:         "ND",
				ConfidentialityRequirement: "ND",
				IntegrityRequirement:       "ND",
				AvailabilityRequirement:    "ND",
			cvss20, err := gocvss20.ParseVector(tt.Vector)
		CVSS20                     *gocvss20.CVSS20
			CVSS20: &gocvss20.CVSS20{
				Base: gocvss20.Base{
					AccessVector:          "N",
					AccessComplexity:      "L",
					Authentication:        "N",
					ConfidentialityImpact: "N",
					IntegrityImpact:       "N",
					AvailabilityImpact:    "C",
				Temporal: gocvss20.Temporal{
					Exploitability:   "F",
					RemediationLevel: "OF",
					ReportConfidence: "C",
				Environmental: gocvss20.Environmental{
					CollateralDamagePotential:  "ND",
					TargetDistribution:         "ND",
					ConfidentialityRequirement: "ND",
					IntegrityRequirement:       "ND",
					AvailabilityRequirement:    "ND",
			CVSS20: &gocvss20.CVSS20{
				Base: gocvss20.Base{
					AccessVector:          "N",
					AccessComplexity:      "L",
					Authentication:        "N",
					ConfidentialityImpact: "C",
					IntegrityImpact:       "C",
					AvailabilityImpact:    "C",
				Temporal: gocvss20.Temporal{
					Exploitability:   "F",
					RemediationLevel: "OF",
					ReportConfidence: "C",
				Environmental: gocvss20.Environmental{
					CollateralDamagePotential:  "ND",
					TargetDistribution:         "ND",
					ConfidentialityRequirement: "ND",
					IntegrityRequirement:       "ND",
					AvailabilityRequirement:    "ND",
			CVSS20: &gocvss20.CVSS20{
				Base: gocvss20.Base{
					AccessVector:          "L",
					AccessComplexity:      "H",
					Authentication:        "N",
					ConfidentialityImpact: "C",
					IntegrityImpact:       "C",
					AvailabilityImpact:    "C",
				Temporal: gocvss20.Temporal{
					Exploitability:   "POC",
					RemediationLevel: "OF",
					ReportConfidence: "C",
				Environmental: gocvss20.Environmental{
					CollateralDamagePotential:  "ND",
					TargetDistribution:         "ND",
					ConfidentialityRequirement: "ND",
					IntegrityRequirement:       "ND",
					AvailabilityRequirement:    "ND",
// ErrBaseScore is an error returned by ParseVector when the
// given vector have missing base score attributes.
type ErrBaseScore struct {
	Missings []string
}

func (err ErrBaseScore) Error() string {
	return fmt.Sprintf("base score is missing metrics %v", err.Missings)
}

var _ error = (*ErrBaseScore)(nil)

	Abv []string
	return fmt.Sprintf("given CVSS v3.1 vector has %v metric abbreviations defined multiple times", err.Abv)
BenchmarkParseVector_Base-4                      1443836               808.4 ns/op           352 B/op          1 allocs/op
BenchmarkParseVector_WithTempAndEnv-4             701901              1711 ns/op             352 B/op          1 allocs/op
BenchmarkCVSS30Vector-4                          5593758               215.8 ns/op            96 B/op          1 allocs/op
BenchmarkCVSS30Get-4                            27306528                41.66 ns/op            0 B/op          0 allocs/op
BenchmarkCVSS30Set-4                            31862641                37.94 ns/op            0 B/op          0 allocs/op
BenchmarkCVSS30BaseScore-4                       7769804               139.2 ns/op             0 B/op          0 allocs/op
BenchmarkCVSS30TemporalScore-4                   5814230               189.1 ns/op             0 B/op          0 allocs/op
BenchmarkCVSS30EnvironmentalScore-4              6402489               188.7 ns/op             0 B/op          0 allocs/op
BenchmarkParseVector_Base-4             	 1312525	       895.0 ns/op	     352 B/op	       1 allocs/op
BenchmarkParseVector_WithTempAndEnv-4   	  685629	        2232 ns/op	     352 B/op	       1 allocs/op
BenchmarkCVSS31Vector-4                 	 4867528	       223.2 ns/op	      96 B/op	       1 allocs/op
BenchmarkCVSS31Get-4                    	31498058	       36.37 ns/op	       0 B/op	       0 allocs/op
BenchmarkCVSS31Set-4                    	30187612	       38.73 ns/op	       0 B/op	       0 allocs/op
BenchmarkCVSS31BaseScore-4              	11144173	       101.2 ns/op	       0 B/op	       0 allocs/op
BenchmarkCVSS31TemporalScore-4          	 7856455	       154.4 ns/op	       0 B/op	       0 allocs/op
BenchmarkCVSS31EnvironmentalScore-4     	 6310815	       169.4 ns/op	       0 B/op	       0 allocs/op

Fixed code:
	"sync"
	"unsafe"
var order = [][]string{
	{"AV", "AC", "Au", "C", "I", "A"}, // Base metrics
	{"E", "RL", "RC"},                 // Temporal metrics
	{"CDP", "TD", "CR", "IR", "AR"},   // Environmental metrics
}

	pts, l := split(vector)
	if l != 6 && l != 9 && l != 14 {
	pts = pts[:l]
		base: base{},
		temporal: temporal{
			exploitability:   "ND",
			remediationLevel: "ND",
			reportConfidence: "ND",
		environmental: environmental{
			collateralDamagePotential:  "ND",
			targetDistribution:         "ND",
			confidentialityRequirement: "ND",
			integrityRequirement:       "ND",
			availabilityRequirement:    "ND",
		if slci == 4 {
			return nil, &ErrDefinedN{Abv: abv}
		}
		if abv != order[slci][i] {


		if i == len(order[slci]) {
var splitPool = sync.Pool{
	New: func() any {
		return make([]string, 14)
	},
}

func split(vector string) ([]string, int) {
	partsPtr := splitPool.Get()
	defer splitPool.Put(partsPtr)
	parts := partsPtr.([]string)

	start := 0
	curr := 0
	l := len(vector)
	i := 0
	for ; i < l; i++ {
		if vector[i] == '/' {
			parts[curr] = vector[start:i]

			start = i + 1
			curr++

			if curr == 13 {
				break
			}
		}
	}
	parts[curr] = vector[start:]
	return parts, curr + 1
}

	l := lenVec(&cvss20)
	b := make([]byte, 0, l)

	app(&b, "AV:", cvss20.accessVector)
	app(&b, "/AC:", cvss20.accessComplexity)
	app(&b, "/Au:", cvss20.authentication)
	app(&b, "/C:", cvss20.confidentialityImpact)
	app(&b, "/I:", cvss20.integrityImpact)
	app(&b, "/A:", cvss20.availabilityImpact)

	// Temporal
	if cvss20.exploitability != "ND" || cvss20.remediationLevel != "ND" || cvss20.reportConfidence != "ND" {
		app(&b, "/E:", cvss20.exploitability)
		app(&b, "/RL:", cvss20.remediationLevel)
		app(&b, "/RC:", cvss20.reportConfidence)

	// Environmental
	if cvss20.collateralDamagePotential != "ND" || cvss20.targetDistribution != "ND" || cvss20.confidentialityRequirement != "ND" || cvss20.integrityRequirement != "ND" || cvss20.availabilityRequirement != "ND" {
		app(&b, "/CDP:", cvss20.collateralDamagePotential)
		app(&b, "/TD:", cvss20.targetDistribution)
		app(&b, "/CR:", cvss20.confidentialityRequirement)
		app(&b, "/IR:", cvss20.integrityRequirement)
		app(&b, "/AR:", cvss20.availabilityRequirement)

	return *(*string)(unsafe.Pointer(&b))
}

func lenVec(cvss20 *CVSS20) int {
	// Base:
	// - AV, AC, Au: 4
	// - C, I, A: 3
	// - separators: 5
	// Total: 3*4 + 3*3 + 5 = 30
	l := 26

	// Temporal:
	// - E: 2 + len(v)
	// - RL: 3 + len(v)
	// - RC: 3 + len(v)
	// - separators: 3
	// Total: 11 + 3*len(v)
	if cvss20.exploitability != "ND" || cvss20.remediationLevel != "ND" || cvss20.reportConfidence != "ND" {
		l += 11 + len(cvss20.exploitability) + len(cvss20.remediationLevel) + len(cvss20.reportConfidence)
	}

	// Environmental:
	// - CDP: 4 + len(v)
	// - TD: 3 + len(v)
	// - CR, IR, AR: 3 + len(v)
	// - separators: 5
	// Total: 21 + 5*len(v)
	if cvss20.collateralDamagePotential != "ND" || cvss20.targetDistribution != "ND" || cvss20.confidentialityRequirement != "ND" || cvss20.integrityRequirement != "ND" || cvss20.availabilityRequirement != "ND" {
		l += 21 + len(cvss20.collateralDamagePotential) + len(cvss20.targetDistribution) + len(cvss20.confidentialityRequirement) + len(cvss20.integrityRequirement) + len(cvss20.availabilityRequirement)
	}

	return l
}

func app(b *[]byte, pre, v string) {
	*b = append(*b, pre...)
	*b = append(*b, v...)
	base
	temporal
	environmental
// base is the group of metrics defined with such name by the
type base struct {
	accessVector string
	accessComplexity string
	authentication string
	confidentialityImpact string
	integrityImpact string
	availabilityImpact string
// temporal is the group of metrics defined with such name by the
type temporal struct {
	exploitability string
	remediationLevel string
	reportConfidence string
// environmental is the group of metrics defined with such name by the
type environmental struct {
	collateralDamagePotential string
	targetDistribution string
	confidentialityRequirement string
	integrityRequirement       string
	availabilityRequirement    string
		return cvss20.accessVector, nil
		return cvss20.accessComplexity, nil
		return cvss20.authentication, nil
		return cvss20.confidentialityImpact, nil
		return cvss20.integrityImpact, nil
		return cvss20.availabilityImpact, nil
		return cvss20.exploitability, nil
		return cvss20.remediationLevel, nil
		return cvss20.reportConfidence, nil
		return cvss20.collateralDamagePotential, nil
		return cvss20.targetDistribution, nil
		return cvss20.confidentialityRequirement, nil
		return cvss20.integrityRequirement, nil
		return cvss20.availabilityRequirement, nil
		cvss20.accessVector = value
		cvss20.accessComplexity = value
		cvss20.authentication = value
		cvss20.confidentialityImpact = value
		cvss20.integrityImpact = value
		cvss20.availabilityImpact = value
		cvss20.exploitability = value
		cvss20.remediationLevel = value
		cvss20.reportConfidence = value
		cvss20.collateralDamagePotential = value
		cvss20.targetDistribution = value
		cvss20.confidentialityRequirement = value
		cvss20.integrityRequirement = value
		cvss20.availabilityRequirement = value
	impact := cvss20.Impact()
	exploitability := cvss20.Exploitability()
func (cvss20 CVSS20) Impact() float64 {
	return 10.41 * (1 - (1-cia(cvss20.confidentialityImpact))*(1-cia(cvss20.integrityImpact))*(1-cia(cvss20.availabilityImpact)))
}

func (cvss20 CVSS20) Exploitability() float64 {
	return 20 * accessVector(cvss20.accessVector) * accessComplexity(cvss20.accessComplexity) * authentication(cvss20.authentication)
}

	return roundTo1Decimal(cvss20.BaseScore() * exploitability(cvss20.exploitability) * remediationLevel(cvss20.remediationLevel) * reportConfidence(cvss20.reportConfidence))
	adjustedImpact := math.Min(10, 10.41*(1-(1-cia(cvss20.confidentialityImpact)*ciar(cvss20.confidentialityRequirement))*(1-cia(cvss20.integrityImpact)*ciar(cvss20.integrityRequirement))*(1-cia(cvss20.availabilityImpact)*ciar(cvss20.availabilityRequirement))))
	expltBase := 20 * accessVector(cvss20.accessVector) * accessComplexity(cvss20.accessComplexity) * authentication(cvss20.authentication)
	adjustedTemporal := roundTo1Decimal(recBase * exploitability(cvss20.exploitability) * remediationLevel(cvss20.remediationLevel) * reportConfidence(cvss20.reportConfidence))
	return roundTo1Decimal((adjustedTemporal + (10-adjustedTemporal)*collateralDamagePotential(cvss20.collateralDamagePotential)) * targetDistribution(cvss20.targetDistribution))
package gocvss20_test

import (
	"testing"

	gocvss20 "github.com/pandatix/go-cvss/20"
)

var Gcvss20 *gocvss20.CVSS20
var Gerr error

func BenchmarkParseVector_Base(b *testing.B) {
	benchmarkParseVector("AV:N/AC:L/Au:N/C:P/I:P/A:C", b)
}

func BenchmarkParseVector_WithTempAndEnv(b *testing.B) {
	benchmarkParseVector("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", b)
}

func benchmarkParseVector(vector string, b *testing.B) {
	var cvss20 *gocvss20.CVSS20
	var err error
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		cvss20, err = gocvss20.ParseVector(vector)
	}
	Gcvss20 = cvss20
	Gerr = err
}

var Gstr string

func BenchmarkCVSS20Vector(b *testing.B) {
	cvss20, _ := gocvss20.ParseVector("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")
	var str string
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		str = cvss20.Vector()
	}
	Gstr = str
}

var Gget string

func BenchmarkCVSS20Get(b *testing.B) {
	const abv = "Au"
	cvss20, _ := gocvss20.ParseVector("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")
	var get string
	var err error
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		get, err = cvss20.Get(abv)
	}
	Gget = get
	Gerr = err
}

func BenchmarkCVSS20Set(b *testing.B) {
	const abv = "Au"
	const value = "S"
	cvss20, _ := gocvss20.ParseVector("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")
	var err error
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		err = cvss20.Set(abv, value)
	}
	Gerr = err
}

var Gscore float64

func BenchmarkCVSS20BaseScore(b *testing.B) {
	var score float64
	cvss20, _ := gocvss20.ParseVector("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")
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		score = cvss20.BaseScore()
	}
	Gscore = score
}

func BenchmarkCVSS20TemporalScore(b *testing.B) {
	var score float64
	cvss20, _ := gocvss20.ParseVector("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")
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		score = cvss20.TemporalScore()
	}
	Gscore = score
}

func BenchmarkCVSS20EnvironmentalScore(b *testing.B) {
	var score float64
	cvss20, _ := gocvss20.ParseVector("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")
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		score = cvss20.EnvironmentalScore()
	}
	Gscore = score
}
package gocvss20
		cvss20, err := ParseVector(vector)
package gocvss20
	ExpectedCVSS20 *CVSS20
		ExpectedCVSS20: &CVSS20{
			base: base{
				accessVector:          "N",
				accessComplexity:      "L",
				authentication:        "N",
				confidentialityImpact: "N",
				integrityImpact:       "N",
				availabilityImpact:    "C",
			temporal: temporal{
				exploitability:   "F",
				remediationLevel: "OF",
				reportConfidence: "C",
			environmental: environmental{
				collateralDamagePotential:  "ND",
				targetDistribution:         "ND",
				confidentialityRequirement: "ND",
				integrityRequirement:       "ND",
				availabilityRequirement:    "ND",
		ExpectedCVSS20: &CVSS20{
			base: base{
				accessVector:          "N",
				accessComplexity:      "L",
				authentication:        "N",
				confidentialityImpact: "C",
				integrityImpact:       "C",
				availabilityImpact:    "C",
			temporal: temporal{
				exploitability:   "F",
				remediationLevel: "OF",
				reportConfidence: "C",
			environmental: environmental{
				collateralDamagePotential:  "ND",
				targetDistribution:         "ND",
				confidentialityRequirement: "ND",
				integrityRequirement:       "ND",
				availabilityRequirement:    "ND",
		ExpectedCVSS20: &CVSS20{
			base: base{
				accessVector:          "L",
				accessComplexity:      "H",
				authentication:        "N",
				confidentialityImpact: "C",
				integrityImpact:       "C",
				availabilityImpact:    "C",
			temporal: temporal{
				exploitability:   "POC",
				remediationLevel: "OF",
				reportConfidence: "C",
			environmental: environmental{
				collateralDamagePotential:  "ND",
				targetDistribution:         "ND",
				confidentialityRequirement: "ND",
				integrityRequirement:       "ND",
				availabilityRequirement:    "ND",
	"all-defined": {
		Vector: "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",
		ExpectedCVSS20: &CVSS20{
			base: base{
				accessVector:          "N",
				accessComplexity:      "L",
				authentication:        "N",
				confidentialityImpact: "P",
				integrityImpact:       "P",
				availabilityImpact:    "C",
			},
			temporal: temporal{
				exploitability:   "U",
				remediationLevel: "OF",
				reportConfidence: "C",
			},
			environmental: environmental{
				collateralDamagePotential:  "MH",
				targetDistribution:         "H",
				confidentialityRequirement: "M",
				integrityRequirement:       "M",
				availabilityRequirement:    "M",
			},
		},
		ExpectedErr: nil,
	},
	"Fuzz_50620a37c4a7716a77a14602b4bcc7b02e6f751d0a714ed796d9b04402c745ac": {
		// This fuzz crasher enabled detecting that the split function
		// (comming from the optimization step) was doing an Out-Of-Bounds
		// Write (CWE-787) if the vector was only composed of '/'.
		Vector:         "//////////////",
		ExpectedCVSS20: nil,
		ExpectedErr:    ErrInvalidMetricOrder,
	},
			cvss20, err := ParseVector(tt.Vector)
		CVSS20                     *CVSS20
			CVSS20: &CVSS20{
				base: base{
					accessVector:          "N",
					accessComplexity:      "L",
					authentication:        "N",
					confidentialityImpact: "N",
					integrityImpact:       "N",
					availabilityImpact:    "C",
				temporal: temporal{
					exploitability:   "F",
					remediationLevel: "OF",
					reportConfidence: "C",
				environmental: environmental{
					collateralDamagePotential:  "ND",
					targetDistribution:         "ND",
					confidentialityRequirement: "ND",
					integrityRequirement:       "ND",
					availabilityRequirement:    "ND",
			CVSS20: &CVSS20{
				base: base{
					accessVector:          "N",
					accessComplexity:      "L",
					authentication:        "N",
					confidentialityImpact: "C",
					integrityImpact:       "C",
					availabilityImpact:    "C",
				temporal: temporal{
					exploitability:   "F",
					remediationLevel: "OF",
					reportConfidence: "C",
				environmental: environmental{
					collateralDamagePotential:  "ND",
					targetDistribution:         "ND",
					confidentialityRequirement: "ND",
					integrityRequirement:       "ND",
					availabilityRequirement:    "ND",
			CVSS20: &CVSS20{
				base: base{
					accessVector:          "L",
					accessComplexity:      "H",
					authentication:        "N",
					confidentialityImpact: "C",
					integrityImpact:       "C",
					availabilityImpact:    "C",
				temporal: temporal{
					exploitability:   "POC",
					remediationLevel: "OF",
					reportConfidence: "C",
				environmental: environmental{
					collateralDamagePotential:  "ND",
					targetDistribution:         "ND",
					confidentialityRequirement: "ND",
					integrityRequirement:       "ND",
					availabilityRequirement:    "ND",
	Abv string
	return fmt.Sprintf("given CVSS v3.1 vector has %s metric abbreviation defined after vector end", err.Abv)
```
goos: linux
goarch: amd64
pkg: github.com/pandatix/go-cvss/20
cpu: Intel(R) Core(TM) i5-2450M CPU @ 2.50GHz
BenchmarkParseVector_Base-4             	 2089275	       572.9 ns/op	     224 B/op	       1 allocs/op
BenchmarkParseVector_WithTempAndEnv-4   	 1000000	        1118 ns/op	     224 B/op	       1 allocs/op
BenchmarkCVSS20Vector-4                 	 6806152	       176.3 ns/op	      80 B/op	       1 allocs/op
BenchmarkCVSS20Get-4                    	46162280	       26.50 ns/op	       0 B/op	       0 allocs/op
BenchmarkCVSS20Set-4                    	42365036	       27.50 ns/op	       0 B/op	       0 allocs/op
BenchmarkCVSS20BaseScore-4              	20117143	       57.68 ns/op	       0 B/op	       0 allocs/op
BenchmarkCVSS20TemporalScore-4          	14383033	       83.66 ns/op	       0 B/op	       0 allocs/op
BenchmarkCVSS20EnvironmentalScore-4     	15307656	       79.48 ns/op	       0 B/op	       0 allocs/op
```

BenchmarkParseVector_Base-4             	 1458514	       843.4 ns/op	     352 B/op	       1 allocs/op
BenchmarkParseVector_WithTempAndEnv-4   	  703789	        2067 ns/op	     352 B/op	       1 allocs/op
BenchmarkCVSS30Vector-4                 	 4587404	       237.0 ns/op	      96 B/op	       1 allocs/op
BenchmarkCVSS30Get-4                    	26877397	       51.38 ns/op	       0 B/op	       0 allocs/op
BenchmarkCVSS30Set-4                    	32284153	       38.53 ns/op	       0 B/op	       0 allocs/op
BenchmarkCVSS30BaseScore-4              	 8275440	       145.4 ns/op	       0 B/op	       0 allocs/op
BenchmarkCVSS30TemporalScore-4          	 6054021	       195.7 ns/op	       0 B/op	       0 allocs/op
BenchmarkCVSS30EnvironmentalScore-4     	 6230708	       191.2 ns/op	       0 B/op	       0 allocs/op
BenchmarkParseVector_Base-4             	 1445559	       825.3 ns/op	     352 B/op	       1 allocs/op
BenchmarkParseVector_WithTempAndEnv-4   	  658578	        1836 ns/op	     352 B/op	       1 allocs/op
BenchmarkCVSS31Vector-4                 	 5087984	       244.1 ns/op	      96 B/op	       1 allocs/op
BenchmarkCVSS31Get-4                    	28350058	       41.40 ns/op	       0 B/op	       0 allocs/op
BenchmarkCVSS31Set-4                    	30340425	       40.16 ns/op	       0 B/op	       0 allocs/op
BenchmarkCVSS31BaseScore-4              	 8535666	       139.3 ns/op	       0 B/op	       0 allocs/op
BenchmarkCVSS31TemporalScore-4          	 6004561	       189.7 ns/op	       0 B/op	       0 allocs/op
BenchmarkCVSS31EnvironmentalScore-4     	 5937879	       184.5 ns/op	       0 B/op	       0 allocs/op