blob: 2f7b678099182fcfd528babbc48cb20ebe7b78b2 [file] [log] [blame]
// Copyright 2022 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build go1.18
// +build go1.18
package main
import (
"embed"
"fmt"
"html/template"
"io"
"golang.org/x/vuln/cmd/govulncheck/internal/govulncheck"
"golang.org/x/vuln/vulncheck"
)
//go:embed static/*
var staticContent embed.FS
func html(w io.Writer, r *vulncheck.Result, ci *govulncheck.CallInfo) error {
tmpl, err := template.New("govulncheck.tmpl").Funcs(template.FuncMap{
"funcName": govulncheck.FuncName,
}).ParseFS(staticContent, "static/govulncheck.tmpl")
if err != nil {
return err
}
type callstack struct {
Summary string
Stack vulncheck.CallStack
}
type vuln struct {
ID string
PkgPath string
CurrentVersion string
FixedVersion string
Reference string
Details string
Stacks []callstack
}
var vulns []*vuln
for _, vg := range ci.VulnGroups {
v0 := vg[0]
vn := &vuln{
ID: v0.OSV.ID,
PkgPath: v0.PkgPath,
CurrentVersion: ci.ModuleVersions[v0.ModPath],
FixedVersion: "v" + govulncheck.LatestFixed(v0.OSV.Affected),
Reference: fmt.Sprintf("https://pkg.go.dev/vuln/%s", v0.OSV.ID),
Details: v0.OSV.Details,
}
// Keep first call stack for each vuln.
for _, v := range vg {
if css := ci.CallStacks[v]; len(css) > 0 {
vn.Stacks = append(vn.Stacks, callstack{
Summary: govulncheck.SummarizeCallStack(css[0], ci.TopPackages, v.PkgPath),
Stack: css[0],
})
}
}
vulns = append(vulns, vn)
}
return tmpl.Execute(w, vulns)
}