@@ -25,6 +25,9 @@ import (
2525 "github.com/crossplane/crossplane-runtime/pkg/errors"
2626)
2727
28+ // DefaultMaxFieldPathIndex is the max allowed index in a field path.
29+ const DefaultMaxFieldPathIndex = 1024
30+
2831type errNotFound struct {
2932 error
3033}
@@ -46,19 +49,39 @@ func IsNotFound(err error) bool {
4649
4750// A Paved JSON object supports getting and setting values by their field path.
4851type Paved struct {
49- object map [string ]any
52+ object map [string ]any
53+ maxFieldPathIndex uint
5054}
5155
56+ type PavedOption func (paved * Paved )
57+
5258// PaveObject paves a runtime.Object, making it possible to get and set values
5359// by field path. o must be a non-nil pointer to an object.
54- func PaveObject (o runtime.Object ) (* Paved , error ) {
60+ func PaveObject (o runtime.Object , opts ... PavedOption ) (* Paved , error ) {
5561 u , err := runtime .DefaultUnstructuredConverter .ToUnstructured (o )
56- return Pave (u ), errors .Wrap (err , "cannot convert object to unstructured data" )
62+ return Pave (u , opts ... ), errors .Wrap (err , "cannot convert object to unstructured data" )
5763}
5864
5965// Pave a JSON object, making it possible to get and set values by field path.
60- func Pave (object map [string ]any ) * Paved {
61- return & Paved {object : object }
66+ func Pave (object map [string ]any , opts ... PavedOption ) * Paved {
67+ p := & Paved {object : object , maxFieldPathIndex : DefaultMaxFieldPathIndex }
68+
69+ for _ , opt := range opts {
70+ opt (p )
71+ }
72+
73+ return p
74+ }
75+
76+ // WithMaxFieldPathIndex returns a PavedOption that sets the max allowed index for field paths, 0 means no limit.
77+ func WithMaxFieldPathIndex (max uint ) PavedOption {
78+ return func (paved * Paved ) {
79+ paved .maxFieldPathIndex = max
80+ }
81+ }
82+
83+ func (p * Paved ) maxFieldPathIndexEnabled () bool {
84+ return p .maxFieldPathIndex > 0
6285}
6386
6487// MarshalJSON to the underlying object.
@@ -358,6 +381,10 @@ func (p *Paved) setValue(s Segments, value any) error {
358381 return errors .Errorf ("%s is not an array" , s [:i ])
359382 }
360383
384+ if p .maxFieldPathIndexEnabled () && current .Index > p .maxFieldPathIndex {
385+ return errors .Errorf ("index %d is greater than max allowed index %d" , current .Index , p .maxFieldPathIndex )
386+ }
387+
361388 if final {
362389 array [current .Index ] = v
363390 return nil
0 commit comments