From 837325bf80517bf2d4b60037d427172eabba53ce Mon Sep 17 00:00:00 2001 From: Frederic BIDON Date: Mon, 4 Mar 2024 07:48:30 +0100 Subject: [PATCH] fix: fixed data race in result (schemata caching) Signed-off-by: Frederic BIDON --- result.go | 18 ++++++++++++++++-- schema_props_test.go | 10 ---------- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/result.go b/result.go index ca45b00..1ff1e3d 100644 --- a/result.go +++ b/result.go @@ -220,12 +220,26 @@ func (r *Result) mergeForSlice(slice reflect.Value, i int, other *Result) *Resul if r.itemSchemata == nil { r.itemSchemata = make([]itemSchemata, slice.Len()) } + // clone other, as other is about to be redeemed to the pool TODO(fred) + var clone schemata + if other.rootObjectSchemata.one != nil { + *clone.one = *other.rootObjectSchemata.one + } + if other.rootObjectSchemata.multiple != nil { + clone.multiple = make([]*spec.Schema, len(other.rootObjectSchemata.multiple)) + for idx := 0; i < len(other.rootObjectSchemata.multiple); idx++ { + s := new(spec.Schema) + *s = *other.rootObjectSchemata.multiple[idx] + clone.multiple[idx] = s + } + } r.itemSchemata = append(r.itemSchemata, itemSchemata{ slice: slice, index: i, - schemata: other.rootObjectSchemata, + schemata: clone, }) } + if other.wantsRedeemOnMerge { pools.poolOfResults.RedeemResult(other) } @@ -502,7 +516,7 @@ func (s *schemata) Slice() []*spec.Schema { return s.multiple } -// appendSchemata appends the schemata in other to s. It mutated s in-place. +// appendSchemata appends the schemata in other to s. It mutates s in-place. func (s *schemata) Append(other schemata) { if other.one == nil && len(other.multiple) == 0 { return diff --git a/schema_props_test.go b/schema_props_test.go index 63a6baf..760113e 100644 --- a/schema_props_test.go +++ b/schema_props_test.go @@ -51,16 +51,6 @@ func TestSchemaPropsValidator_EdgeCases(t *testing.T) { res := s.Validate(data) require.NotNil(t, res) require.Empty(t, res.Errors) - - /* TODO(fred) - t.Run("validator should run once", func(t *testing.T) { - // we should not do that: the pool chain list is populated with a duplicate: needs a reset - t.Cleanup(resetPools) - require.NotPanics(t, func() { - _ = s.Validate(data) - }) - }) - */ }) t.Run("should NOT validate unformatted string", func(t *testing.T) {