From b4ab103ed15a1318c6d53225f06ef52ca1bc69ee Mon Sep 17 00:00:00 2001 From: Chris Roche Date: Thu, 1 Jun 2023 11:38:56 -0700 Subject: [PATCH] Fix map field paths that contain Go format tokens (#5) Fixes related to bufbuild/protovalidate#9. Formatting was being double-applied to error prefixes, causing `%`'s in field paths (such as a string map key) to be mangled. --- internal/errors/utils.go | 7 ++++--- internal/evaluator/field.go | 2 +- internal/evaluator/map.go | 4 +--- internal/evaluator/repeated.go | 4 +--- 4 files changed, 7 insertions(+), 10 deletions(-) diff --git a/internal/errors/utils.go b/internal/errors/utils.go index 78b0e5b..b19d0e1 100644 --- a/internal/errors/utils.go +++ b/internal/errors/utils.go @@ -47,10 +47,11 @@ func Merge(dst, src error, failFast bool) (ok bool, err error) { return !(failFast && len(dstValErrs.Violations) > 0), dst } -// PrefixErrorPaths prepends the prefix to the violations of a ValidationError. -func PrefixErrorPaths(err error, prefix string) { +// PrefixErrorPaths prepends the formatted prefix to the violations of a +// ValidationError. +func PrefixErrorPaths(err error, format string, args ...any) { var valErr *ValidationError if errors.As(err, &valErr) { - PrefixFieldPaths(valErr, prefix) + PrefixFieldPaths(valErr, format, args...) } } diff --git a/internal/evaluator/field.go b/internal/evaluator/field.go index 5d1547f..3ee32e6 100644 --- a/internal/evaluator/field.go +++ b/internal/evaluator/field.go @@ -55,7 +55,7 @@ func (f field) EvaluateMessage(msg protoreflect.Message, failFast bool) (err err val := msg.Get(f.Descriptor) if err = f.Value.Evaluate(val, failFast); err != nil { - errors.PrefixErrorPaths(err, string(f.Descriptor.Name())) + errors.PrefixErrorPaths(err, "%s", f.Descriptor.Name()) } return err } diff --git a/internal/evaluator/map.go b/internal/evaluator/map.go index 06c4e3e..405bf6f 100644 --- a/internal/evaluator/map.go +++ b/internal/evaluator/map.go @@ -15,8 +15,6 @@ package evaluator import ( - "fmt" - "github.com/bufbuild/protovalidate-go/internal/errors" "google.golang.org/protobuf/reflect/protoreflect" ) @@ -34,7 +32,7 @@ func (m kvPairs) Evaluate(val protoreflect.Value, failFast bool) (err error) { val.Map().Range(func(key protoreflect.MapKey, value protoreflect.Value) bool { evalErr := m.evalPairs(key, value, failFast) if evalErr != nil { - errors.PrefixErrorPaths(evalErr, fmt.Sprintf("[%#v]", key.Interface())) + errors.PrefixErrorPaths(evalErr, "[%#v]", key.Interface()) } ok, err = errors.Merge(err, evalErr, failFast) return ok diff --git a/internal/evaluator/repeated.go b/internal/evaluator/repeated.go index b1181df..33f5d39 100644 --- a/internal/evaluator/repeated.go +++ b/internal/evaluator/repeated.go @@ -15,8 +15,6 @@ package evaluator import ( - "fmt" - "github.com/bufbuild/protovalidate-go/internal/errors" "google.golang.org/protobuf/reflect/protoreflect" ) @@ -34,7 +32,7 @@ func (r listItems) Evaluate(val protoreflect.Value, failFast bool) error { for i := 0; i < list.Len(); i++ { itemErr := r.ItemConstraints.Evaluate(list.Get(i), failFast) if itemErr != nil { - errors.PrefixErrorPaths(itemErr, fmt.Sprintf("[%d]", i)) + errors.PrefixErrorPaths(itemErr, "[%d]", i) } if ok, err = errors.Merge(err, itemErr, failFast); !ok { return err