Skip to content

Commit

Permalink
internal/lsp/command: add VulncheckArgs/Result types
Browse files Browse the repository at this point in the history
And move types defined in gopls/internal/vulncheck
to internal/lsp/command so VulncheckResult can use them.

Another approach considered is to encode Vuln as a
json raw message. However, presenting the data structure
in gopls api documentation is too nice to give up.

Updates golang/vscode-go#2096
Updates golang/go#50577

Change-Id: I8587d19f9c47cf786dacaae8cfe1727c77cda711
Reviewed-on: https://go-review.googlesource.com/c/tools/+/395575
Trust: Hyang-Ah Hana Kim <[email protected]>
Run-TryBot: Hyang-Ah Hana Kim <[email protected]>
Reviewed-by: Jonathan Amsterdam <[email protected]>
Reviewed-by: Robert Findley <[email protected]>
gopls-CI: kokoro <[email protected]>
TryBot-Result: Gopher Robot <[email protected]>
  • Loading branch information
hyangah committed Mar 24, 2022
1 parent 84a0321 commit 4737f45
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 61 deletions.
59 changes: 4 additions & 55 deletions gopls/internal/vulncheck/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,64 +17,13 @@ import (

"golang.org/x/exp/vulncheck"
"golang.org/x/tools/go/packages"
"golang.org/x/tools/internal/lsp/protocol"
"golang.org/x/tools/internal/span"
"golang.org/x/tools/internal/lsp/command"
"golang.org/x/vuln/client"
)

// CallStack models a trace of function calls starting
// with a client function or method and ending with a
// call to a vulnerable symbol.
type CallStack []StackEntry

// StackEntry models an element of a call stack.
type StackEntry struct {
// See golang.org/x/exp/vulncheck.StackEntry.

// User-friendly representation of function/method names.
// e.g. package.funcName, package.(recvType).methodName, ...
Name string
URI span.URI
Pos protocol.Position // Start position. (0-based. Column is always 0)
}

// Vuln models an osv.Entry and representative call stacks.
type Vuln struct {
// ID is the vulnerability ID (osv.Entry.ID).
// https://ossf.github.io/osv-schema/#id-modified-fields
ID string `json:"id,omitempty"`
// Details is the description of the vulnerability (osv.Entry.Details).
// https://ossf.github.io/osv-schema/#summary-details-fields
Details string `json:"details,omitempty"`
// Aliases are alternative IDs of the vulnerability.
// https://ossf.github.io/osv-schema/#aliases-field
Aliases []string `json:"aliases,omitempty"`

// Symbol is the name of the detected vulnerable function or method.
Symbol string `json:"symbol,omitempty"`
// PkgPath is the package path of the detected Symbol.
PkgPath string `json:"pkg_path,omitempty"`
// ModPath is the module path corresponding to PkgPath.
// TODO: don't we need explicit module version?
// TODO: how do we specify standard library's vulnerability?
ModPath string `json:"mod_path,omitempty"`

// URL is the URL for more info about the information.
// Either the database specific URL or the one of the URLs
// included in osv.Entry.References.
URL string `json:"url,omitempty"`

// Current is the current module version.
CurrentVersion string `json:"current_version,omitempty"`

// Fixed is the minimum module version that contains the fix.
FixedVersion string `json:"fixed_version,omitempty"`

// Example call stacks.
CallStacks []CallStack `json:"call_stacks,omitempty"`

// TODO: import graph & module graph.
}
type Vuln = command.Vuln
type CallStack = command.CallStack
type StackEntry = command.StackEntry

