@@ -8,11 +8,11 @@ package jsonschema
88
99import (
1010 "bytes"
11- "cmp"
1211 "encoding/json"
1312 "errors"
1413 "fmt"
1514 "iter"
15+ "math"
1616)
1717
1818// A Schema is a JSON schema object.
@@ -177,14 +177,14 @@ func (s *Schema) UnmarshalJSON(data []byte) error {
177177 ms := struct {
178178 Type json.RawMessage `json:"type,omitempty"`
179179 Const json.RawMessage `json:"const,omitempty"`
180- MinLength * float64 `json:"minLength,omitempty"`
181- MaxLength * float64 `json:"maxLength,omitempty"`
182- MinItems * float64 `json:"minItems,omitempty"`
183- MaxItems * float64 `json:"maxItems,omitempty"`
184- MinProperties * float64 `json:"minProperties,omitempty"`
185- MaxProperties * float64 `json:"maxProperties,omitempty"`
186- MinContains * float64 `json:"minContains,omitempty"`
187- MaxContains * float64 `json:"maxContains,omitempty"`
180+ MinLength * integer `json:"minLength,omitempty"`
181+ MaxLength * integer `json:"maxLength,omitempty"`
182+ MinItems * integer `json:"minItems,omitempty"`
183+ MaxItems * integer `json:"maxItems,omitempty"`
184+ MinProperties * integer `json:"minProperties,omitempty"`
185+ MaxProperties * integer `json:"maxProperties,omitempty"`
186+ MinContains * integer `json:"minContains,omitempty"`
187+ MaxContains * integer `json:"maxContains,omitempty"`
188188
189189 * schemaWithoutMethods
190190 }{
@@ -219,33 +219,52 @@ func (s *Schema) UnmarshalJSON(data []byte) error {
219219 }
220220 }
221221
222- // Store integer properties as ints.
223- setInt := func (name string , dst * * int , src * float64 ) error {
224- if src == nil {
225- return nil
222+ set := func (dst * * int , src * integer ) {
223+ if src != nil {
224+ * dst = Ptr (int (* src ))
226225 }
227- i := int (* src )
228- if float64 (i ) != * src {
229- return fmt .Errorf ("%s: %f is not an int" , name , * src )
230- }
231- * dst = & i
232- return nil
233226 }
234227
235- err = cmp .Or (
236- setInt ("minLength" , & s .MinLength , ms .MinLength ),
237- setInt ("maxLength" , & s .MaxLength , ms .MaxLength ),
238- setInt ("minItems" , & s .MinItems , ms .MinItems ),
239- setInt ("maxItems" , & s .MaxItems , ms .MaxItems ),
240- setInt ("minProperties" , & s .MinProperties , ms .MinProperties ),
241- setInt ("maxProperties" , & s .MaxProperties , ms .MaxProperties ),
242- setInt ("minContains" , & s .MinContains , ms .MinContains ),
243- setInt ("maxContains" , & s .MaxContains , ms .MaxContains ),
244- )
245- if err != nil {
246- return err
247- }
228+ set (& s .MinLength , ms .MinLength )
229+ set (& s .MaxLength , ms .MaxLength )
230+ set (& s .MinItems , ms .MinItems )
231+ set (& s .MaxItems , ms .MaxItems )
232+ set (& s .MinProperties , ms .MinProperties )
233+ set (& s .MaxProperties , ms .MaxProperties )
234+ set (& s .MinContains , ms .MinContains )
235+ set (& s .MaxContains , ms .MaxContains )
236+
237+ return nil
238+ }
248239
240+ type integer int32 // for the integer-valued fields of Schema
241+
242+ func (ip * integer ) UnmarshalJSON (data []byte ) error {
243+ if len (data ) == 0 {
244+ // nothing to do
245+ return nil
246+ }
247+ // If there is a decimal point, src is a floating-point number.
248+ var i int64
249+ if bytes .ContainsRune (data , '.' ) {
250+ var f float64
251+ if err := json .Unmarshal (data , & f ); err != nil {
252+ return errors .New ("not a number" )
253+ }
254+ i = int64 (f )
255+ if float64 (i ) != f {
256+ return errors .New ("not an integer value" )
257+ }
258+ } else {
259+ if err := json .Unmarshal (data , & i ); err != nil {
260+ return errors .New ("cannot be unmarshaled into an int" )
261+ }
262+ }
263+ // Ensure behavior is the same on both 32-bit and 64-bit systems.
264+ if i < math .MinInt32 || i > math .MaxInt32 {
265+ return errors .New ("integer is out of range" )
266+ }
267+ * ip = integer (i )
249268 return nil
250269}
251270
0 commit comments