diff --git a/tm2/pkg/std/memfile.go b/tm2/pkg/std/memfile.go index 5935428ac28..5655876c9bb 100644 --- a/tm2/pkg/std/memfile.go +++ b/tm2/pkg/std/memfile.go @@ -37,11 +37,9 @@ func (mempkg *MemPackage) IsEmpty() bool { return len(mempkg.Files) == 0 } -const rePathPart = `[a-z][a-z0-9_]*` - var ( rePkgName = regexp.MustCompile(`^[a-z][a-z0-9_]*$`) - rePkgOrRlmPath = regexp.MustCompile(`gno\.land/(?:p|r)(?:/` + rePathPart + `)+`) + rePkgOrRlmPath = regexp.MustCompile(`^gno\.land\/(?:p|r)(?:\/_?[a-z]+[a-z0-9_]*)+$`) reFileName = regexp.MustCompile(`^([a-zA-Z0-9_]*\.[a-z0-9_\.]*|LICENSE|README)$`) ) diff --git a/tm2/pkg/std/memfile_test.go b/tm2/pkg/std/memfile_test.go index 44031cd1b8b..375e0d1a41a 100644 --- a/tm2/pkg/std/memfile_test.go +++ b/tm2/pkg/std/memfile_test.go @@ -51,3 +51,152 @@ func TestMemPackage_Validate(t *testing.T) { }) } } + +func TestRePkgOrRlmPath(t *testing.T) { + t.Parallel() + + testTable := []struct { + desc, in string + expected bool + }{ + { + desc: "Valid p", + in: "gno.land/p/path/path", + expected: true, + }, + { + desc: "Valid r", + in: "gno.land/r/path/path", + expected: true, + }, + { + desc: "Leading Underscore", + in: "gno.land/r/path/_path", + expected: true, + }, + { + desc: "Trailing Underscore", + in: "gno.land/r/path/path_", + expected: true, + }, + { + desc: "Underscore in Between", + in: "gno.land/r/path/p_ath", + expected: true, + }, + { + desc: "Invalid With Underscore 1", + in: "gno.land/r/path/_", + expected: false, + }, + { + desc: "Invalid With Underscore 2", + in: "gno.land/r/path/_/_", + expected: false, + }, + { + desc: "Invalid With Underscore 3", + in: "gno.land/r/path/__/path", + expected: false, + }, + { + desc: "Invalid With Hyphen", + in: "gno.land/r/path/pa-th", + expected: false, + }, + { + desc: "Invalid x", + in: "gno.land/x/path/path", + expected: false, + }, + { + desc: "Missing Path 1", + in: "gno.land/p", + expected: false, + }, + { + desc: "Missing Path 2", + in: "gno.land/p/", + expected: false, + }, + { + desc: "Invalid domain", + in: "github.com/p/path/path", + expected: false, + }, + { + desc: "Special Character 1", + in: "gno.land/p/p@th/abc/def", + expected: false, + }, + { + desc: "Special Character 2", + in: "gno.land/p/p&th/abc/def", + expected: false, + }, + { + desc: "Special Character 3", + in: "gno.land/p/p&%$#h/abc/def", + expected: false, + }, + { + desc: "Leading Number", + in: "gno.land/p/1Path/abc/def", + expected: false, + }, + { + desc: "Uppercase Letters", + in: "gno.land/p/PaTh/abc/def", + expected: false, + }, + { + desc: "Empty Path Part", + in: "gno.land/p/path//def", + expected: false, + }, + { + desc: "Trailing Slash", + in: "gno.land/p/path/abc/def/", + expected: false, + }, + { + desc: "Extra Slash(s)", + in: "gno.land/p/path///abc/def", + expected: false, + }, + { + desc: "Valid Long path", + in: "gno.land/r/very/very/very/long/path", + expected: true, + }, + { + desc: "Long Path With Special Character 1", + in: "gno.land/r/very/very/very/long/p@th", + expected: false, + }, + { + desc: "Long Path With Special Character 2", + in: "gno.land/r/very/very/v%ry/long/path", + expected: false, + }, + { + desc: "Long Path With Trailing Slash", + in: "gno.land/r/very/very/very/long/path/", + expected: false, + }, + { + desc: "Long Path With Empty Path Part", + in: "gno.land/r/very/very/very//long/path/", + expected: false, + }, + } + + for _, tc := range testTable { + tc := tc + t.Run(tc.desc, func(t *testing.T) { + t.Parallel() + + assert.Equal(t, tc.expected, rePkgOrRlmPath.MatchString(tc.in)) + }) + } +}