@@ -8,11 +8,11 @@ package jsonschema
8
8
9
9
import (
10
10
"bytes"
11
- "cmp"
12
11
"encoding/json"
13
12
"errors"
14
13
"fmt"
15
14
"iter"
15
+ "math"
16
16
)
17
17
18
18
// A Schema is a JSON schema object.
@@ -177,14 +177,14 @@ func (s *Schema) UnmarshalJSON(data []byte) error {
177
177
ms := struct {
178
178
Type json.RawMessage `json:"type,omitempty"`
179
179
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"`
188
188
189
189
* schemaWithoutMethods
190
190
}{
@@ -219,33 +219,52 @@ func (s *Schema) UnmarshalJSON(data []byte) error {
219
219
}
220
220
}
221
221
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 ))
226
225
}
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
233
226
}
234
227
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
+ }
248
239
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 )
249
268
return nil
250
269
}
251
270
0 commit comments