Skip to content

Commit 738fe87

Browse files
authored
validate pattern or schema, not pattern xor schema anymore (#265)
1 parent d96b816 commit 738fe87

File tree

2 files changed

+57
-48
lines changed

2 files changed

+57
-48
lines changed

.github/workflows/go.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,11 @@ jobs:
2626
- run: go version
2727

2828
- run: go get ./...
29-
- run: go test ./...
3029
- run: go vet ./...
3130
- run: go fmt ./...
31+
- run: git --no-pager diff && [[ $(git --no-pager diff --name-only | wc -l) = 0 ]]
32+
shell: bash
33+
- run: go test ./...
3234
- run: git --no-pager diff && [[ $(git --no-pager diff --name-only | wc -l) = 0 ]]
3335
shell: bash
3436
- run: go get -u -a -v ./... && go mod tidy && go mod verify

openapi3/schema.go

Lines changed: 54 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@ var (
2424

2525
errSchema = errors.New("Input does not match the schema")
2626

27+
// ErrSchemaInputNaN may be returned when validating a number
2728
ErrSchemaInputNaN = errors.New("NaN is not allowed")
29+
// ErrSchemaInputInf may be returned when validating a number
2830
ErrSchemaInputInf = errors.New("Inf is not allowed")
2931
)
3032

@@ -89,7 +91,7 @@ type Schema struct {
8991
MinLength uint64 `json:"minLength,omitempty" yaml:"minLength,omitempty"`
9092
MaxLength *uint64 `json:"maxLength,omitempty" yaml:"maxLength,omitempty"`
9193
Pattern string `json:"pattern,omitempty" yaml:"pattern,omitempty"`
92-
compiledPattern *compiledPattern
94+
compiledPattern *regexp.Regexp
9395

9496
// Array
9597
MinItems uint64 `json:"minItems,omitempty" yaml:"minItems,omitempty"`
@@ -225,11 +227,6 @@ func NewObjectSchema() *Schema {
225227
}
226228
}
227229

228-
type compiledPattern struct {
229-
Regexp *regexp.Regexp
230-
ErrReason string
231-
}
232-
233230
func (schema *Schema) WithNullable() *Schema {
234231
schema.Nullable = true
235232
return schema
@@ -977,56 +974,66 @@ func (schema *Schema) visitJSONString(settings *schemaValidationSettings, value
977974
}
978975
}
979976

980-
// "format" and "pattern"
981-
cp := schema.compiledPattern
982-
if cp == nil {
983-
pattern := schema.Pattern
984-
if v := schema.Pattern; len(v) > 0 {
985-
// Pattern
986-
re, err := regexp.Compile(v)
987-
if err != nil {
988-
return fmt.Errorf("Error while compiling regular expression '%s': %v", pattern, err)
989-
}
990-
cp = &compiledPattern{
991-
Regexp: re,
992-
ErrReason: "JSON string doesn't match the regular expression '" + v + "'",
993-
}
994-
schema.compiledPattern = cp
995-
} else if v := schema.Format; len(v) > 0 {
996-
// No pattern, but does have a format
997-
if f, ok := SchemaStringFormats[v]; ok {
998-
if f.regexp != nil && f.callback == nil {
999-
schema.compiledPattern = &compiledPattern{
1000-
Regexp: f.regexp,
1001-
ErrReason: "JSON string doesn't match the format '" + v + " (regular expression `" + f.regexp.String() + "`)'",
1002-
}
1003-
1004-
} else if f.regexp == nil && f.callback != nil {
1005-
return f.callback(value)
1006-
} else {
1007-
return fmt.Errorf("corrupted entry %q in SchemaStringFormats", v)
1008-
}
1009-
}
1010-
}
1011-
}
1012-
if cp != nil {
1013-
if !cp.Regexp.MatchString(value) {
1014-
field := "format"
1015-
if schema.Pattern != "" {
1016-
field = "pattern"
1017-
}
1018-
err := &SchemaError{
977+
// "pattern"
978+
if pattern := schema.Pattern; pattern != "" && schema.compiledPattern == nil {
979+
var err error
980+
if schema.compiledPattern, err = regexp.Compile(pattern); err != nil {
981+
err = &SchemaError{
1019982
Value: value,
1020983
Schema: schema,
1021-
SchemaField: field,
1022-
Reason: cp.ErrReason,
984+
SchemaField: "pattern",
985+
Reason: fmt.Sprintf("cannot compile pattern %q: %v", pattern, err),
1023986
}
1024987
if !settings.multiError {
1025988
return err
1026989
}
1027990
me = append(me, err)
1028991
}
1029992
}
993+
if cp := schema.compiledPattern; cp != nil && !cp.MatchString(value) {
994+
err := &SchemaError{
995+
Value: value,
996+
Schema: schema,
997+
SchemaField: "pattern",
998+
Reason: fmt.Sprintf("JSON string doesn't match the regular expression %q", schema.Pattern),
999+
}
1000+
if !settings.multiError {
1001+
return err
1002+
}
1003+
me = append(me, err)
1004+
}
1005+
1006+
// "format"
1007+
var formatErr string
1008+
if format := schema.Format; format != "" {
1009+
if f, ok := SchemaStringFormats[format]; ok {
1010+
switch {
1011+
case f.regexp != nil && f.callback == nil:
1012+
if cp := f.regexp; !cp.MatchString(value) {
1013+
formatErr = fmt.Sprintf("JSON string doesn't match the format %q (regular expression %q)", format, cp.String())
1014+
}
1015+
case f.regexp == nil && f.callback != nil:
1016+
if err := f.callback(value); err != nil {
1017+
formatErr = err.Error()
1018+
}
1019+
default:
1020+
formatErr = fmt.Sprintf("corrupted entry %q in SchemaStringFormats", format)
1021+
}
1022+
}
1023+
}
1024+
if formatErr != "" {
1025+
err := &SchemaError{
1026+
Value: value,
1027+
Schema: schema,
1028+
SchemaField: "format",
1029+
Reason: formatErr,
1030+
}
1031+
if !settings.multiError {
1032+
return err
1033+
}
1034+
me = append(me, err)
1035+
1036+
}
10301037

10311038
if len(me) > 0 {
10321039
return me

0 commit comments

Comments
 (0)