src

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

query.go (1893B)


      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 scan
      6 
      7 import (
      8 	"context"
      9 	"fmt"
     10 	"regexp"
     11 
     12 	"golang.org/x/vuln/internal/client"
     13 	"golang.org/x/vuln/internal/govulncheck"
     14 	isem "golang.org/x/vuln/internal/semver"
     15 )
     16 
     17 // runQuery reports vulnerabilities that apply to the queries in the config.
     18 func runQuery(ctx context.Context, handler govulncheck.Handler, cfg *config, c *client.Client) error {
     19 	reqs := make([]*client.ModuleRequest, len(cfg.patterns))
     20 	for i, query := range cfg.patterns {
     21 		mod, ver, err := parseModuleQuery(query)
     22 		if err != nil {
     23 			return err
     24 		}
     25 		if err := handler.Progress(queryProgressMessage(mod, ver)); err != nil {
     26 			return err
     27 		}
     28 		reqs[i] = &client.ModuleRequest{
     29 			Path: mod, Version: ver,
     30 		}
     31 	}
     32 
     33 	resps, err := c.ByModules(ctx, reqs)
     34 	if err != nil {
     35 		return err
     36 	}
     37 
     38 	ids := make(map[string]bool)
     39 	for _, resp := range resps {
     40 		for _, entry := range resp.Entries {
     41 			if _, ok := ids[entry.ID]; !ok {
     42 				err := handler.OSV(entry)
     43 				if err != nil {
     44 					return err
     45 				}
     46 				ids[entry.ID] = true
     47 			}
     48 		}
     49 	}
     50 
     51 	return nil
     52 }
     53 
     54 func queryProgressMessage(module, version string) *govulncheck.Progress {
     55 	return &govulncheck.Progress{
     56 		Message: fmt.Sprintf("Looking up vulnerabilities in %s at %s...", module, version),
     57 	}
     58 }
     59 
     60 var modQueryRegex = regexp.MustCompile(`(.+)@(.+)`)
     61 
     62 func parseModuleQuery(pattern string) (_ string, _ string, err error) {
     63 	matches := modQueryRegex.FindStringSubmatch(pattern)
     64 	// matches should be [module@version, module, version]
     65 	if len(matches) != 3 {
     66 		return "", "", fmt.Errorf("invalid query %s: must be of the form module@version", pattern)
     67 	}
     68 	mod, ver := matches[1], matches[2]
     69 	if !isem.Valid(ver) {
     70 		return "", "", fmt.Errorf("version %s is not valid semver", ver)
     71 	}
     72 
     73 	return mod, ver, nil
     74 }