From 45c36f3e2c55f09d865841a0c41cfe663efe5e41 Mon Sep 17 00:00:00 2001 From: Ricardo N Feliciano Date: Tue, 7 Feb 2023 00:25:01 -0500 Subject: [PATCH] vcsurl: detect bad URLs without a hostname (#84) --- warden/cmd/repos_add.go | 2 +- warden/vcsurl/parse.go | 40 +++++++++++++++++++++------------------- 2 files changed, 22 insertions(+), 20 deletions(-) diff --git a/warden/cmd/repos_add.go b/warden/cmd/repos_add.go index 25a8db3..22049d2 100644 --- a/warden/cmd/repos_add.go +++ b/warden/cmd/repos_add.go @@ -19,7 +19,7 @@ var ( // ensure the repository URL is valid _, err := vcsurl.Parse(repository) if err != nil { - return fmt.Errorf("The repository URL %s isn't valid.", repository) + return fmt.Errorf("The repository URL %s is invalid: %s", repository, err) } repositoriesFile, _, err := loadRepositoriesFile(repositoriesFileFl) diff --git a/warden/vcsurl/parse.go b/warden/vcsurl/parse.go index 92139dd..3569eb3 100644 --- a/warden/vcsurl/parse.go +++ b/warden/vcsurl/parse.go @@ -2,9 +2,16 @@ package vcsurl import ( "fmt" + "net/url" "strings" + + "golang.org/x/exp/slices" ) +var hosts = []string{ + "github.com", +} + var protocols = [...]string{ "git", "http", @@ -28,36 +35,31 @@ func (this *Repository) ToSSH() string { func Parse(input string) (*Repository, error) { - var repo Repository - if strings.HasSuffix(input, ".git") { input = input[:len(input)-4] } if strings.HasPrefix(input, "git@") { - - input = input[4:] - repo.Host = strings.Split(input, ":")[0] - input = input[len(repo.Host)+1:] + input = strings.Replace(input, ":", "/", 1) + input = strings.Replace(input, "git@", "https://", 1) } - if strings.HasPrefix(input, "https://") { - - input = input[8:] - repo.Host = strings.Split(input, "/")[0] - input = input[len(repo.Host)+1:] - } else if strings.HasPrefix(input, "http://") { + repoURL, err := url.Parse(input) + if err != nil { + return nil, err + } - input = input[7:] - repo.Host = strings.Split(input, "/")[0] - input = input[len(repo.Host)+1:] + if !slices.Contains(hosts, repoURL.Host) { + return nil, fmt.Errorf("%s is not a valid hostname.", repoURL.Host) } - repoParts := strings.Split(input, "/") - repo.Owner = repoParts[0] - repo.Name = repoParts[1] + repoParts := strings.Split(repoURL.Path, "/") - return &repo, nil + return &Repository{ + Host: repoURL.Host, + Owner: repoParts[1], + Name: repoParts[2], + }, nil } func Validate(url string) bool {