reference: remove support for deprecated "shortid" refs

The "shortid" syntax was added in d26a3b37a6,
and allowed for matching an image on its ID prefix (this is before images were
content-addressable). With the introduction of content-addressable references,
this syntax became problematic, and Docker deprecated this syntax in 2016
(Docker v1.13.0) through commit; 5fc71599a0

> The `repository:shortid` syntax for referencing images is very little used,
> collides with tag references, and can be confused with digest references.

Support for this syntax was removed in 2017 (Docker 17.12) through commit:
a942c92dd7

containerd uses a fork of the reference package with this syntax removed, and
does not support this syntax:
901bcb2231

This patch removes the deprecated syntax, the ParseAnyReferenceWithSet function,
and the ShortIdentifierRegexp regex.

As there are no external consumers for this function, nor the regexp, I'm
skipping a deprecation cycle for this;

- https://grep.app/search?q=.ShortIdentifierRegexp
- https://grep.app/search?q=.ParseAnyReferenceWithSet%28

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
Sebastiaan van Stijn 2022-11-06 20:21:55 +01:00
parent e3509fc1de
commit 6d4f62d7fd
No known key found for this signature in database
GPG key ID: 76698F39D527CE8C
4 changed files with 1 additions and 115 deletions

View file

@ -4,7 +4,6 @@ import (
"fmt" "fmt"
"strings" "strings"
"github.com/distribution/distribution/v3/digestset"
"github.com/opencontainers/go-digest" "github.com/opencontainers/go-digest"
) )
@ -179,20 +178,3 @@ func ParseAnyReference(ref string) (Reference, error) {
return ParseNormalizedNamed(ref) return ParseNormalizedNamed(ref)
} }
// ParseAnyReferenceWithSet parses a reference string as a possible short
// identifier to be matched in a digest set, a full digest, or familiar name.
func ParseAnyReferenceWithSet(ref string, ds *digestset.Set) (Reference, error) {
if ok := anchoredShortIdentifierRegexp.MatchString(ref); ok {
dgst, err := ds.Lookup(ref)
if err == nil {
return digestReference(dgst), nil
}
} else {
if dgst, err := digest.Parse(ref); err == nil {
return digestReference(dgst), nil
}
}
return ParseNormalizedNamed(ref)
}

View file

