aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/go/internal/get/vcs.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/go/internal/get/vcs.go')
-rw-r--r--src/cmd/go/internal/get/vcs.go34
1 files changed, 32 insertions, 2 deletions
diff --git a/src/cmd/go/internal/get/vcs.go b/src/cmd/go/internal/get/vcs.go
index 86d2e32efb..dcc7047211 100644
--- a/src/cmd/go/internal/get/vcs.go
+++ b/src/cmd/go/internal/get/vcs.go
@@ -767,8 +767,8 @@ func repoRootForImportDynamic(importPath string, security web.SecurityMode) (*re
}
}
- if !strings.Contains(mmi.RepoRoot, "://") {
- return nil, fmt.Errorf("%s: invalid repo root %q; no scheme", urlStr, mmi.RepoRoot)
+ if err := validateRepoRootScheme(mmi.RepoRoot); err != nil {
+ return nil, fmt.Errorf("%s: invalid repo root %q: %v", urlStr, mmi.RepoRoot, err)
}
rr := &repoRoot{
vcs: vcsByCmd(mmi.VCS),
@@ -782,6 +782,36 @@ func repoRootForImportDynamic(importPath string, security web.SecurityMode) (*re
return rr, nil
}
+// validateRepoRootScheme returns an error if repoRoot does not seem
+// to have a valid URL scheme. At this point we permit things that
+// aren't valid URLs, although later, if not using -insecure, we will
+// restrict repoRoots to be valid URLs. This is only because we've
+// historically permitted them, and people may depend on that.
+func validateRepoRootScheme(repoRoot string) error {
+ end := strings.Index(repoRoot, "://")
+ if end <= 0 {
+ return errors.New("no scheme")
+ }
+
+ // RFC 3986 section 3.1.
+ for i := 0; i < end; i++ {
+ c := repoRoot[i]
+ switch {
+ case 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z':
+ // OK.
+ case '0' <= c && c <= '9' || c == '+' || c == '-' || c == '.':
+ // OK except at start.
+ if i == 0 {
+ return errors.New("invalid scheme")
+ }
+ default:
+ return errors.New("invalid scheme")
+ }
+ }
+
+ return nil
+}
+
var fetchGroup singleflight.Group
var (
fetchCacheMu sync.Mutex