// cmd is an in-process govulncheck command runner
// that uses the provided client.Client.
Expand Down
6 changes: 3 additions & 3 deletions gopls/internal/vulncheck/command_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,15 +123,15 @@ type report struct {
func toReport(v Vuln) report {
var r = report{Vuln: v}
for _, s := range v.CallStacks {
r.CallStacksStr = append(r.CallStacksStr, s.String())
r.CallStacksStr = append(r.CallStacksStr, CallStackString(s))
}
return r
}

func (callstack CallStack) String() string {
func CallStackString(callstack CallStack) string {
var b bytes.Buffer
for _, entry := range callstack {
fname := filepath.Base(entry.URI.Filename())
fname := filepath.Base(entry.URI.SpanURI().Filename())
fmt.Fprintf(&b, "%v (%v:%d)\n", entry.Name, fname, entry.Pos.Line)
}
return b.String()
Expand Down
5 changes: 2 additions & 3 deletions gopls/internal/vulncheck/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import (

"golang.org/x/exp/vulncheck"
"golang.org/x/tools/internal/lsp/protocol"
"golang.org/x/tools/internal/span"
"golang.org/x/vuln/osv"
)

Expand Down Expand Up @@ -107,11 +106,11 @@ func href(vuln *osv.Entry) string {
return fmt.Sprintf("https://pkg.go.dev/vuln/%s", vuln.ID)
}

func filenameToURI(pos *token.Position) span.URI {
func filenameToURI(pos *token.Position) protocol.DocumentURI {
if pos == nil || pos.Filename == "" {
return ""
}
return span.URIFromPath(pos.Filename)
return protocol.URIFromPath(pos.Filename)
}

func posToPosition(pos *token.Position) (p protocol.Position) {
Expand Down
70 changes: 70 additions & 0 deletions internal/lsp/command/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -307,3 +307,73 @@ type DebuggingResult struct {
// will be empty.
URLs []string
}

type VulncheckArgs struct {
// Dir is the directory from which vulncheck will run from.
Dir protocol.DocumentURI

// Package pattern. E.g. "", ".", "./...".
Pattern string

// TODO: Flag []string (flags accepted by govulncheck, e.g., -tests)
// TODO: Format string (json, text)
}

type VulncheckResult struct {
Vuln []Vuln

// TODO: Text string format output?
}

// CallStack models a trace of function calls starting
// with a client function or method and ending with a
// call to a vulnerable symbol.
type CallStack []StackEntry

// StackEntry models an element of a call stack.
type StackEntry struct {
// See golang.org/x/exp/vulncheck.StackEntry.

// User-friendly representation of function/method names.
// e.g. package.funcName, package.(recvType).methodName, ...
Name string
URI protocol.DocumentURI
Pos protocol.Position // Start position. (0-based. Column is always 0)
}

// Vuln models an osv.Entry and representative call stacks.
type Vuln struct {
// ID is the vulnerability ID (osv.Entry.ID).
// https://ossf.github.io/osv-schema/#id-modified-fields
ID string `json:"id,omitempty"`
// Details is the description of the vulnerability (osv.Entry.Details).
// https://ossf.github.io/osv-schema/#summary-details-fields
Details string `json:"details,omitempty"`
// Aliases are alternative IDs of the vulnerability.
// https://ossf.github.io/osv-schema/#aliases-field
Aliases []string `json:"aliases,omitempty"`

// Symbol is the name of the detected vulnerable function or method.
Symbol string `json:"symbol,omitempty"`
// PkgPath is the package path of the detected Symbol.
PkgPath string `json:"pkg_path,omitempty"`
// ModPath is the module path corresponding to PkgPath.
// TODO: how do we specify standard library's vulnerability?
ModPath string `json:"mod_path,omitempty"`

// URL is the URL for more info about the information.
// Either the database specific URL or the one of the URLs
// included in osv.Entry.References.
URL string `json:"url,omitempty"`

// Current is the current module version.
CurrentVersion string `json:"current_version,omitempty"`

// Fixed is the minimum module version that contains the fix.
FixedVersion string `json:"fixed_version,omitempty"`

// Example call stacks.
CallStacks []CallStack `json:"call_stacks,omitempty"`

// TODO: import graph & module graph.
}

0 comments on commit 4737f45

Please sign in to comment.