@ -4,7 +4,6 @@ import (
"strconv" "strconv"
"testing" "testing"
"github.com/distribution/distribution/v3/digestset"
"github.com/opencontainers/go-digest" "github.com/opencontainers/go-digest"
) )
@ -360,7 +359,6 @@ func TestParseAnyReference(t *testing.T) {
Reference string Reference string
Equivalent string Equivalent string
Expected Reference Expected Reference
Digests []digest.Digest
}{ }{
{ {
Reference: "redis", Reference: "redis",
@ -416,62 +414,16 @@ func TestParseAnyReference(t *testing.T) {
Reference: "dbcc1c35ac38df41fd2f5e4130b32ffdb93ebae8b3dbe638c23575912276fc9", Reference: "dbcc1c35ac38df41fd2f5e4130b32ffdb93ebae8b3dbe638c23575912276fc9",
Equivalent: "docker.io/library/dbcc1c35ac38df41fd2f5e4130b32ffdb93ebae8b3dbe638c23575912276fc9", Equivalent: "docker.io/library/dbcc1c35ac38df41fd2f5e4130b32ffdb93ebae8b3dbe638c23575912276fc9",
}, },
{
Reference: "dbcc1c35ac38df41fd2f5e4130b32ffdb93ebae8b3dbe638c23575912276fc9",
Expected: digestReference("sha256:dbcc1c35ac38df41fd2f5e4130b32ffdb93ebae8b3dbe638c23575912276fc9c"),
Equivalent: "sha256:dbcc1c35ac38df41fd2f5e4130b32ffdb93ebae8b3dbe638c23575912276fc9c",
Digests: []digest.Digest{
digest.Digest("sha256:dbcc1c35ac38df41fd2f5e4130b32ffdb93ebae8b3dbe638c23575912276fc9c"),
digest.Digest("sha256:abcc1c35ac38df41fd2f5e4130b32ffdb93ebae8b3dbe638c23575912276fc9c"),
},
},
{
Reference: "dbcc1c35ac38df41fd2f5e4130b32ffdb93ebae8b3dbe638c23575912276fc9",
Equivalent: "docker.io/library/dbcc1c35ac38df41fd2f5e4130b32ffdb93ebae8b3dbe638c23575912276fc9",
Digests: []digest.Digest{
digest.Digest("sha256:abcc1c35ac38df41fd2f5e4130b32ffdb93ebae8b3dbe638c23575912276fc9c"),
},
},
{
Reference: "dbcc1c",
Expected: digestReference("sha256:dbcc1c35ac38df41fd2f5e4130b32ffdb93ebae8b3dbe638c23575912276fc9c"),
Equivalent: "sha256:dbcc1c35ac38df41fd2f5e4130b32ffdb93ebae8b3dbe638c23575912276fc9c",
Digests: []digest.Digest{
digest.Digest("sha256:dbcc1c35ac38df41fd2f5e4130b32ffdb93ebae8b3dbe638c23575912276fc9c"),
digest.Digest("sha256:abcc1c35ac38df41fd2f5e4130b32ffdb93ebae8b3dbe638c23575912276fc9c"),
},
},
{ {
Reference: "dbcc1", Reference: "dbcc1",
Equivalent: "docker.io/library/dbcc1", Equivalent: "docker.io/library/dbcc1",
Digests: []digest.Digest{
digest.Digest("sha256:dbcc1c35ac38df41fd2f5e4130b32ffdb93ebae8b3dbe638c23575912276fc9c"),
digest.Digest("sha256:abcc1c35ac38df41fd2f5e4130b32ffdb93ebae8b3dbe638c23575912276fc9c"),
},
},
{
Reference: "dbcc1c",
Equivalent: "docker.io/library/dbcc1c",
Digests: []digest.Digest{
digest.Digest("sha256:abcc1c35ac38df41fd2f5e4130b32ffdb93ebae8b3dbe638c23575912276fc9c"),
},
}, },
} }
for _, tcase := range tcases { for _, tcase := range tcases {
var ref Reference var ref Reference
var err error var err error
if len(tcase.Digests) == 0 { ref, err = ParseAnyReference(tcase.Reference)
ref, err = ParseAnyReference(tcase.Reference)
} else {
ds := digestset.NewSet()
for _, dgst := range tcase.Digests {
if err := ds.Add(dgst); err != nil {
t.Fatalf("Error adding digest %s: %v", dgst.String(), err)
}
}
ref, err = ParseAnyReferenceWithSet(tcase.Reference, ds)
}
if err != nil { if err != nil {
t.Fatalf("Error parsing reference %s: %v", tcase.Reference, err) t.Fatalf("Error parsing reference %s: %v", tcase.Reference, err)
} }

View file

@ -112,22 +112,10 @@ var (
// are like digests without the algorithm, since sha256 is used. // are like digests without the algorithm, since sha256 is used.
IdentifierRegexp = regexp.MustCompile(identifier) IdentifierRegexp = regexp.MustCompile(identifier)
shortIdentifier = `([a-f0-9]{6,64})`
// ShortIdentifierRegexp is the format used to represent a prefix
// of an identifier. A prefix may be used to match a sha256 identifier
// within a list of trusted identifiers.
ShortIdentifierRegexp = regexp.MustCompile(shortIdentifier)
anchoredIdentifier = anchored(identifier) anchoredIdentifier = anchored(identifier)
// anchoredIdentifierRegexp is used to check or match an // anchoredIdentifierRegexp is used to check or match an
// identifier value, anchored at start and end of string. // identifier value, anchored at start and end of string.
anchoredIdentifierRegexp = regexp.MustCompile(anchoredIdentifier) anchoredIdentifierRegexp = regexp.MustCompile(anchoredIdentifier)
anchoredShortIdentifier = anchored(shortIdentifier)
// anchoredShortIdentifierRegexp is used to check if a value
// is a possible identifier prefix, anchored at start and end
// of string.
anchoredShortIdentifierRegexp = regexp.MustCompile(anchoredShortIdentifier)
) )
// literal compiles s into a literal regular expression, escaping any regexp // literal compiles s into a literal regular expression, escaping any regexp

View file

@ -550,43 +550,7 @@ func TestIdentifierRegexp(t *testing.T) {
match: false, match: false,
}, },
} }
shortCases := []regexpMatch{
{
input: "da304e823d8ca2b9d863a3c897baeb852ba21ea9a9f1414736394ae7fcaf9821",
match: true,
},
{
input: "7EC43B381E5AEFE6E04EFB0B3F0693FF2A4A50652D64AEC573905F2DB5889A1C",
match: false,
},
{
input: "da304e823d8ca2b9d863a3c897baeb852ba21ea9a9f1414736394ae7fcaf",
match: true,
},
{
input: "sha256:da304e823d8ca2b9d863a3c897baeb852ba21ea9a9f1414736394ae7fcaf9821",
match: false,
},
{
input: "da304e823d8ca2b9d863a3c897baeb852ba21ea9a9f1414736394ae7fcaf98218482",
match: false,
},
{
input: "da304",
match: false,
},
{
input: "da304e",
match: true,
},
}
for i := range fullCases { for i := range fullCases {
checkRegexp(t, anchoredIdentifierRegexp, fullCases[i]) checkRegexp(t, anchoredIdentifierRegexp, fullCases[i])
} }
for i := range shortCases {
checkRegexp(t, anchoredShortIdentifierRegexp, shortCases[i])
}
} }