fix CVE-2022-23773
Conflict:src/cmd/go/internal/modfetch/coderepo.go;src/cmd/go/internal/modfetch/coderepo_test.go Score:CVE-2022-23773:7.5 Reference:https://go-review.googlesource.com/c/go/+/378400/ Reason:fix CVE-2022-23773
This commit is contained in:
parent
7f42874389
commit
abeaca7a73
77
0002-fix-patch-cmd-go-internal-modfetch-do-not-sho.patch
Normal file
77
0002-fix-patch-cmd-go-internal-modfetch-do-not-sho.patch
Normal file
@ -0,0 +1,77 @@
|
||||
From d57e23e7bd6a8f80ace3f1d668a387cf1bc989f7 Mon Sep 17 00:00:00 2001
|
||||
From: hanchao <hanchao47@huawei.com>
|
||||
Date: Wed, 23 Mar 2022 20:51:31 +0800
|
||||
Subject: [PATCH 2/2] fix patch
|
||||
cmd-go-internal-modfetch-do-not-short-circuit-canoni.patch
|
||||
|
||||
reason:the above patch is to fix CVE-2022-23773, but it does not work with golang1.15,
|
||||
so this patch is used to fix the above issue.
|
||||
|
||||
Conflict:NA
|
||||
Reference:https://go-review.googlesource.com/c/go/+/378400/
|
||||
|
||||
Signed-off-by: hanchao <hanchao47@huawei.com>
|
||||
---
|
||||
src/cmd/go/internal/modfetch/coderepo.go | 24 +++++-------------------
|
||||
1 file changed, 5 insertions(+), 19 deletions(-)
|
||||
|
||||
diff --git a/src/cmd/go/internal/modfetch/coderepo.go b/src/cmd/go/internal/modfetch/coderepo.go
|
||||
index c654b36..def62d7 100644
|
||||
--- a/src/cmd/go/internal/modfetch/coderepo.go
|
||||
+++ b/src/cmd/go/internal/modfetch/coderepo.go
|
||||
@@ -456,11 +456,6 @@ func (r *codeRepo) convert(info *codehost.RevInfo, statVers string) (*RevInfo, e
|
||||
tagPrefix = r.codeDir + "/"
|
||||
}
|
||||
|
||||
- isRetracted, err := r.retractedVersions()
|
||||
- if err != nil {
|
||||
- isRetracted = func(string) bool { return false }
|
||||
- }
|
||||
-
|
||||
// tagToVersion returns the version obtained by trimming tagPrefix from tag.
|
||||
// If the tag is invalid, retracted, or a pseudo-version, tagToVersion returns
|
||||
// an empty version.
|
||||
@@ -523,7 +518,7 @@ func (r *codeRepo) convert(info *codehost.RevInfo, statVers string) (*RevInfo, e
|
||||
}
|
||||
// Save the highest non-retracted canonical tag for the revision.
|
||||
// If we don't find a better match, we'll use it as the canonical version.
|
||||
- if tagIsCanonical && semver.Compare(highestCanonical, v) < 0 && !isRetracted(v) {
|
||||
+ if tagIsCanonical && semver.Compare(highestCanonical, v) < 0 {
|
||||
if module.MatchPathMajor(v, r.pathMajor) || canUseIncompatible(v) {
|
||||
highestCanonical = v
|
||||
}
|
||||
@@ -536,27 +531,18 @@ func (r *codeRepo) convert(info *codehost.RevInfo, statVers string) (*RevInfo, e
|
||||
return checkCanonical(highestCanonical)
|
||||
}
|
||||
|
||||
- // Find the highest tagged version in the revision's history, subject to
|
||||
- // major version and +incompatible constraints. Use that version as the
|
||||
- // pseudo-version base so that the pseudo-version sorts higher. Ignore
|
||||
- // retracted versions.
|
||||
- allowedMajor := func(major string) func(v string) bool {
|
||||
- return func(v string) bool {
|
||||
- return ((major == "" && canUseIncompatible(v)) || semver.Major(v) == major) && !isRetracted(v)
|
||||
- }
|
||||
- }
|
||||
if pseudoBase == "" {
|
||||
var tag string
|
||||
if r.pseudoMajor != "" || canUseIncompatible("") {
|
||||
- tag, _ = r.code.RecentTag(info.Name, tagPrefix, allowedMajor(r.pseudoMajor))
|
||||
+ tag, _ = r.code.RecentTag(info.Name, tagPrefix, r.pseudoMajor)
|
||||
} else {
|
||||
// Allow either v1 or v0, but not incompatible higher versions.
|
||||
- tag, _ = r.code.RecentTag(info.Name, tagPrefix, allowedMajor("v1"))
|
||||
+ tag, _ = r.code.RecentTag(info.Name, tagPrefix, "v1")
|
||||
if tag == "" {
|
||||
- tag, _ = r.code.RecentTag(info.Name, tagPrefix, allowedMajor("v0"))
|
||||
+ tag, _ = r.code.RecentTag(info.Name, tagPrefix, "v0")
|
||||
}
|
||||
}
|
||||
- pseudoBase, _ = tagToVersion(tag)
|
||||
+ pseudoBase, _ = tagToVersion(tag) // empty if the tag is invalid
|
||||
}
|
||||
|
||||
return checkCanonical(PseudoVersion(r.pseudoMajor, pseudoBase, info.Time, info.Short))
|
||||
--
|
||||
2.30.0
|
||||
|
||||
472
0060-cmd-go-internal-modfetch-do-not-short-circuit-canoni.patch
Normal file
472
0060-cmd-go-internal-modfetch-do-not-short-circuit-canoni.patch
Normal file
@ -0,0 +1,472 @@
|
||||
From 2d036d30f6f9290874c9220335e70ef6dec7470d Mon Sep 17 00:00:00 2001
|
||||
From: Bryan Mills <bcmills@google.com>
|
||||
Date: Wed, 23 Mar 2022 20:37:48 +0800
|
||||
Subject: [PATCH 1/2] cmd/go/internal/modfetch: do not short-circuit canonical
|
||||
versions
|
||||
|
||||
Since at least CL 121857, the conversion logic in
|
||||
(*modfetch).codeRepo.Stat has had a short-circuit to use the version
|
||||
requested by the caller if it successfully resolves and is already
|
||||
canonical.
|
||||
|
||||
However, we should not use that version if it refers to a branch
|
||||
instead of a tag, because branches (unlike tags) usually do not refer
|
||||
to a single, stable release: a branch named "v1.0.0" may be for the
|
||||
development of the v1.0.0 release, or for the development of patches
|
||||
based on v1.0.0, but only one commit (perhaps at the end of that
|
||||
branch but possibly not even written yet!) can be that specific
|
||||
version.
|
||||
|
||||
We already have some logic to prefer tags that are semver-equivalent
|
||||
to the version requested by the caller. That more general case
|
||||
suffices for exact equality too so we can eliminate the
|
||||
special-case, fixing the bug and (happily!) also somewhat simplifying
|
||||
the code.
|
||||
|
||||
Fixes #35671
|
||||
Updates #41512
|
||||
|
||||
Change-Id: I2fd290190b8a99a580deec7e26d15659b58a50b0
|
||||
Reviewed-on: https://go-review.googlesource.com/c/go/+/378400
|
||||
Trust: Bryan Mills <bcmills@google.com>
|
||||
Run-TryBot: Bryan Mills <bcmills@google.com>
|
||||
Reviewed-by: Russ Cox <rsc@golang.org>
|
||||
TryBot-Result: Gopher Robot <gobot@golang.org>
|
||||
|
||||
Conflict:src/cmd/go/internal/modfetch/coderepo.go;src/cmd/go/internal/modfetch/coderepo_test.go
|
||||
Reference:https://go-review.googlesource.com/c/go/+/378400/
|
||||
---
|
||||
src/cmd/go/internal/modfetch/coderepo.go | 278 ++++++++++--------
|
||||
src/cmd/go/internal/modfetch/coderepo_test.go | 40 +++
|
||||
2 files changed, 201 insertions(+), 117 deletions(-)
|
||||
|
||||
diff --git a/src/cmd/go/internal/modfetch/coderepo.go b/src/cmd/go/internal/modfetch/coderepo.go
|
||||
index d043903..c654b36 100644
|
||||
--- a/src/cmd/go/internal/modfetch/coderepo.go
|
||||
+++ b/src/cmd/go/internal/modfetch/coderepo.go
|
||||
@@ -298,42 +298,61 @@ func (r *codeRepo) Latest() (*RevInfo, error) {
|
||||
// If statVers is a valid module version, it is used for the Version field.
|
||||
// Otherwise, the Version is derived from the passed-in info and recent tags.
|
||||
func (r *codeRepo) convert(info *codehost.RevInfo, statVers string) (*RevInfo, error) {
|
||||
- info2 := &RevInfo{
|
||||
- Name: info.Name,
|
||||
- Short: info.Short,
|
||||
- Time: info.Time,
|
||||
- }
|
||||
-
|
||||
// If this is a plain tag (no dir/ prefix)
|
||||
// and the module path is unversioned,
|
||||
// and if the underlying file tree has no go.mod,
|
||||
// then allow using the tag with a +incompatible suffix.
|
||||
- var canUseIncompatible func() bool
|
||||
- canUseIncompatible = func() bool {
|
||||
- var ok bool
|
||||
- if r.codeDir == "" && r.pathMajor == "" {
|
||||
+ //
|
||||
+ // (If the version is +incompatible, then the go.mod file must not exist:
|
||||
+ // +incompatible is not an ongoing opt-out from semantic import versioning.)
|
||||
+ incompatibleOk := map[string]bool{}
|
||||
+ canUseIncompatible := func(v string) bool {
|
||||
+ if r.codeDir != "" || r.pathMajor != "" {
|
||||
+ // A non-empty codeDir indicates a module within a subdirectory,
|
||||
+ // which necessarily has a go.mod file indicating the module boundary.
|
||||
+ // A non-empty pathMajor indicates a module path with a major-version
|
||||
+ // suffix, which must match.
|
||||
+ return false
|
||||
+ }
|
||||
+
|
||||
+ ok, seen := incompatibleOk[""]
|
||||
+ if !seen {
|
||||
_, errGoMod := r.code.ReadFile(info.Name, "go.mod", codehost.MaxGoMod)
|
||||
- if errGoMod != nil {
|
||||
- ok = true
|
||||
- }
|
||||
+ ok = (errGoMod != nil)
|
||||
+ incompatibleOk[""] = ok
|
||||
+ }
|
||||
+ if !ok {
|
||||
+ // A go.mod file exists at the repo root.
|
||||
+ return false
|
||||
}
|
||||
- canUseIncompatible = func() bool { return ok }
|
||||
- return ok
|
||||
- }
|
||||
|
||||
- invalidf := func(format string, args ...interface{}) error {
|
||||
- return &module.ModuleError{
|
||||
- Path: r.modPath,
|
||||
- Err: &module.InvalidVersionError{
|
||||
- Version: info2.Version,
|
||||
- Err: fmt.Errorf(format, args...),
|
||||
- },
|
||||
+ // Per https://go.dev/issue/51324, previous versions of the 'go' command
|
||||
+ // didn't always check for go.mod files in subdirectories, so if the user
|
||||
+ // requests a +incompatible version explicitly, we should continue to allow
|
||||
+ // it. Otherwise, if vN/go.mod exists, expect that release tags for that
|
||||
+ // major version are intended for the vN module.
|
||||
+ if v != "" && !strings.HasSuffix(statVers, "+incompatible") {
|
||||
+ major := semver.Major(v)
|
||||
+ ok, seen = incompatibleOk[major]
|
||||
+ if !seen {
|
||||
+ _, errGoModSub := r.code.ReadFile(info.Name, path.Join(major, "go.mod"), codehost.MaxGoMod)
|
||||
+ ok = (errGoModSub != nil)
|
||||
+ incompatibleOk[major] = ok
|
||||
+ }
|
||||
+ if !ok {
|
||||
+ return false
|
||||
+ }
|
||||
}
|
||||
+
|
||||
+ return true
|
||||
}
|
||||
|
||||
- // checkGoMod verifies that the go.mod file for the module exists or does not
|
||||
- // exist as required by info2.Version and the module path represented by r.
|
||||
- checkGoMod := func() (*RevInfo, error) {
|
||||
+ // checkCanonical verifies that the canonical version v is compatible with the
|
||||
+ // module path represented by r, adding a "+incompatible" suffix if needed.
|
||||
+ //
|
||||
+ // If statVers is also canonical, checkCanonical also verifies that v is
|
||||
+ // either statVers or statVers with the added "+incompatible" suffix.
|
||||
+ checkCanonical := func(v string) (*RevInfo, error) {
|
||||
// If r.codeDir is non-empty, then the go.mod file must exist: the module
|
||||
// author — not the module consumer, — gets to decide how to carve up the repo
|
||||
// into modules.
|
||||
@@ -344,73 +363,91 @@ func (r *codeRepo) convert(info *codehost.RevInfo, statVers string) (*RevInfo, e
|
||||
// r.findDir verifies both of these conditions. Execute it now so that
|
||||
// r.Stat will correctly return a notExistError if the go.mod location or
|
||||
// declared module path doesn't match.
|
||||
- _, _, _, err := r.findDir(info2.Version)
|
||||
+ _, _, _, err := r.findDir(v)
|
||||
if err != nil {
|
||||
// TODO: It would be nice to return an error like "not a module".
|
||||
// Right now we return "missing go.mod", which is a little confusing.
|
||||
return nil, &module.ModuleError{
|
||||
Path: r.modPath,
|
||||
Err: &module.InvalidVersionError{
|
||||
- Version: info2.Version,
|
||||
+ Version: v,
|
||||
Err: notExistError{err: err},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
- // If the version is +incompatible, then the go.mod file must not exist:
|
||||
- // +incompatible is not an ongoing opt-out from semantic import versioning.
|
||||
- if strings.HasSuffix(info2.Version, "+incompatible") {
|
||||
- if !canUseIncompatible() {
|
||||
+ invalidf := func(format string, args ...interface{}) error {
|
||||
+ return &module.ModuleError{
|
||||
+ Path: r.modPath,
|
||||
+ Err: &module.InvalidVersionError{
|
||||
+ Version: v,
|
||||
+ Err: fmt.Errorf(format, args...),
|
||||
+ },
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ // Add the +incompatible suffix if needed or requested explicitly, and
|
||||
+ // verify that its presence or absence is appropriate for this version
|
||||
+ // (which depends on whether it has an explicit go.mod file).
|
||||
+
|
||||
+ if v == strings.TrimSuffix(statVers, "+incompatible") {
|
||||
+ v = statVers
|
||||
+ }
|
||||
+ base := strings.TrimSuffix(v, "+incompatible")
|
||||
+ var errIncompatible error
|
||||
+ if !module.MatchPathMajor(base, r.pathMajor) {
|
||||
+ if canUseIncompatible(base) {
|
||||
+ v = base + "+incompatible"
|
||||
+ } else {
|
||||
if r.pathMajor != "" {
|
||||
- return nil, invalidf("+incompatible suffix not allowed: module path includes a major version suffix, so major version must match")
|
||||
+ errIncompatible = invalidf("module path includes a major version suffix, so major version must match")
|
||||
} else {
|
||||
- return nil, invalidf("+incompatible suffix not allowed: module contains a go.mod file, so semantic import versioning is required")
|
||||
+ errIncompatible = invalidf("module contains a go.mod file, so module path must match major version (%q)", path.Join(r.pathPrefix, semver.Major(v)))
|
||||
}
|
||||
}
|
||||
+ } else if strings.HasSuffix(v, "+incompatible") {
|
||||
+ errIncompatible = invalidf("+incompatible suffix not allowed: major version %s is compatible", semver.Major(v))
|
||||
+ }
|
||||
|
||||
- if err := module.CheckPathMajor(strings.TrimSuffix(info2.Version, "+incompatible"), r.pathMajor); err == nil {
|
||||
- return nil, invalidf("+incompatible suffix not allowed: major version %s is compatible", semver.Major(info2.Version))
|
||||
+ if statVers != "" && statVers == module.CanonicalVersion(statVers) {
|
||||
+ // Since the caller-requested version is canonical, it would be very
|
||||
+ // confusing to resolve it to anything but itself, possibly with a
|
||||
+ // "+incompatible" suffix. Error out explicitly.
|
||||
+ if statBase := strings.TrimSuffix(statVers, "+incompatible"); statBase != base {
|
||||
+ return nil, &module.ModuleError{
|
||||
+ Path: r.modPath,
|
||||
+ Err: &module.InvalidVersionError{
|
||||
+ Version: statVers,
|
||||
+ Err: fmt.Errorf("resolves to version %v (%s is not a tag)", v, statBase),
|
||||
+ },
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
- return info2, nil
|
||||
+ if errIncompatible != nil {
|
||||
+ return nil, errIncompatible
|
||||
+ }
|
||||
+
|
||||
+ return &RevInfo{
|
||||
+ Name: info.Name,
|
||||
+ Short: info.Short,
|
||||
+ Time: info.Time,
|
||||
+ Version: v,
|
||||
+ }, nil
|
||||
}
|
||||
|
||||
// Determine version.
|
||||
- //
|
||||
- // If statVers is canonical, then the original call was repo.Stat(statVers).
|
||||
- // Since the version is canonical, we must not resolve it to anything but
|
||||
- // itself, possibly with a '+incompatible' annotation: we do not need to do
|
||||
- // the work required to look for an arbitrary pseudo-version.
|
||||
- if statVers != "" && statVers == module.CanonicalVersion(statVers) {
|
||||
- info2.Version = statVers
|
||||
-
|
||||
- if IsPseudoVersion(info2.Version) {
|
||||
- if err := r.validatePseudoVersion(info, info2.Version); err != nil {
|
||||
- return nil, err
|
||||
- }
|
||||
- return checkGoMod()
|
||||
- }
|
||||
|
||||
- if err := module.CheckPathMajor(info2.Version, r.pathMajor); err != nil {
|
||||
- if canUseIncompatible() {
|
||||
- info2.Version += "+incompatible"
|
||||
- return checkGoMod()
|
||||
- } else {
|
||||
- if vErr, ok := err.(*module.InvalidVersionError); ok {
|
||||
- // We're going to describe why the version is invalid in more detail,
|
||||
- // so strip out the existing “invalid version” wrapper.
|
||||
- err = vErr.Err
|
||||
- }
|
||||
- return nil, invalidf("module contains a go.mod file, so major version must be compatible: %v", err)
|
||||
- }
|
||||
+ if IsPseudoVersion(statVers) {
|
||||
+ if err := r.validatePseudoVersion(info, statVers); err != nil {
|
||||
+ return nil, err
|
||||
}
|
||||
-
|
||||
- return checkGoMod()
|
||||
+ return checkCanonical(statVers)
|
||||
}
|
||||
|
||||
- // statVers is empty or non-canonical, so we need to resolve it to a canonical
|
||||
- // version or pseudo-version.
|
||||
+ // statVers is not a pseudo-version, so we need to either resolve it to a
|
||||
+ // canonical version or verify that it is already a canonical tag
|
||||
+ // (not a branch).
|
||||
|
||||
// Derive or verify a version from a code repo tag.
|
||||
// Tag must have a prefix matching codeDir.
|
||||
@@ -419,9 +456,14 @@ func (r *codeRepo) convert(info *codehost.RevInfo, statVers string) (*RevInfo, e
|
||||
tagPrefix = r.codeDir + "/"
|
||||
}
|
||||
|
||||
+ isRetracted, err := r.retractedVersions()
|
||||
+ if err != nil {
|
||||
+ isRetracted = func(string) bool { return false }
|
||||
+ }
|
||||
+
|
||||
// tagToVersion returns the version obtained by trimming tagPrefix from tag.
|
||||
- // If the tag is invalid or a pseudo-version, tagToVersion returns an empty
|
||||
- // version.
|
||||
+ // If the tag is invalid, retracted, or a pseudo-version, tagToVersion returns
|
||||
+ // an empty version.
|
||||
tagToVersion := func(tag string) (v string, tagIsCanonical bool) {
|
||||
if !strings.HasPrefix(tag, tagPrefix) {
|
||||
return "", false
|
||||
@@ -439,83 +481,85 @@ func (r *codeRepo) convert(info *codehost.RevInfo, statVers string) (*RevInfo, e
|
||||
if v == trimmed {
|
||||
tagIsCanonical = true
|
||||
}
|
||||
-
|
||||
- if err := module.CheckPathMajor(v, r.pathMajor); err != nil {
|
||||
- if canUseIncompatible() {
|
||||
- return v + "+incompatible", tagIsCanonical
|
||||
- }
|
||||
- return "", false
|
||||
- }
|
||||
-
|
||||
return v, tagIsCanonical
|
||||
}
|
||||
|
||||
// If the VCS gave us a valid version, use that.
|
||||
if v, tagIsCanonical := tagToVersion(info.Version); tagIsCanonical {
|
||||
- info2.Version = v
|
||||
- return checkGoMod()
|
||||
+ if info, err := checkCanonical(v); err == nil {
|
||||
+ return info, err
|
||||
+ }
|
||||
}
|
||||
|
||||
// Look through the tags on the revision for either a usable canonical version
|
||||
// or an appropriate base for a pseudo-version.
|
||||
- var pseudoBase string
|
||||
+ var (
|
||||
+ highestCanonical string
|
||||
+ pseudoBase string
|
||||
+ )
|
||||
for _, pathTag := range info.Tags {
|
||||
v, tagIsCanonical := tagToVersion(pathTag)
|
||||
- if tagIsCanonical {
|
||||
- if statVers != "" && semver.Compare(v, statVers) == 0 {
|
||||
- // The user requested a non-canonical version, but the tag for the
|
||||
- // canonical equivalent refers to the same revision. Use it.
|
||||
- info2.Version = v
|
||||
- return checkGoMod()
|
||||
+ if statVers != "" && semver.Compare(v, statVers) == 0 {
|
||||
+ // The tag is equivalent to the version requested by the user.
|
||||
+ if tagIsCanonical {
|
||||
+ // This tag is the canonical form of the requested version,
|
||||
+ // not some other form with extra build metadata.
|
||||
+ // Use this tag so that the resolved version will match exactly.
|
||||
+ // (If it isn't actually allowed, we'll error out in checkCanonical.)
|
||||
+ return checkCanonical(v)
|
||||
} else {
|
||||
- // Save the highest canonical tag for the revision. If we don't find a
|
||||
- // better match, we'll use it as the canonical version.
|
||||
+ // The user explicitly requested something equivalent to this tag. We
|
||||
+ // can't use the version from the tag directly: since the tag is not
|
||||
+ // canonical, it could be ambiguous. For example, tags v0.0.1+a and
|
||||
+ // v0.0.1+b might both exist and refer to different revisions.
|
||||
//
|
||||
- // NOTE: Do not replace this with semver.Max. Despite the name,
|
||||
- // semver.Max *also* canonicalizes its arguments, which uses
|
||||
- // semver.Canonical instead of module.CanonicalVersion and thereby
|
||||
- // strips our "+incompatible" suffix.
|
||||
- if semver.Compare(info2.Version, v) < 0 {
|
||||
- info2.Version = v
|
||||
- }
|
||||
+ // The tag is otherwise valid for the module, so we can at least use it as
|
||||
+ // the base of an unambiguous pseudo-version.
|
||||
+ //
|
||||
+ // If multiple tags match, tagToVersion will canonicalize them to the same
|
||||
+ // base version.
|
||||
+ pseudoBase = v
|
||||
+ }
|
||||
+ }
|
||||
+ // Save the highest non-retracted canonical tag for the revision.
|
||||
+ // If we don't find a better match, we'll use it as the canonical version.
|
||||
+ if tagIsCanonical && semver.Compare(highestCanonical, v) < 0 && !isRetracted(v) {
|
||||
+ if module.MatchPathMajor(v, r.pathMajor) || canUseIncompatible(v) {
|
||||
+ highestCanonical = v
|
||||
}
|
||||
- } else if v != "" && semver.Compare(v, statVers) == 0 {
|
||||
- // The user explicitly requested something equivalent to this tag. We
|
||||
- // can't use the version from the tag directly: since the tag is not
|
||||
- // canonical, it could be ambiguous. For example, tags v0.0.1+a and
|
||||
- // v0.0.1+b might both exist and refer to different revisions.
|
||||
- //
|
||||
- // The tag is otherwise valid for the module, so we can at least use it as
|
||||
- // the base of an unambiguous pseudo-version.
|
||||
- //
|
||||
- // If multiple tags match, tagToVersion will canonicalize them to the same
|
||||
- // base version.
|
||||
- pseudoBase = v
|
||||
}
|
||||
}
|
||||
|
||||
- // If we found any canonical tag for the revision, return it.
|
||||
+ // If we found a valid canonical tag for the revision, return it.
|
||||
// Even if we found a good pseudo-version base, a canonical version is better.
|
||||
- if info2.Version != "" {
|
||||
- return checkGoMod()
|
||||
+ if highestCanonical != "" {
|
||||
+ return checkCanonical(highestCanonical)
|
||||
}
|
||||
|
||||
+ // Find the highest tagged version in the revision's history, subject to
|
||||
+ // major version and +incompatible constraints. Use that version as the
|
||||
+ // pseudo-version base so that the pseudo-version sorts higher. Ignore
|
||||
+ // retracted versions.
|
||||
+ allowedMajor := func(major string) func(v string) bool {
|
||||
+ return func(v string) bool {
|
||||
+ return ((major == "" && canUseIncompatible(v)) || semver.Major(v) == major) && !isRetracted(v)
|
||||
+ }
|
||||
+ }
|
||||
if pseudoBase == "" {
|
||||
var tag string
|
||||
- if r.pseudoMajor != "" || canUseIncompatible() {
|
||||
- tag, _ = r.code.RecentTag(info.Name, tagPrefix, r.pseudoMajor)
|
||||
+ if r.pseudoMajor != "" || canUseIncompatible("") {
|
||||
+ tag, _ = r.code.RecentTag(info.Name, tagPrefix, allowedMajor(r.pseudoMajor))
|
||||
} else {
|
||||
// Allow either v1 or v0, but not incompatible higher versions.
|
||||
- tag, _ = r.code.RecentTag(info.Name, tagPrefix, "v1")
|
||||
+ tag, _ = r.code.RecentTag(info.Name, tagPrefix, allowedMajor("v1"))
|
||||
if tag == "" {
|
||||
- tag, _ = r.code.RecentTag(info.Name, tagPrefix, "v0")
|
||||
+ tag, _ = r.code.RecentTag(info.Name, tagPrefix, allowedMajor("v0"))
|
||||
}
|
||||
}
|
||||
- pseudoBase, _ = tagToVersion(tag) // empty if the tag is invalid
|
||||
+ pseudoBase, _ = tagToVersion(tag)
|
||||
}
|
||||
|
||||
- info2.Version = PseudoVersion(r.pseudoMajor, pseudoBase, info.Time, info.Short)
|
||||
- return checkGoMod()
|
||||
+ return checkCanonical(PseudoVersion(r.pseudoMajor, pseudoBase, info.Time, info.Short))
|
||||
}
|
||||
|
||||
// validatePseudoVersion checks that version has a major version compatible with
|
||||
diff --git a/src/cmd/go/internal/modfetch/coderepo_test.go b/src/cmd/go/internal/modfetch/coderepo_test.go
|
||||
index 9a0cd7d..ee1ec9e 100644
|
||||
--- a/src/cmd/go/internal/modfetch/coderepo_test.go
|
||||
+++ b/src/cmd/go/internal/modfetch/coderepo_test.go
|
||||
@@ -420,6 +420,46 @@ var codeRepoTests = []codeRepoTest{
|
||||
zipSum: "h1:JItBZ+gwA5WvtZEGEbuDL4lUttGtLrs53lmdurq3bOg=",
|
||||
zipFileHash: "9ea9ae1673cffcc44b7fdd3cc89953d68c102449b46c982dbf085e4f2e394da5",
|
||||
},
|
||||
+ {
|
||||
+ // Git branch with a semver name, +incompatible version, and no go.mod file.
|
||||
+ vcs: "git",
|
||||
+ path: "vcs-test.golang.org/go/mod/gitrepo1",
|
||||
+ rev: "v2.3.4+incompatible",
|
||||
+ err: `resolves to version v2.0.1+incompatible (v2.3.4 is not a tag)`,
|
||||
+ },
|
||||
+ {
|
||||
+ // Git branch with a semver name, matching go.mod file, and compatible version.
|
||||
+ vcs: "git",
|
||||
+ path: "vcs-test.golang.org/git/semver-branch.git",
|
||||
+ rev: "v1.0.0",
|
||||
+ err: `resolves to version v0.1.1-0.20220202191944-09c4d8f6938c (v1.0.0 is not a tag)`,
|
||||
+ },
|
||||
+ {
|
||||
+ // Git branch with a semver name, matching go.mod file, and disallowed +incompatible version.
|
||||
+ // The version/tag mismatch takes precedence over the +incompatible mismatched.
|
||||
+ vcs: "git",
|
||||
+ path: "vcs-test.golang.org/git/semver-branch.git",
|
||||
+ rev: "v2.0.0+incompatible",
|
||||
+ err: `resolves to version v0.1.0 (v2.0.0 is not a tag)`,
|
||||
+ },
|
||||
+ {
|
||||
+ // Git branch with a semver name, matching go.mod file, and mismatched version.
|
||||
+ // The version/tag mismatch takes precedence over the +incompatible mismatched.
|
||||
+ vcs: "git",
|
||||
+ path: "vcs-test.golang.org/git/semver-branch.git",
|
||||
+ rev: "v2.0.0",
|
||||
+ err: `resolves to version v0.1.0 (v2.0.0 is not a tag)`,
|
||||
+ },
|
||||
+ {
|
||||
+ // v3.0.0-devel is the same as tag v4.0.0-beta.1, but v4.0.0-beta.1 would
|
||||
+ // not be allowed because it is incompatible and a go.mod file exists.
|
||||
+ // The error message should refer to a valid pseudo-version, not the
|
||||
+ // unusable semver tag.
|
||||
+ vcs: "git",
|
||||
+ path: "vcs-test.golang.org/git/semver-branch.git",
|
||||
+ rev: "v3.0.0-devel",
|
||||
+ err: `resolves to version v0.1.1-0.20220203155313-d59622f6e4d7 (v3.0.0-devel is not a tag)`,
|
||||
+ },
|
||||
}
|
||||
|
||||
func TestCodeRepo(t *testing.T) {
|
||||
--
|
||||
2.30.0
|
||||
|
||||
@ -62,7 +62,7 @@
|
||||
|
||||
Name: golang
|
||||
Version: 1.15.7
|
||||
Release: 10
|
||||
Release: 11
|
||||
Summary: The Go Programming Language
|
||||
License: BSD and Public Domain
|
||||
URL: https://golang.org/
|
||||
@ -205,8 +205,10 @@ Patch6056: 0056-release-branch.go1.16-debug-macho-fail-on-invalid-dy.patch
|
||||
Patch6057: 0057-release-branch.go1.16-math-big-prevent-overflow-in-R.patch
|
||||
Patch6058: 0058-release-branch.go1.16-crypto-elliptic-make-IsOnCurve.patch
|
||||
Patch6059: 0059-release-branch.go1.16-regexp-syntax-reject-very-deep.patch
|
||||
Patch6060: 0060-cmd-go-internal-modfetch-do-not-short-circuit-canoni.patch
|
||||
|
||||
Patch9001: 0001-drop-hard-code-cert.patch
|
||||
Patch9002: 0002-fix-patch-cmd-go-internal-modfetch-do-not-sho.patch
|
||||
|
||||
|
||||
%description
|
||||
@ -438,6 +440,9 @@ fi
|
||||
%files devel -f go-tests.list -f go-misc.list -f go-src.list
|
||||
|
||||
%changelog
|
||||
* Thu Mar 24 2022 hanchao<hanchao47@huawei.com> - 1.15.7-11
|
||||
- fix CVE-2022-23773
|
||||
|
||||
* Fri Mar 11 2022 hanchao<hanchao47@huawei.com> - 1.15.7-10
|
||||
- fix CVE-2022-24921
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user