Skip to content

Commit 6ce8bb3

Browse files
tzierbockJay Conrod
authored and
Jay Conrod
committed
cmd/go: validating version format in mod edit
Version strings set by -retract and -exclude are not canonicalized by go mod commands. This change adds validation to go mod edit to prevent invalid version strings from being added to the go.mod file. For golang/go#43280 Change-Id: I3708b7a09111a56effac1fe1165122772e3f2d75 Reviewed-on: https://go-review.googlesource.com/c/mod/+/279394 Run-TryBot: Bryan C. Mills <bcmills@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Jay Conrod <jayconrod@google.com> Reviewed-by: Bryan C. Mills <bcmills@google.com> Trust: Michael Matloob <matloob@golang.org>
1 parent bc388b2 commit 6ce8bb3

File tree

2 files changed

+100
-0
lines changed

2 files changed

+100
-0
lines changed

modfile/rule.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -832,7 +832,16 @@ func (f *File) DropRequire(path string) error {
832832
return nil
833833
}
834834

835+
// AddExclude adds a exclude statement to the mod file. Errors if the provided
836+
// version is not a canonical version string
835837
func (f *File) AddExclude(path, vers string) error {
838+
if !isCanonicalVersion(vers) {
839+
return &module.InvalidVersionError{
840+
Version: vers,
841+
Err: errors.New("must be of the form v1.2.3"),
842+
}
843+
}
844+
836845
var hint *Line
837846
for _, x := range f.Exclude {
838847
if x.Mod.Path == path && x.Mod.Version == vers {
@@ -904,7 +913,22 @@ func (f *File) DropReplace(oldPath, oldVers string) error {
904913
return nil
905914
}
906915

916+
// AddRetract adds a retract statement to the mod file. Errors if the provided
917+
// version interval does not consist of canonical version strings
907918
func (f *File) AddRetract(vi VersionInterval, rationale string) error {
919+
if !isCanonicalVersion(vi.High) {
920+
return &module.InvalidVersionError{
921+
Version: vi.High,
922+
Err: errors.New("must be of the form v1.2.3"),
923+
}
924+
}
925+
if !isCanonicalVersion(vi.Low) {
926+
return &module.InvalidVersionError{
927+
Version: vi.Low,
928+
Err: errors.New("must be of the form v1.2.3"),
929+
}
930+
}
931+
908932
r := &Retract{
909933
VersionInterval: vi,
910934
}
@@ -1061,3 +1085,9 @@ func lineRetractLess(li, lj *Line) bool {
10611085
}
10621086
return semver.Compare(vii.High, vij.High) > 0
10631087
}
1088+
1089+
// isCanonicalVersion tests if the provided version string represents a valid
1090+
// canonical version.
1091+
func isCanonicalVersion(vers string) bool {
1092+
return vers != "" && semver.Canonical(vers) == vers
1093+
}

modfile/rule_test.go

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -568,6 +568,48 @@ var sortBlocksTests = []struct {
568568
},
569569
}
570570

571+
var addRetractValidateVersionTests = []struct {
572+
dsc, low, high string
573+
}{
574+
{
575+
"blank_version",
576+
"",
577+
"",
578+
},
579+
{
580+
"missing_prefix",
581+
"1.0.0",
582+
"1.0.0",
583+
},
584+
{
585+
"non_canonical",
586+
"v1.2",
587+
"v1.2",
588+
},
589+
{
590+
"invalid_range",
591+
"v1.2.3",
592+
"v1.3",
593+
},
594+
}
595+
596+
var addExcludeValidateVersionTests = []struct {
597+
dsc, ver string
598+
}{
599+
{
600+
"blank_version",
601+
"",
602+
},
603+
{
604+
"missing_prefix",
605+
"1.0.0",
606+
},
607+
{
608+
"non_canonical",
609+
"v1.2",
610+
},
611+
}
612+
571613
func TestAddRequire(t *testing.T) {
572614
for _, tt := range addRequireTests {
573615
t.Run(tt.desc, func(t *testing.T) {
@@ -699,3 +741,31 @@ func testEdit(t *testing.T, in, want string, strict bool, transform func(f *File
699741

700742
return f
701743
}
744+
745+
func TestAddRetractValidateVersion(t *testing.T) {
746+
for _, tt := range addRetractValidateVersionTests {
747+
t.Run(tt.dsc, func(t *testing.T) {
748+
f, err := Parse("in", []byte("module m"), nil)
749+
if err != nil {
750+
t.Fatal(err)
751+
}
752+
if err = f.AddRetract(VersionInterval{Low: tt.low, High: tt.high}, ""); err == nil {
753+
t.Fatal("expected AddRetract to complain about version format")
754+
}
755+
})
756+
}
757+
}
758+
759+
func TestAddExcludeValidateVersion(t *testing.T) {
760+
for _, tt := range addExcludeValidateVersionTests {
761+
t.Run(tt.dsc, func(t *testing.T) {
762+
f, err := Parse("in", []byte("module m"), nil)
763+
if err != nil {
764+
t.Fatal(err)
765+
}
766+
if err = f.AddExclude("aa", tt.ver); err == nil {
767+
t.Fatal("expected AddExclude to complain about version format")
768+
}
769+
})
770+
}
771+
}

0 commit comments

Comments
 (0)