From e9055d15745242049494d48b0b82d6d5158f2fd5 Mon Sep 17 00:00:00 2001 From: Riccardo Manfrin Date: Mon, 12 Oct 2020 17:41:32 +0200 Subject: [PATCH 01/23] Adds ipv4 and ipv6 formats support --- openapi3/schema.go | 30 +++++++++--- openapi3/schema_formats.go | 95 ++++++++++++++++++++++++++++++++++---- 2 files changed, 111 insertions(+), 14 deletions(-) diff --git a/openapi3/schema.go b/openapi3/schema.go index 8a34282ff..b3e0a025d 100644 --- a/openapi3/schema.go +++ b/openapi3/schema.go @@ -930,14 +930,25 @@ func (schema *Schema) visitJSONString(value string, fast bool) (err error) { schema.compiledPattern = cp } else if v := schema.Format; len(v) > 0 { // No pattern, but does have a format - re := SchemaStringFormats[v] - if re != nil { - cp = &compiledPattern{ - Regexp: re, - ErrReason: "JSON string doesn't match the format '" + v + " (regular expression `" + re.String() + "`)'", + f := SchemaStringFormats[v] + switch f.Type { + case FormatTypeRe: + { + re := f.Regexp + if re != nil { + cp = &compiledPattern{ + Regexp: re, + ErrReason: "JSON string doesn't match the format '" + v + " (regular expression `" + re.String() + "`)'", + } + schema.compiledPattern = cp + } + } + case FormatTypeCallback: + { + return f.Callback(value) } - schema.compiledPattern = cp } + } } if cp != nil { @@ -953,6 +964,13 @@ func (schema *Schema) visitJSONString(value string, fast bool) (err error) { Reason: cp.ErrReason, } } + } else if len(schema.Format) > 0 && cp == nil { + return &SchemaError{ + Value: value, + Schema: schema, + SchemaField: "format", + Reason: "Unsupported Format", + } } return } diff --git a/openapi3/schema_formats.go b/openapi3/schema_formats.go index 746e40882..fd5bff519 100644 --- a/openapi3/schema_formats.go +++ b/openapi3/schema_formats.go @@ -2,6 +2,7 @@ package openapi3 import ( "fmt" + "net" "regexp" ) @@ -10,29 +11,107 @@ const ( FormatOfStringForUUIDOfRFC4122 = `^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$` ) -var SchemaStringFormats = make(map[string]*regexp.Regexp, 8) +// FormatType is the type of format validation used +type FormatType string -func DefineStringFormat(name string, pattern string) { +// FormatTypeRe is regexp based validation +const FormatTypeRe = "re" + +// FormatTypeCallback is callback based validation +const FormatTypeCallback = "callback" + +type FormatCallback func(Val string) error + +//Format is the format type context fo validate the format +type Format struct { + Type FormatType + Regexp *regexp.Regexp + Callback FormatCallback +} + +//SchemaStringFormats allows for validating strings format +var SchemaStringFormats = make(map[string]Format, 8) + +//DefineStringReFormat Defines a new regexp pattern for a given format +func DefineStringReFormat(name string, pattern string) { re, err := regexp.Compile(pattern) if err != nil { err := fmt.Errorf("Format '%v' has invalid pattern '%v': %v", name, pattern, err) panic(err) } - SchemaStringFormats[name] = re + f := Format{ + Type: FormatTypeRe, + Regexp: re, + Callback: nil} + SchemaStringFormats[name] = f +} + +// DefineStringCallbackFormat define callback based type callback validation +func DefineStringCallbackFormat(name string, callback FormatCallback) { + + f := Format{ + Type: FormatTypeCallback, + Regexp: nil, + Callback: callback} + SchemaStringFormats[name] = f +} + +func validateIP(ip string) (*net.IP, error) { + parsed := net.ParseIP(ip) + if parsed == nil { + return nil, &SchemaError{ + Value: ip, + Reason: "Not an IP address", + } + } + return &parsed, nil +} + +func validateIPv4(ip string) error { + parsed, err := validateIP(ip) + if err != nil { + return err + } + + if parsed.To4() == nil { + return &SchemaError{ + Value: ip, + Reason: "Not an IPv4 address (it's IPv6)", + } + } + return nil +} +func validateIPv6(ip string) error { + parsed, err := validateIP(ip) + if err != nil { + return err + } + + if parsed.To4() != nil { + return &SchemaError{ + Value: ip, + Reason: "Not an IPv6 address (it's IPv4)", + } + } + return nil } func init() { // This pattern catches only some suspiciously wrong-looking email addresses. - // Use DefineStringFormat(...) if you need something stricter. - DefineStringFormat("email", `^[^@]+@[^@<>",\s]+$`) + // Use DefineStringReFormat(...) if you need something stricter. + DefineStringReFormat("email", `^[^@]+@[^@<>",\s]+$`) // Base64 // The pattern supports base64 and b./ase64url. Padding ('=') is supported. - DefineStringFormat("byte", `(^$|^[a-zA-Z0-9+/\-_]*=*$)`) + DefineStringReFormat("byte", `(^$|^[a-zA-Z0-9+/\-_]*=*$)`) // date - DefineStringFormat("date", `^[0-9]{4}-(0[0-9]|10|11|12)-([0-2][0-9]|30|31)$`) + DefineStringReFormat("date", `^[0-9]{4}-(0[0-9]|10|11|12)-([0-2][0-9]|30|31)$`) // date-time - DefineStringFormat("date-time", `^[0-9]{4}-(0[0-9]|10|11|12)-([0-2][0-9]|30|31)T[0-9]{2}:[0-9]{2}:[0-9]{2}(.[0-9]+)?(Z|(\+|-)[0-9]{2}:[0-9]{2})?$`) + DefineStringReFormat("date-time", `^[0-9]{4}-(0[0-9]|10|11|12)-([0-2][0-9]|30|31)T[0-9]{2}:[0-9]{2}:[0-9]{2}(.[0-9]+)?(Z|(\+|-)[0-9]{2}:[0-9]{2})?$`) + + DefineStringCallbackFormat("ipv4", validateIPv4) + DefineStringCallbackFormat("ipv6", validateIPv6) + } From 6a8d346351332c34ecc5b6fcb70c5111401b0bd3 Mon Sep 17 00:00:00 2001 From: Riccardo Manfrin Date: Tue, 13 Oct 2020 08:44:07 +0200 Subject: [PATCH 02/23] Fix tests --- openapi3/schema_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openapi3/schema_test.go b/openapi3/schema_test.go index 10e1d0589..700c6c872 100644 --- a/openapi3/schema_test.go +++ b/openapi3/schema_test.go @@ -20,7 +20,7 @@ type schemaExample struct { } func TestSchemas(t *testing.T) { - DefineStringFormat("uuid", FormatOfStringForUUIDOfRFC4122) + DefineStringReFormat("uuid", FormatOfStringForUUIDOfRFC4122) for _, example := range schemaExamples { t.Run(example.Title, testSchema(t, example)) } From 43aa7a25f51ea9aa375c598dfb2d1d3a6a7036db Mon Sep 17 00:00:00 2001 From: Riccardo Manfrin Date: Wed, 14 Oct 2020 08:51:27 +0200 Subject: [PATCH 03/23] Comply to comment find . -iname "*.go" -exec perl -pe 's/DefineStringReFormat/DefineStringFormat/g' -i {} \; --- openapi3/schema_formats.go | 14 +++++++------- openapi3/schema_test.go | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/openapi3/schema_formats.go b/openapi3/schema_formats.go index fd5bff519..70b8e2f81 100644 --- a/openapi3/schema_formats.go +++ b/openapi3/schema_formats.go @@ -32,8 +32,8 @@ type Format struct { //SchemaStringFormats allows for validating strings format var SchemaStringFormats = make(map[string]Format, 8) -//DefineStringReFormat Defines a new regexp pattern for a given format -func DefineStringReFormat(name string, pattern string) { +//DefineStringFormat Defines a new regexp pattern for a given format +func DefineStringFormat(name string, pattern string) { re, err := regexp.Compile(pattern) if err != nil { err := fmt.Errorf("Format '%v' has invalid pattern '%v': %v", name, pattern, err) @@ -98,18 +98,18 @@ func validateIPv6(ip string) error { func init() { // This pattern catches only some suspiciously wrong-looking email addresses. - // Use DefineStringReFormat(...) if you need something stricter. - DefineStringReFormat("email", `^[^@]+@[^@<>",\s]+$`) + // Use DefineStringFormat(...) if you need something stricter. + DefineStringFormat("email", `^[^@]+@[^@<>",\s]+$`) // Base64 // The pattern supports base64 and b./ase64url. Padding ('=') is supported. - DefineStringReFormat("byte", `(^$|^[a-zA-Z0-9+/\-_]*=*$)`) + DefineStringFormat("byte", `(^$|^[a-zA-Z0-9+/\-_]*=*$)`) // date - DefineStringReFormat("date", `^[0-9]{4}-(0[0-9]|10|11|12)-([0-2][0-9]|30|31)$`) + DefineStringFormat("date", `^[0-9]{4}-(0[0-9]|10|11|12)-([0-2][0-9]|30|31)$`) // date-time - DefineStringReFormat("date-time", `^[0-9]{4}-(0[0-9]|10|11|12)-([0-2][0-9]|30|31)T[0-9]{2}:[0-9]{2}:[0-9]{2}(.[0-9]+)?(Z|(\+|-)[0-9]{2}:[0-9]{2})?$`) + DefineStringFormat("date-time", `^[0-9]{4}-(0[0-9]|10|11|12)-([0-2][0-9]|30|31)T[0-9]{2}:[0-9]{2}:[0-9]{2}(.[0-9]+)?(Z|(\+|-)[0-9]{2}:[0-9]{2})?$`) DefineStringCallbackFormat("ipv4", validateIPv4) DefineStringCallbackFormat("ipv6", validateIPv6) diff --git a/openapi3/schema_test.go b/openapi3/schema_test.go index 700c6c872..10e1d0589 100644 --- a/openapi3/schema_test.go +++ b/openapi3/schema_test.go @@ -20,7 +20,7 @@ type schemaExample struct { } func TestSchemas(t *testing.T) { - DefineStringReFormat("uuid", FormatOfStringForUUIDOfRFC4122) + DefineStringFormat("uuid", FormatOfStringForUUIDOfRFC4122) for _, example := range schemaExamples { t.Run(example.Title, testSchema(t, example)) } From 12eed8d684050af14e7427c1a8038fcad607ce6b Mon Sep 17 00:00:00 2001 From: Riccardo Manfrin Date: Tue, 27 Oct 2020 08:31:24 +0100 Subject: [PATCH 04/23] Substitutes Type check with nil check on Regexp value --- openapi3/schema.go | 24 +++++++++--------------- openapi3/schema_formats.go | 5 +---- 2 files changed, 10 insertions(+), 19 deletions(-) diff --git a/openapi3/schema.go b/openapi3/schema.go index b3e0a025d..8d2b1ddd5 100644 --- a/openapi3/schema.go +++ b/openapi3/schema.go @@ -931,24 +931,18 @@ func (schema *Schema) visitJSONString(value string, fast bool) (err error) { } else if v := schema.Format; len(v) > 0 { // No pattern, but does have a format f := SchemaStringFormats[v] - switch f.Type { - case FormatTypeRe: - { - re := f.Regexp - if re != nil { - cp = &compiledPattern{ - Regexp: re, - ErrReason: "JSON string doesn't match the format '" + v + " (regular expression `" + re.String() + "`)'", - } - schema.compiledPattern = cp + if f.Regexp != nil { + re := f.Regexp + if re != nil { + cp = &compiledPattern{ + Regexp: re, + ErrReason: "JSON string doesn't match the format '" + v + " (regular expression `" + re.String() + "`)'", } + schema.compiledPattern = cp } - case FormatTypeCallback: - { - return f.Callback(value) - } + } else if f.Callback != nil { + return f.Callback(value) } - } } if cp != nil { diff --git a/openapi3/schema_formats.go b/openapi3/schema_formats.go index 70b8e2f81..7c2c5bf77 100644 --- a/openapi3/schema_formats.go +++ b/openapi3/schema_formats.go @@ -20,11 +20,11 @@ const FormatTypeRe = "re" // FormatTypeCallback is callback based validation const FormatTypeCallback = "callback" +//FormatCallback custom check on exotic formats type FormatCallback func(Val string) error //Format is the format type context fo validate the format type Format struct { - Type FormatType Regexp *regexp.Regexp Callback FormatCallback } @@ -40,7 +40,6 @@ func DefineStringFormat(name string, pattern string) { panic(err) } f := Format{ - Type: FormatTypeRe, Regexp: re, Callback: nil} SchemaStringFormats[name] = f @@ -48,9 +47,7 @@ func DefineStringFormat(name string, pattern string) { // DefineStringCallbackFormat define callback based type callback validation func DefineStringCallbackFormat(name string, callback FormatCallback) { - f := Format{ - Type: FormatTypeCallback, Regexp: nil, Callback: callback} SchemaStringFormats[name] = f From 117a159affa4c1a603f7a4c21b46f26820765453 Mon Sep 17 00:00:00 2001 From: Riccardo Manfrin Date: Tue, 27 Oct 2020 08:33:36 +0100 Subject: [PATCH 05/23] Makes regexp and callback private --- openapi3/schema.go | 8 ++++---- openapi3/schema_formats.go | 12 ++++++------ 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/openapi3/schema.go b/openapi3/schema.go index 8d2b1ddd5..6485ef455 100644 --- a/openapi3/schema.go +++ b/openapi3/schema.go @@ -931,8 +931,8 @@ func (schema *Schema) visitJSONString(value string, fast bool) (err error) { } else if v := schema.Format; len(v) > 0 { // No pattern, but does have a format f := SchemaStringFormats[v] - if f.Regexp != nil { - re := f.Regexp + if f.regexp != nil { + re := f.regexp if re != nil { cp = &compiledPattern{ Regexp: re, @@ -940,8 +940,8 @@ func (schema *Schema) visitJSONString(value string, fast bool) (err error) { } schema.compiledPattern = cp } - } else if f.Callback != nil { - return f.Callback(value) + } else if f.callback != nil { + return f.callback(value) } } } diff --git a/openapi3/schema_formats.go b/openapi3/schema_formats.go index 7c2c5bf77..e1d893746 100644 --- a/openapi3/schema_formats.go +++ b/openapi3/schema_formats.go @@ -25,8 +25,8 @@ type FormatCallback func(Val string) error //Format is the format type context fo validate the format type Format struct { - Regexp *regexp.Regexp - Callback FormatCallback + regexp *regexp.Regexp + callback FormatCallback } //SchemaStringFormats allows for validating strings format @@ -40,16 +40,16 @@ func DefineStringFormat(name string, pattern string) { panic(err) } f := Format{ - Regexp: re, - Callback: nil} + regexp: re, + callback: nil} SchemaStringFormats[name] = f } // DefineStringCallbackFormat define callback based type callback validation func DefineStringCallbackFormat(name string, callback FormatCallback) { f := Format{ - Regexp: nil, - Callback: callback} + regexp: nil, + callback: callback} SchemaStringFormats[name] = f } From 625527001106c5f654cc0315517b4e1d4b3999b4 Mon Sep 17 00:00:00 2001 From: Riccardo Manfrin Date: Tue, 27 Oct 2020 08:43:28 +0100 Subject: [PATCH 06/23] Keep ipv4 and ipv6 format validation optional --- openapi3/schema_formats.go | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/openapi3/schema_formats.go b/openapi3/schema_formats.go index e1d893746..ad1158aa4 100644 --- a/openapi3/schema_formats.go +++ b/openapi3/schema_formats.go @@ -108,7 +108,14 @@ func init() { // date-time DefineStringFormat("date-time", `^[0-9]{4}-(0[0-9]|10|11|12)-([0-2][0-9]|30|31)T[0-9]{2}:[0-9]{2}:[0-9]{2}(.[0-9]+)?(Z|(\+|-)[0-9]{2}:[0-9]{2})?$`) +} + +// DefineIPv4Format opts in ipv4 format validation on top of OAS 3 spec +func DefineIPv4Format() { DefineStringCallbackFormat("ipv4", validateIPv4) - DefineStringCallbackFormat("ipv6", validateIPv6) +} +// DefineIPv6Format opts in ipv6 format validation on top of OAS 3 spec +func DefineIPv6Format() { + DefineStringCallbackFormat("ipv6", validateIPv6) } From cdf5de556f19e3ffa82fd03545227ee9c3b1b016 Mon Sep 17 00:00:00 2001 From: Riccardo Manfrin Date: Tue, 27 Oct 2020 17:09:26 +0100 Subject: [PATCH 07/23] Update openapi3/schema_formats.go Co-authored-by: Pierre Fenoll --- openapi3/schema_formats.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openapi3/schema_formats.go b/openapi3/schema_formats.go index ad1158aa4..b8d924df7 100644 --- a/openapi3/schema_formats.go +++ b/openapi3/schema_formats.go @@ -46,7 +46,7 @@ func DefineStringFormat(name string, pattern string) { } // DefineStringCallbackFormat define callback based type callback validation -func DefineStringCallbackFormat(name string, callback FormatCallback) { +func DefineStringFormatCallback(name string, callback FormatCallback) { f := Format{ regexp: nil, callback: callback} From c59bba23879a628bc4bb9161e195363f52538d81 Mon Sep 17 00:00:00 2001 From: Riccardo Manfrin Date: Tue, 27 Oct 2020 17:09:44 +0100 Subject: [PATCH 08/23] Update openapi3/schema_formats.go Co-authored-by: Pierre Fenoll --- openapi3/schema_formats.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openapi3/schema_formats.go b/openapi3/schema_formats.go index b8d924df7..b55f8c64d 100644 --- a/openapi3/schema_formats.go +++ b/openapi3/schema_formats.go @@ -45,7 +45,7 @@ func DefineStringFormat(name string, pattern string) { SchemaStringFormats[name] = f } -// DefineStringCallbackFormat define callback based type callback validation +// DefineStringFormatCallback ads a validation function for a specific schema format entry func DefineStringFormatCallback(name string, callback FormatCallback) { f := Format{ regexp: nil, From b98a889b8651b5a92649f8fde1caf3bbb1a2a4e8 Mon Sep 17 00:00:00 2001 From: Riccardo Manfrin Date: Tue, 27 Oct 2020 17:09:56 +0100 Subject: [PATCH 09/23] Update openapi3/schema_formats.go Co-authored-by: Pierre Fenoll --- openapi3/schema_formats.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openapi3/schema_formats.go b/openapi3/schema_formats.go index b55f8c64d..960260064 100644 --- a/openapi3/schema_formats.go +++ b/openapi3/schema_formats.go @@ -112,7 +112,7 @@ func init() { // DefineIPv4Format opts in ipv4 format validation on top of OAS 3 spec func DefineIPv4Format() { - DefineStringCallbackFormat("ipv4", validateIPv4) + DefineStringFormatCallback("ipv4", validateIPv4) } // DefineIPv6Format opts in ipv6 format validation on top of OAS 3 spec From 1eb4c54bb5d05e8ccdcd00b898f0bb7c1f09d026 Mon Sep 17 00:00:00 2001 From: Riccardo Manfrin Date: Tue, 27 Oct 2020 17:10:19 +0100 Subject: [PATCH 10/23] Update openapi3/schema_formats.go Co-authored-by: Pierre Fenoll --- openapi3/schema_formats.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openapi3/schema_formats.go b/openapi3/schema_formats.go index 960260064..71fba184c 100644 --- a/openapi3/schema_formats.go +++ b/openapi3/schema_formats.go @@ -117,5 +117,5 @@ func DefineIPv4Format() { // DefineIPv6Format opts in ipv6 format validation on top of OAS 3 spec func DefineIPv6Format() { - DefineStringCallbackFormat("ipv6", validateIPv6) + DefineStringFormatCallback("ipv6", validateIPv6) } From d44ccf349e4b795f992b4939503cb5bab9c50f65 Mon Sep 17 00:00:00 2001 From: Riccardo Manfrin Date: Tue, 27 Oct 2020 17:11:25 +0100 Subject: [PATCH 11/23] Update openapi3/schema_formats.go Co-authored-by: Pierre Fenoll --- openapi3/schema_formats.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openapi3/schema_formats.go b/openapi3/schema_formats.go index 71fba184c..1f70da28f 100644 --- a/openapi3/schema_formats.go +++ b/openapi3/schema_formats.go @@ -47,7 +47,7 @@ func DefineStringFormat(name string, pattern string) { // DefineStringFormatCallback ads a validation function for a specific schema format entry func DefineStringFormatCallback(name string, callback FormatCallback) { - f := Format{ + SchemaStringFormats[name] = Format{callback: callback} regexp: nil, callback: callback} SchemaStringFormats[name] = f From 624e8333d53ff41160068c1ecc46e9fed7aaaf7b Mon Sep 17 00:00:00 2001 From: Riccardo Manfrin Date: Tue, 27 Oct 2020 17:12:12 +0100 Subject: [PATCH 12/23] Update openapi3/schema_formats.go Co-authored-by: Pierre Fenoll --- openapi3/schema_formats.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openapi3/schema_formats.go b/openapi3/schema_formats.go index 1f70da28f..5483e4e82 100644 --- a/openapi3/schema_formats.go +++ b/openapi3/schema_formats.go @@ -39,7 +39,7 @@ func DefineStringFormat(name string, pattern string) { err := fmt.Errorf("Format '%v' has invalid pattern '%v': %v", name, pattern, err) panic(err) } - f := Format{ + SchemaStringFormats[name] = Format{regexp: re} regexp: re, callback: nil} SchemaStringFormats[name] = f From 718b995a4a890708449f44ad313e6f6ca3b66ae6 Mon Sep 17 00:00:00 2001 From: Riccardo Manfrin Date: Wed, 11 Nov 2020 23:57:44 +0100 Subject: [PATCH 13/23] Keep this for a different PR --- openapi3/schema.go | 7 ------- 1 file changed, 7 deletions(-) diff --git a/openapi3/schema.go b/openapi3/schema.go index 6485ef455..e3ac9c0a0 100644 --- a/openapi3/schema.go +++ b/openapi3/schema.go @@ -958,13 +958,6 @@ func (schema *Schema) visitJSONString(value string, fast bool) (err error) { Reason: cp.ErrReason, } } - } else if len(schema.Format) > 0 && cp == nil { - return &SchemaError{ - Value: value, - Schema: schema, - SchemaField: "format", - Reason: "Unsupported Format", - } } return } From 5c8452814c14df72c723b8375d61af18a589bece Mon Sep 17 00:00:00 2001 From: Riccardo Manfrin Date: Thu, 12 Nov 2020 00:21:11 +0100 Subject: [PATCH 14/23] Adds check on f existence and default currupted error case --- openapi3/schema.go | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/openapi3/schema.go b/openapi3/schema.go index e3ac9c0a0..4160a57db 100644 --- a/openapi3/schema.go +++ b/openapi3/schema.go @@ -930,18 +930,21 @@ func (schema *Schema) visitJSONString(value string, fast bool) (err error) { schema.compiledPattern = cp } else if v := schema.Format; len(v) > 0 { // No pattern, but does have a format - f := SchemaStringFormats[v] - if f.regexp != nil { - re := f.regexp - if re != nil { - cp = &compiledPattern{ - Regexp: re, - ErrReason: "JSON string doesn't match the format '" + v + " (regular expression `" + re.String() + "`)'", + if f, ok := SchemaStringFormats[v]; ok { + if f.regexp != nil && f.callback == nil { + re := f.regexp + if re != nil { + cp = &compiledPattern{ + Regexp: re, + ErrReason: "JSON string doesn't match the format '" + v + " (regular expression `" + re.String() + "`)'", + } + schema.compiledPattern = cp } - schema.compiledPattern = cp + } else if f.regexp == nil && f.callback != nil { + return f.callback(value) + } else { + return fmt.Errorf("corrupted entry %q in SchemaStringFormats", v) } - } else if f.callback != nil { - return f.callback(value) } } } From aa9a033d9aaf0e87bcd266021636a8cafbc0c497 Mon Sep 17 00:00:00 2001 From: Riccardo Manfrin Date: Thu, 12 Nov 2020 00:24:22 +0100 Subject: [PATCH 15/23] Fixups --- openapi3/schema_formats.go | 6 ------ 1 file changed, 6 deletions(-) diff --git a/openapi3/schema_formats.go b/openapi3/schema_formats.go index 5483e4e82..4402154c1 100644 --- a/openapi3/schema_formats.go +++ b/openapi3/schema_formats.go @@ -40,17 +40,11 @@ func DefineStringFormat(name string, pattern string) { panic(err) } SchemaStringFormats[name] = Format{regexp: re} - regexp: re, - callback: nil} - SchemaStringFormats[name] = f } // DefineStringFormatCallback ads a validation function for a specific schema format entry func DefineStringFormatCallback(name string, callback FormatCallback) { SchemaStringFormats[name] = Format{callback: callback} - regexp: nil, - callback: callback} - SchemaStringFormats[name] = f } func validateIP(ip string) (*net.IP, error) { From 774bc6363785ab9833a3892847ec0c9f2f18ee96 Mon Sep 17 00:00:00 2001 From: Riccardo Manfrin Date: Thu, 12 Nov 2020 00:33:56 +0100 Subject: [PATCH 16/23] Removes redundant check --- openapi3/schema.go | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/openapi3/schema.go b/openapi3/schema.go index 4160a57db..52690eadc 100644 --- a/openapi3/schema.go +++ b/openapi3/schema.go @@ -932,14 +932,11 @@ func (schema *Schema) visitJSONString(value string, fast bool) (err error) { // No pattern, but does have a format if f, ok := SchemaStringFormats[v]; ok { if f.regexp != nil && f.callback == nil { - re := f.regexp - if re != nil { - cp = &compiledPattern{ - Regexp: re, - ErrReason: "JSON string doesn't match the format '" + v + " (regular expression `" + re.String() + "`)'", - } - schema.compiledPattern = cp + schema.compiledPattern = &compiledPattern{ + Regexp: f.regexp, + ErrReason: "JSON string doesn't match the format '" + v + " (regular expression `" + re.String() + "`)'", } + } else if f.regexp == nil && f.callback != nil { return f.callback(value) } else { From 9c0b7aed80128b2692a783f7b8ce0ed0ee8948f5 Mon Sep 17 00:00:00 2001 From: Riccardo Manfrin Date: Thu, 12 Nov 2020 00:38:10 +0100 Subject: [PATCH 17/23] typo --- openapi3/schema_formats.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openapi3/schema_formats.go b/openapi3/schema_formats.go index 4402154c1..e93ae2c82 100644 --- a/openapi3/schema_formats.go +++ b/openapi3/schema_formats.go @@ -42,7 +42,7 @@ func DefineStringFormat(name string, pattern string) { SchemaStringFormats[name] = Format{regexp: re} } -// DefineStringFormatCallback ads a validation function for a specific schema format entry +// DefineStringFormatCallback adds a validation function for a specific schema format entry func DefineStringFormatCallback(name string, callback FormatCallback) { SchemaStringFormats[name] = Format{callback: callback} } From af108f2d64d62b517ddc89e736addbab5d6214ab Mon Sep 17 00:00:00 2001 From: Riccardo Manfrin Date: Thu, 12 Nov 2020 00:49:48 +0100 Subject: [PATCH 18/23] Fix --- openapi3/schema.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openapi3/schema.go b/openapi3/schema.go index 52690eadc..daf0b6646 100644 --- a/openapi3/schema.go +++ b/openapi3/schema.go @@ -934,7 +934,7 @@ func (schema *Schema) visitJSONString(value string, fast bool) (err error) { if f.regexp != nil && f.callback == nil { schema.compiledPattern = &compiledPattern{ Regexp: f.regexp, - ErrReason: "JSON string doesn't match the format '" + v + " (regular expression `" + re.String() + "`)'", + ErrReason: "JSON string doesn't match the format '" + v + " (regular expression `" + f.regexp.String() + "`)'", } } else if f.regexp == nil && f.callback != nil { From 48e4b0ad9f64fa19a8681ecbf5000e1c12a382da Mon Sep 17 00:00:00 2001 From: Pierre Fenoll Date: Thu, 12 Nov 2020 11:29:39 +0100 Subject: [PATCH 19/23] Update openapi3/schema_formats.go --- openapi3/schema_formats.go | 1 - 1 file changed, 1 deletion(-) diff --git a/openapi3/schema_formats.go b/openapi3/schema_formats.go index e93ae2c82..19cf3982c 100644 --- a/openapi3/schema_formats.go +++ b/openapi3/schema_formats.go @@ -11,7 +11,6 @@ const ( FormatOfStringForUUIDOfRFC4122 = `^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$` ) -// FormatType is the type of format validation used type FormatType string // FormatTypeRe is regexp based validation From 1736357c367abeca279c468002a0ea5e33fb0d83 Mon Sep 17 00:00:00 2001 From: Pierre Fenoll Date: Thu, 12 Nov 2020 11:30:50 +0100 Subject: [PATCH 20/23] Apply suggestions from code review --- openapi3/schema_formats.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/openapi3/schema_formats.go b/openapi3/schema_formats.go index 19cf3982c..7137f28ef 100644 --- a/openapi3/schema_formats.go +++ b/openapi3/schema_formats.go @@ -11,10 +11,7 @@ const ( FormatOfStringForUUIDOfRFC4122 = `^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$` ) -type FormatType string -// FormatTypeRe is regexp based validation -const FormatTypeRe = "re" // FormatTypeCallback is callback based validation const FormatTypeCallback = "callback" @@ -22,7 +19,6 @@ const FormatTypeCallback = "callback" //FormatCallback custom check on exotic formats type FormatCallback func(Val string) error -//Format is the format type context fo validate the format type Format struct { regexp *regexp.Regexp callback FormatCallback From c58b987e96d0f0b4b78b1ad71da9c3319ff66851 Mon Sep 17 00:00:00 2001 From: Pierre Fenoll Date: Thu, 12 Nov 2020 11:32:25 +0100 Subject: [PATCH 21/23] Apply suggestions from code review --- openapi3/schema_formats.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/openapi3/schema_formats.go b/openapi3/schema_formats.go index 7137f28ef..65a58daca 100644 --- a/openapi3/schema_formats.go +++ b/openapi3/schema_formats.go @@ -13,9 +13,6 @@ const ( -// FormatTypeCallback is callback based validation -const FormatTypeCallback = "callback" - //FormatCallback custom check on exotic formats type FormatCallback func(Val string) error From d9145d4bb45fa3a01703d98a70df126677fe51e5 Mon Sep 17 00:00:00 2001 From: Pierre Fenoll Date: Thu, 12 Nov 2020 11:45:08 +0100 Subject: [PATCH 22/23] Update openapi3/schema_formats.go --- openapi3/schema_formats.go | 1 - 1 file changed, 1 deletion(-) diff --git a/openapi3/schema_formats.go b/openapi3/schema_formats.go index 65a58daca..634dd30f9 100644 --- a/openapi3/schema_formats.go +++ b/openapi3/schema_formats.go @@ -12,7 +12,6 @@ const ( ) - //FormatCallback custom check on exotic formats type FormatCallback func(Val string) error From bcf4aae5a1b9d2960b65d63f9fa33a04c51671c6 Mon Sep 17 00:00:00 2001 From: Pierre Fenoll Date: Thu, 12 Nov 2020 11:46:34 +0100 Subject: [PATCH 23/23] Update openapi3/schema_formats.go --- openapi3/schema_formats.go | 1 - 1 file changed, 1 deletion(-) diff --git a/openapi3/schema_formats.go b/openapi3/schema_formats.go index 634dd30f9..ab2992bc9 100644 --- a/openapi3/schema_formats.go +++ b/openapi3/schema_formats.go @@ -11,7 +11,6 @@ const ( FormatOfStringForUUIDOfRFC4122 = `^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$` ) - //FormatCallback custom check on exotic formats type FormatCallback func(Val string) error