mirror of
https://github.com/moby/moby.git
synced 2026-01-11 10:41:43 +00:00
layer: rm regexp use
Replace the regexp checking ID validity with a function. The benefits are: - function is faster (up to 10x faster with less allocations); - no init overhead to compile the regexp; Add a test case. Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
This commit is contained in:
@@ -7,7 +7,6 @@ import (
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
@@ -18,14 +17,11 @@ import (
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
var (
|
||||
stringIDRegexp = regexp.MustCompile(`^[a-f0-9]{64}(-init)?$`)
|
||||
supportedAlgorithms = []digest.Algorithm{
|
||||
digest.SHA256,
|
||||
// digest.SHA384, // Currently not used
|
||||
// digest.SHA512, // Currently not used
|
||||
}
|
||||
)
|
||||
var supportedAlgorithms = []digest.Algorithm{
|
||||
digest.SHA256,
|
||||
// digest.SHA384, // Currently not used
|
||||
// digest.SHA512, // Currently not used
|
||||
}
|
||||
|
||||
type fileMetadataStore struct {
|
||||
root string
|
||||
@@ -262,7 +258,7 @@ func (fms *fileMetadataStore) GetMountID(mount string) (string, error) {
|
||||
}
|
||||
content := strings.TrimSpace(string(contentBytes))
|
||||
|
||||
if !stringIDRegexp.MatchString(content) {
|
||||
if !isValidID(content) {
|
||||
return "", errors.New("invalid mount id value")
|
||||
}
|
||||
|
||||
@@ -279,7 +275,7 @@ func (fms *fileMetadataStore) GetInitID(mount string) (string, error) {
|
||||
}
|
||||
content := strings.TrimSpace(string(contentBytes))
|
||||
|
||||
if !stringIDRegexp.MatchString(content) {
|
||||
if !isValidID(content) {
|
||||
return "", errors.New("invalid init id value")
|
||||
}
|
||||
|
||||
@@ -431,3 +427,18 @@ func (fms *fileMetadataStore) Remove(layer ChainID, cache string) error {
|
||||
func (fms *fileMetadataStore) RemoveMount(mount string) error {
|
||||
return os.RemoveAll(fms.getMountDirectory(mount))
|
||||
}
|
||||
|
||||
// isValidID checks if mount/init id is valid. It is similar to
|
||||
// regexp.MustCompile(`^[a-f0-9]{64}(-init)?$`).MatchString(id).
|
||||
func isValidID(id string) bool {
|
||||
id = strings.TrimSuffix(id, "-init")
|
||||
if len(id) != 64 {
|
||||
return false
|
||||
}
|
||||
for _, c := range id {
|
||||
if (c < '0' || c > '9') && (c < 'a' || c > 'f') {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -149,3 +149,29 @@ func TestGetOrphan(t *testing.T) {
|
||||
t.Fatalf("Expected to have one orphan layer")
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsValidID(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
id string
|
||||
expected bool
|
||||
}{
|
||||
{"Valid 64-char hexadecimal", "1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef", true},
|
||||
{"Valid 64-char hexadecimal with -init suffix", "1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef-init", true},
|
||||
{"Invalid: too short", "1234567890abcdef", false},
|
||||
{"Invalid: too long", "1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef00", false},
|
||||
{"Invalid: contains uppercase letter", "1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdeF", false},
|
||||
{"Invalid: contains non-hexadecimal character", "1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdeg", false},
|
||||
{"Invalid: empty string", "", false},
|
||||
{"Invalid: only -init suffix", "-init", false},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
result := isValidID(tc.id)
|
||||
if result != tc.expected {
|
||||
t.Errorf("isValidID(%q): got %v, want %v", tc.id, result, tc.expected)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user