mirror of
https://github.com/safedep/vet.git
synced 2025-12-10 00:22:08 -06:00
89 lines
1.8 KiB
Go
89 lines
1.8 KiB
Go
package exceptions
|
|
|
|
import (
|
|
"fmt"
|
|
"hash/fnv"
|
|
"io"
|
|
"strconv"
|
|
"strings"
|
|
"sync"
|
|
"time"
|
|
|
|
"github.com/safedep/vet/gen/exceptionsapi"
|
|
)
|
|
|
|
// Represents an exception rule as per spec with additional details
|
|
type exceptionRule struct {
|
|
spec *exceptionsapi.Exception
|
|
expiry time.Time
|
|
}
|
|
|
|
// In-memory store of exceptions to be used for package hash and exception ID
|
|
// based lookup for fast matching and avoid duplicates
|
|
type exceptionStore struct {
|
|
m sync.Mutex
|
|
rules map[string]map[string]*exceptionRule
|
|
}
|
|
|
|
// Represents an exceptions loader interface to support loading exceptions
|
|
// from multiple sources
|
|
type exceptionsLoader interface {
|
|
// Read an exception rule, return io.EOF on done
|
|
Read() (*exceptionRule, error)
|
|
}
|
|
|
|
// Global exceptions store
|
|
var globalExceptions *exceptionStore
|
|
|
|
// Initialize the global exceptions cache
|
|
func init() {
|
|
initStore()
|
|
}
|
|
|
|
func initStore() {
|
|
globalExceptions = &exceptionStore{
|
|
rules: make(map[string]map[string]*exceptionRule),
|
|
}
|
|
}
|
|
|
|
func Load(loader exceptionsLoader) error {
|
|
globalExceptions.m.Lock()
|
|
defer globalExceptions.m.Unlock()
|
|
|
|
for {
|
|
rule, err := loader.Read()
|
|
if err != nil {
|
|
if err == io.EOF {
|
|
break
|
|
} else {
|
|
return err
|
|
}
|
|
}
|
|
|
|
h := pkgHash(rule.spec.GetEcosystem(), rule.spec.GetName())
|
|
if _, ok := globalExceptions.rules[h]; ok {
|
|
if _, ok = globalExceptions.rules[h][rule.spec.GetId()]; ok {
|
|
continue
|
|
}
|
|
} else {
|
|
globalExceptions.rules[h] = make(map[string]*exceptionRule)
|
|
}
|
|
|
|
if rule.expiry.UTC().Before(time.Now().UTC()) {
|
|
continue
|
|
}
|
|
|
|
globalExceptions.rules[h][rule.spec.GetId()] = rule
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func pkgHash(ecosystem, name string) string {
|
|
h := fnv.New64a()
|
|
h.Write([]byte(fmt.Sprintf("%s/%s",
|
|
strings.ToLower(ecosystem), strings.ToLower(name))))
|
|
|
|
return strconv.FormatUint(h.Sum64(), 16)
|
|
}
|