From 8d1a500303a9dd892301e343c94821207c715fbb Mon Sep 17 00:00:00 2001 From: Richard Burnison Date: Fri, 10 Apr 2015 13:09:08 -0400 Subject: [PATCH] Only use fallback to short IDs when obvious. As reported in #11294, the Docker daemon will execute contains it shouldn't run in the event that a requested tag is present in an image's ID. This leads to the wrong image being started up silently. This change reduces the risk of such a collision by using the short ID iff the actual revOrTag looks like a short ID (not that it necessarily is). Signed-off-by: Richard Burnison --- graph/tags.go | 9 ++++++--- pkg/stringid/stringid.go | 14 +++++++++++--- pkg/stringid/stringid_test.go | 23 ++++++++++++++++++++++- 3 files changed, 39 insertions(+), 7 deletions(-) diff --git a/graph/tags.go b/graph/tags.go index 6346ea8b50..74d86141d4 100644 --- a/graph/tags.go +++ b/graph/tags.go @@ -335,9 +335,12 @@ func (store *TagStore) GetImage(repoName, refOrID string) (*image.Image, error) } // If no matching tag is found, search through images for a matching image id - for _, revision := range repo { - if strings.HasPrefix(revision, refOrID) { - return store.graph.Get(revision) + // iff it looks like a short ID or would look like a short ID + if stringid.IsShortID(stringid.TruncateID(refOrID)) { + for _, revision := range repo { + if strings.HasPrefix(revision, refOrID) { + return store.graph.Get(revision) + } } } diff --git a/pkg/stringid/stringid.go b/pkg/stringid/stringid.go index bf39df9b73..3e6ff2a921 100644 --- a/pkg/stringid/stringid.go +++ b/pkg/stringid/stringid.go @@ -4,19 +4,27 @@ import ( "crypto/rand" "encoding/hex" "io" + "regexp" "strconv" ) +const shortLen = 12 + +// Determine if an arbitrary string *looks like* a short ID. +func IsShortID(id string) bool { + return regexp.MustCompile("^[a-z0-9]{12}$").MatchString(id) +} + // TruncateID returns a shorthand version of a string identifier for convenience. // A collision with other shorthands is very unlikely, but possible. // In case of a collision a lookup with TruncIndex.Get() will fail, and the caller // will need to use a langer prefix, or the full-length Id. func TruncateID(id string) string { - shortLen := 12 + trimTo := shortLen if len(id) < shortLen { - shortLen = len(id) + trimTo = len(id) } - return id[:shortLen] + return id[:trimTo] } // GenerateRandomID returns an unique id diff --git a/pkg/stringid/stringid_test.go b/pkg/stringid/stringid_test.go index 21f8f8a2fb..bcb1365495 100644 --- a/pkg/stringid/stringid_test.go +++ b/pkg/stringid/stringid_test.go @@ -1,6 +1,9 @@ package stringid -import "testing" +import ( + "strings" + "testing" +) func TestGenerateRandomID(t *testing.T) { id := GenerateRandomID() @@ -33,3 +36,21 @@ func TestShortenIdInvalid(t *testing.T) { t.Fatalf("Id returned is incorrect: truncate on %s returned %s", id, truncID) } } + +func TestIsShortIDNonHex(t *testing.T) { + id := "some non-hex value" + if IsShortID(id) { + t.Fatalf("%s is not a short ID", id) + } +} + +func TestIsShortIDNotCorrectSize(t *testing.T) { + id := strings.Repeat("a", shortLen+1) + if IsShortID(id) { + t.Fatalf("%s is not a short ID", id) + } + id = strings.Repeat("a", shortLen-1) + if IsShortID(id) { + t.Fatalf("%s is not a short ID", id) + } +}