internal/frontend: redirect searches for Go vulns
If a user searches for something in the form of a Go vuln
ID (e.g. GO-2021-0231), redirect to the page for that vuln.
Change-Id: I496b4c387fb97951312ca58ff61f3a5797c1b4d9
Reviewed-on: https://go-review.googlesource.com/c/pkgsite/+/382095
Trust: Jonathan Amsterdam <jba@google.com>
Run-TryBot: Jonathan Amsterdam <jba@google.com>
TryBot-Result: kokoro <noreply+kokoro@google.com>
Reviewed-by: Julie Qiu <julie@golang.org>
diff --git a/internal/frontend/search.go b/internal/frontend/search.go
index 34e98bc..5e6aeee 100644
--- a/internal/frontend/search.go
+++ b/internal/frontend/search.go
@@ -10,6 +10,7 @@
"fmt"
"net/http"
"path"
+ "regexp"
"sort"
"strings"
"sync"
@@ -303,17 +304,27 @@
return sr
}
+// A regexp that matches Go vuln IDs.
+var goVulnIDRegexp = regexp.MustCompile("^GO-[0-9]{4}-[0-9]{4}$")
+
// searchRequestRedirectPath returns the path that a search request should be
-// redirected to, or the empty string if there is no such path. If the user
-// types an existing package path into the search bar, we will redirect the
-// user to the details page. Standard library packages that only contain one
-// element (such as fmt, errors, etc.) will not redirect, to allow users to
-// search by those terms.
+// redirected to, or the empty string if there is no such path.
+//
+// If the user types an existing package path into the search bar, we will
+// redirect the user to the details page. Standard library packages that only
+// contain one element (such as fmt, errors, etc.) will not redirect, to allow
+// users to search by those terms.
+//
+// If the user types a name that is in the form of a Go vulnerability ID, we will
+// redirect to the page for that ID (whether or not it exists).
func searchRequestRedirectPath(ctx context.Context, ds internal.DataSource, query string) string {
urlSchemeIdx := strings.Index(query, "://")
if urlSchemeIdx > -1 {
query = query[urlSchemeIdx+3:]
}
+ if goVulnIDRegexp.MatchString(query) {
+ return fmt.Sprintf("/vuln/%s", query)
+ }
requestedPath := path.Clean(query)
if !strings.Contains(requestedPath, "/") {
return ""
diff --git a/internal/frontend/search_test.go b/internal/frontend/search_test.go
index 44c3c3f..3552118 100644
--- a/internal/frontend/search_test.go
+++ b/internal/frontend/search_test.go
@@ -378,6 +378,8 @@
{"std does not redirect", "std", ""},
{"non-existent path does not redirect", "github.com/non-existent", ""},
{"trim URL scheme from query", "https://golang.org/x/tools", "/golang.org/x/tools"},
+ {"Go vuln redirects", "GO-1969-0720", "/vuln/GO-1969-0720"},
+ {"not a Go vuln", "somepkg/GO-1969-0720", ""},
} {
t.Run(test.name, func(t *testing.T) {
if got := searchRequestRedirectPath(ctx, testDB, test.query); got != test.want {