src

Go monorepo.
git clone git://code.dwrz.net/src
Log | Files | Refs

affects.go (2252B)


      1 // Copyright 2023 The Go Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style
      3 // license that can be found in the LICENSE file.
      4 
      5 package semver
      6 
      7 import (
      8 	"sort"
      9 
     10 	"golang.org/x/vuln/internal/osv"
     11 )
     12 
     13 func Affects(a []osv.Range, v string) bool {
     14 	if len(a) == 0 {
     15 		// No ranges implies all versions are affected
     16 		return true
     17 	}
     18 	var semverRangePresent bool
     19 	for _, r := range a {
     20 		if r.Type != osv.RangeTypeSemver {
     21 			continue
     22 		}
     23 		semverRangePresent = true
     24 		if ContainsSemver(r, v) {
     25 			return true
     26 		}
     27 	}
     28 	// If there were no semver ranges present we
     29 	// assume that all semvers are affected, similarly
     30 	// to how to we assume all semvers are affected
     31 	// if there are no ranges at all.
     32 	return !semverRangePresent
     33 }
     34 
     35 // ContainsSemver checks if semver version v is in the
     36 // range encoded by ar. If ar is not a semver range,
     37 // returns false. A range is interpreted as a left-closed
     38 // and right-open interval.
     39 //
     40 // Assumes that
     41 //   - exactly one of Introduced or Fixed fields is set
     42 //   - ranges in ar are not overlapping
     43 //   - beginning of time is encoded with .Introduced="0"
     44 //   - no-fix is not an event, as opposed to being an
     45 //     event where Introduced="" and Fixed=""
     46 func ContainsSemver(ar osv.Range, v string) bool {
     47 	if ar.Type != osv.RangeTypeSemver {
     48 		return false
     49 	}
     50 	if len(ar.Events) == 0 {
     51 		return true
     52 	}
     53 
     54 	// Strip and then add the semver prefix so we can support bare versions,
     55 	// versions prefixed with 'v', and versions prefixed with 'go'.
     56 	v = canonicalizeSemverPrefix(v)
     57 
     58 	// Sort events by semver versions. Event for beginning
     59 	// of time, if present, always comes first.
     60 	sort.SliceStable(ar.Events, func(i, j int) bool {
     61 		e1 := ar.Events[i]
     62 		v1 := e1.Introduced
     63 		if v1 == "0" {
     64 			// -inf case.
     65 			return true
     66 		}
     67 		if e1.Fixed != "" {
     68 			v1 = e1.Fixed
     69 		}
     70 
     71 		e2 := ar.Events[j]
     72 		v2 := e2.Introduced
     73 		if v2 == "0" {
     74 			// -inf case.
     75 			return false
     76 		}
     77 		if e2.Fixed != "" {
     78 			v2 = e2.Fixed
     79 		}
     80 
     81 		return Less(v1, v2)
     82 	})
     83 
     84 	var affected bool
     85 	for _, e := range ar.Events {
     86 		if !affected && e.Introduced != "" {
     87 			affected = e.Introduced == "0" || !Less(v, e.Introduced)
     88 		} else if affected && e.Fixed != "" {
     89 			affected = Less(v, e.Fixed)
     90 		}
     91 	}
     92 
     93 	return affected
     94 }