gosrc: validate repo from meta

Fixes CVE-2018-12976.

Change-Id: I6b87ab692915d46ba4f668ab848473de9b054c8a
Reviewed-on: https://go-review.googlesource.com/121358
Reviewed-by: Filippo Valsorda <filippo@golang.org>
diff --git a/gosrc/gosrc.go b/gosrc/gosrc.go
index 9a9e44b..b5173d3 100644
--- a/gosrc/gosrc.go
+++ b/gosrc/gosrc.go
@@ -378,6 +378,9 @@
 	proto := im.repo[:i]
 	clonePath := im.repo[i+len("://"):]
 	repo := strings.TrimSuffix(clonePath, "."+im.vcs)
+	if !IsValidRemotePath(repo) {
+		return nil, fmt.Errorf("bad path from meta: %s", repo)
+	}
 	dirName := importPath[len(im.projectRoot):]
 
 	resolvedPath := repo + dirName
diff --git a/gosrc/gosrc_test.go b/gosrc/gosrc_test.go
index be4acde..d90e798 100644
--- a/gosrc/gosrc_test.go
+++ b/gosrc/gosrc_test.go
@@ -94,6 +94,9 @@
 		`<meta name="go-import" content="myitcv.io/blah2 mod https://raw.githubusercontent.com/myitcv/pubx/master">` +
 		`<meta name="go-source" content="myitcv.io https://github.com/myitcv/x/wiki https://github.com/myitcv/x/tree/master{/dir} https://github.com/myitcv/x/blob/master{/dir}/{file}#L{line}">` +
 		`</head>`,
+
+	// The repo element of go-import includes "../"
+	"http://my.host/pkg": `<head> <meta name="go-import" content="my.host/pkg git http://vcs.net/myhost/../../tmp/pkg.git"></head>`,
 }
 
 var getDynamicTests = []struct {
@@ -221,6 +224,7 @@
 		VCS:          "git",
 		Files:        []*File{{Name: "main.go", BrowseURL: "https://github.com/myitcv/x/blob/master/main.go"}},
 	}},
+	{"my.host/pkg", nil},
 }
 
 type testTransport map[string]string
@@ -293,13 +297,13 @@
 
 		if tt.dir == nil {
 			if err == nil {
-				t.Errorf("getDynamic(client, %q, etag) did not return expected error", tt.importPath)
+				t.Errorf("getDynamic(ctx, client, %q, etag) did not return expected error", tt.importPath)
 			}
 			continue
 		}
 
 		if err != nil {
-			t.Errorf("getDynamic(client, %q, etag) return unexpected error: %v", tt.importPath, err)
+			t.Errorf("getDynamic(ctx, client, %q, etag) return unexpected error: %v", tt.importPath, err)
 			continue
 		}