diff --git a/openapi3/schema.go b/openapi3/schema.go index 4c8df1cba..2753851f0 100644 --- a/openapi3/schema.go +++ b/openapi3/schema.go @@ -24,6 +24,12 @@ const ( TypeNumber = "number" TypeObject = "object" TypeString = "string" + + // constants for integer formats + formatMinInt32 = float64(math.MinInt32) + formatMaxInt32 = float64(math.MaxInt32) + formatMinInt64 = float64(math.MinInt64) + formatMaxInt64 = float64(math.MaxInt64) ) var ( @@ -42,6 +48,8 @@ var ( ErrSchemaInputNaN = errors.New("floating point NaN is not allowed") // ErrSchemaInputInf may be returned when validating a number ErrSchemaInputInf = errors.New("floating point Inf is not allowed") + // ErrIntergerFormat may be returned when validation an integer + ErrSchemaInvalidIntegerFormat = errors.New("integer format not supported") ) // Float64Ptr is a helper for defining OpenAPI schemas. @@ -1019,7 +1027,7 @@ func (schema *Schema) VisitJSONNumber(value float64) error { func (schema *Schema) visitJSONNumber(settings *schemaValidationSettings, value float64) error { var me MultiError schemaType := schema.Type - if schemaType == "integer" { + if schemaType == TypeInteger { if bigFloat := big.NewFloat(value); !bigFloat.IsInt() { if settings.failfast { return errSchema @@ -1039,6 +1047,37 @@ func (schema *Schema) visitJSONNumber(settings *schemaValidationSettings, value return schema.expectedType(settings, "number, integer") } + // formats + if schemaType == TypeInteger && schema.Format != "" { + formatMin := float64(0) + formatMax := float64(0) + switch schema.Format { + case "int32": + formatMin = formatMinInt32 + formatMax = formatMaxInt32 + case "int64": + formatMin = formatMinInt64 + formatMax = formatMaxInt64 + default: + return ErrSchemaInvalidIntegerFormat + } + if !(formatMin <= value && value <= formatMax) { + if settings.failfast { + return errSchema + } + err := &SchemaError{ + Value: value, + Schema: schema, + SchemaField: "format", + Reason: fmt.Sprintf("number must be an %s", schema.Format), + } + if !settings.multiError { + return err + } + me = append(me, err) + } + } + // "exclusiveMinimum" if v := schema.ExclusiveMin; v && !(*schema.Min < value) { if settings.failfast {