From 4849dec610e148cf91c9accadab93f42bf44a705 Mon Sep 17 00:00:00 2001 From: "Lixia (Sylvia) Lei" Date: Thu, 21 Sep 2023 16:59:33 +0800 Subject: [PATCH] fix race? Signed-off-by: Lixia (Sylvia) Lei --- internal/maps/maps.go | 28 ++++++++++++++++++++++++++++ registry/remote/auth/scope.go | 22 ++++++++++++---------- 2 files changed, 40 insertions(+), 10 deletions(-) create mode 100644 internal/maps/maps.go diff --git a/internal/maps/maps.go b/internal/maps/maps.go new file mode 100644 index 00000000..8db27fcb --- /dev/null +++ b/internal/maps/maps.go @@ -0,0 +1,28 @@ +/* +Copyright The ORAS Authors. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package maps + +// Copy copies all key/value pairs in src adding them to dst. +// When a key in src is already present in dst, +// the value in dst will be overwritten by the value associated +// with the key in src. +// +// Reference: https://pkg.go.dev/maps@go1.21.1#Copy +func Copy[M1 ~map[K]V, M2 ~map[K]V, K comparable, V any](dst M1, src M2) { + for k, v := range src { + dst[k] = v + } +} diff --git a/registry/remote/auth/scope.go b/registry/remote/auth/scope.go index 99b62d8f..7d8bb2c9 100644 --- a/registry/remote/auth/scope.go +++ b/registry/remote/auth/scope.go @@ -20,6 +20,7 @@ import ( "sort" "strings" + "oras.land/oras-go/v2/internal/maps" "oras.land/oras-go/v2/internal/slices" "oras.land/oras-go/v2/registry" ) @@ -146,15 +147,16 @@ type scopesPerHostContextKey struct{} // // Reference: https://docs.docker.com/registry/spec/auth/scope/ func WithScopesPerHost(ctx context.Context, host string, scopes ...string) context.Context { - var regMap map[string][]string - var ok bool - regMap, ok = ctx.Value(scopesPerHostContextKey{}).(map[string][]string) - if !ok { - regMap = make(map[string][]string) + var scopesByHost map[string][]string + if old, ok := ctx.Value(scopesPerHostContextKey{}).(map[string][]string); ok { + scopesByHost = make(map[string][]string, len(old)) + maps.Copy(scopesByHost, old) + } else { + scopesByHost = make(map[string][]string, 1) } - scopes = CleanScopes(scopes) - regMap[host] = scopes - return context.WithValue(ctx, scopesPerHostContextKey{}, regMap) + + scopesByHost[host] = CleanScopes(scopes) + return context.WithValue(ctx, scopesPerHostContextKey{}, scopesByHost) } // AppendScopesPerHost appends additional scopes to the existing scopes @@ -171,8 +173,8 @@ func AppendScopesPerHost(ctx context.Context, host string, scopes ...string) con // GetScopesPerHost returns the scopes in the context for the given host. func GetScopesPerHost(ctx context.Context, host string) []string { - if regMap, ok := ctx.Value(scopesPerHostContextKey{}).(map[string][]string); ok { - return slices.Clone(regMap[host]) + if scopesByHost, ok := ctx.Value(scopesPerHostContextKey{}).(map[string][]string); ok { + return slices.Clone(scopesByHost[host]) } return nil }