Skip to content

Commit 9652794

Browse files
authored
Support common ssh repo format (#878)
* Try ssh repo format * Add tests
1 parent ab71b93 commit 9652794

2 files changed

Lines changed: 84 additions & 6 deletions

File tree

pkg/sources/git/git.go

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,21 @@ func CleanOnError(err *error, path string) {
231231
}
232232
}
233233

234+
func gitURLParse(gitURL string) (*url.URL, error) {
235+
parsedURL, originalError := url.Parse(gitURL)
236+
if originalError != nil {
237+
var err error
238+
gitURLBytes := []byte("ssh://" + gitURL)
239+
colonIndex := bytes.LastIndex(gitURLBytes, []byte(":"))
240+
gitURLBytes[colonIndex] = byte('/')
241+
parsedURL, err = url.Parse(string(gitURLBytes))
242+
if err != nil {
243+
return nil, originalError
244+
}
245+
}
246+
return parsedURL, nil
247+
}
248+
234249
func CloneRepo(userInfo *url.Userinfo, gitUrl string, args ...string) (clonePath string, repo *git.Repository, err error) {
235250
if err = GitCmdCheck(); err != nil {
236251
return
@@ -241,12 +256,13 @@ func CloneRepo(userInfo *url.Userinfo, gitUrl string, args ...string) (clonePath
241256
return
242257
}
243258
defer CleanOnError(&err, clonePath)
244-
cloneURL, err := url.Parse(gitUrl)
259+
cloneURL, err := gitURLParse(gitUrl)
245260
if err != nil {
246-
err = errors.WrapPrefix(err, "could not parse url", 0)
247-
return
261+
return "", nil, err
262+
}
263+
if cloneURL.User == nil {
264+
cloneURL.User = userInfo
248265
}
249-
cloneURL.User = userInfo
250266

251267
gitArgs := []string{"clone", cloneURL.String(), clonePath}
252268
gitArgs = append(gitArgs, args...)
@@ -651,7 +667,7 @@ func PrepareRepoSinceCommit(uriString, commitHash string) (string, bool, error)
651667
// the uriString is github.com, then we query the API for the timestamp of the
652668
// hash and use that to clone.
653669

654-
uri, err := url.Parse(uriString)
670+
uri, err := gitURLParse(uriString)
655671
if err != nil {
656672
return "", false, fmt.Errorf("unable to parse Git URI: %s", err)
657673
}
@@ -715,7 +731,7 @@ func PrepareRepoSinceCommit(uriString, commitHash string) (string, bool, error)
715731
// PrepareRepo clones a repo if possible and returns the cloned repo path.
716732
func PrepareRepo(uriString string) (string, bool, error) {
717733
var path string
718-
uri, err := url.Parse(uriString)
734+
uri, err := gitURLParse(uriString)
719735
if err != nil {
720736
return "", false, fmt.Errorf("unable to parse Git URI: %s", err)
721737
}

pkg/sources/git/git_test.go

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88

99
"github.com/kylelemons/godebug/pretty"
1010
log "github.com/sirupsen/logrus"
11+
"github.com/stretchr/testify/assert"
1112
"google.golang.org/protobuf/types/known/anypb"
1213

1314
"github.com/trufflesecurity/trufflehog/v3/pkg/common"
@@ -494,3 +495,64 @@ func BenchmarkPrepareRepo(b *testing.B) {
494495
_, _, _ = PrepareRepo(uri)
495496
}
496497
}
498+
499+
func TestGitURLParse(t *testing.T) {
500+
for _, tt := range []struct {
501+
url string
502+
host string
503+
user string
504+
password string
505+
port string
506+
path string
507+
scheme string
508+
}{
509+
{
510+
"https://user@github.com/org/repo",
511+
"github.com",
512+
"user",
513+
"",
514+
"",
515+
"/org/repo",
516+
"https",
517+
},
518+
{
519+
"https://user:pass@github.com/org/repo",
520+
"github.com",
521+
"user",
522+
"pass",
523+
"",
524+
"/org/repo",
525+
"https",
526+
},
527+
{
528+
"ssh://user@github.com/org/repo",
529+
"github.com",
530+
"user",
531+
"",
532+
"",
533+
"/org/repo",
534+
"ssh",
535+
},
536+
{
537+
"user@github.com:org/repo",
538+
"github.com",
539+
"user",
540+
"",
541+
"",
542+
"/org/repo",
543+
"ssh",
544+
},
545+
} {
546+
u, err := gitURLParse(tt.url)
547+
if err != nil {
548+
t.Fatal(err)
549+
}
550+
assert.Equal(t, tt.host, u.Host)
551+
assert.Equal(t, tt.user, u.User.Username())
552+
password, _ := u.User.Password()
553+
assert.Equal(t, tt.password, password)
554+
assert.Equal(t, tt.port, u.Port())
555+
assert.Equal(t, tt.path, u.Path)
556+
assert.Equal(t, tt.scheme, u.Scheme)
557+
}
558+
}

0 commit comments

Comments
 (0)