From 7c5b4653f463b4f52e717cd820f5969f3b84eb1d Mon Sep 17 00:00:00 2001 From: Pierre Fenoll Date: Sat, 2 Oct 2021 12:14:52 +0200 Subject: [PATCH 1/3] reproduce isse #430 Signed-off-by: Pierre Fenoll --- openapi3/schema_formats_test.go | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 openapi3/schema_formats_test.go diff --git a/openapi3/schema_formats_test.go b/openapi3/schema_formats_test.go new file mode 100644 index 000000000..bd3d951ed --- /dev/null +++ b/openapi3/schema_formats_test.go @@ -0,0 +1,21 @@ +package openapi3 + +import ( + "context" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestIssue430(t *testing.T) { + schema := NewOneOfSchema( + NewStringSchema().WithFormat("ipv4"), + NewStringSchema().WithFormat("ipv6"), + ) + + err := schema.Validate(context.Background()) + require.NoError(t, err) + + err = schema.VisitJSON("127.0.1.1") + require.NoError(t, err) +} From 83f14b966911c043ba2215b4d573310596c652c8 Mon Sep 17 00:00:00 2001 From: Pierre Fenoll Date: Sat, 2 Oct 2021 12:20:42 +0200 Subject: [PATCH 2/3] right Signed-off-by: Pierre Fenoll --- openapi3/schema_formats_test.go | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/openapi3/schema_formats_test.go b/openapi3/schema_formats_test.go index bd3d951ed..de5c9355f 100644 --- a/openapi3/schema_formats_test.go +++ b/openapi3/schema_formats_test.go @@ -1,21 +1,28 @@ -package openapi3 +package openapi3_test import ( "context" "testing" + "github.com/getkin/kin-openapi/openapi3" "github.com/stretchr/testify/require" ) func TestIssue430(t *testing.T) { - schema := NewOneOfSchema( - NewStringSchema().WithFormat("ipv4"), - NewStringSchema().WithFormat("ipv6"), + schema := openapi3.NewOneOfSchema( + openapi3.NewStringSchema().WithFormat("ipv4"), + openapi3.NewStringSchema().WithFormat("ipv6"), ) err := schema.Validate(context.Background()) require.NoError(t, err) + err = schema.VisitJSON("127.0.1.1") + require.Error(t, err, openapi3.ErrOneOfConflict.Error()) + + openapi3.DefineIPv4Format() + openapi3.DefineIPv6Format() + err = schema.VisitJSON("127.0.1.1") require.NoError(t, err) } From 33a01e384e9e35305905b93a4af2702f7eb8d9eb Mon Sep 17 00:00:00 2001 From: Pierre Fenoll Date: Sat, 2 Oct 2021 12:51:02 +0200 Subject: [PATCH 3/3] sort out possible mishandling of ipv4 vs v6 Signed-off-by: Pierre Fenoll --- openapi3/schema_formats.go | 18 ++++++------ openapi3/schema_formats_test.go | 51 ++++++++++++++++++++++++++------- 2 files changed, 49 insertions(+), 20 deletions(-) diff --git a/openapi3/schema_formats.go b/openapi3/schema_formats.go index 1eb41509e..095bb2228 100644 --- a/openapi3/schema_formats.go +++ b/openapi3/schema_formats.go @@ -4,6 +4,7 @@ import ( "fmt" "net" "regexp" + "strings" ) const ( @@ -37,24 +38,23 @@ func DefineStringFormatCallback(name string, callback FormatCallback) { SchemaStringFormats[name] = Format{callback: callback} } -func validateIP(ip string) (*net.IP, error) { +func validateIP(ip string) error { parsed := net.ParseIP(ip) if parsed == nil { - return nil, &SchemaError{ + return &SchemaError{ Value: ip, Reason: "Not an IP address", } } - return &parsed, nil + return nil } func validateIPv4(ip string) error { - parsed, err := validateIP(ip) - if err != nil { + if err := validateIP(ip); err != nil { return err } - if parsed.To4() == nil { + if !(strings.Count(ip, ":") < 2) { return &SchemaError{ Value: ip, Reason: "Not an IPv4 address (it's IPv6)", @@ -62,13 +62,13 @@ func validateIPv4(ip string) error { } return nil } + func validateIPv6(ip string) error { - parsed, err := validateIP(ip) - if err != nil { + if err := validateIP(ip); err != nil { return err } - if parsed.To4() != nil { + if !(strings.Count(ip, ":") >= 2) { return &SchemaError{ Value: ip, Reason: "Not an IPv6 address (it's IPv4)", diff --git a/openapi3/schema_formats_test.go b/openapi3/schema_formats_test.go index de5c9355f..14733c8a1 100644 --- a/openapi3/schema_formats_test.go +++ b/openapi3/schema_formats_test.go @@ -1,28 +1,57 @@ -package openapi3_test +package openapi3 import ( "context" "testing" - "github.com/getkin/kin-openapi/openapi3" "github.com/stretchr/testify/require" ) func TestIssue430(t *testing.T) { - schema := openapi3.NewOneOfSchema( - openapi3.NewStringSchema().WithFormat("ipv4"), - openapi3.NewStringSchema().WithFormat("ipv6"), + schema := NewOneOfSchema( + NewStringSchema().WithFormat("ipv4"), + NewStringSchema().WithFormat("ipv6"), ) err := schema.Validate(context.Background()) require.NoError(t, err) - err = schema.VisitJSON("127.0.1.1") - require.Error(t, err, openapi3.ErrOneOfConflict.Error()) + data := map[string]bool{ + "127.0.1.1": true, - openapi3.DefineIPv4Format() - openapi3.DefineIPv6Format() + // https://stackoverflow.com/a/48519490/1418165 - err = schema.VisitJSON("127.0.1.1") - require.NoError(t, err) + // v4 + "192.168.0.1": true, + // "192.168.0.1:80" doesn't parse per net.ParseIP() + + // v6 + "::FFFF:C0A8:1": false, + "::FFFF:C0A8:0001": false, + "0000:0000:0000:0000:0000:FFFF:C0A8:1": false, + // "::FFFF:C0A8:1%1" doesn't parse per net.ParseIP() + "::FFFF:192.168.0.1": false, + // "[::FFFF:C0A8:1]:80" doesn't parse per net.ParseIP() + // "[::FFFF:C0A8:1%1]:80" doesn't parse per net.ParseIP() + } + + for datum := range data { + err = schema.VisitJSON(datum) + require.Error(t, err, ErrOneOfConflict.Error()) + } + + DefineIPv4Format() + DefineIPv6Format() + + for datum, isV4 := range data { + err = schema.VisitJSON(datum) + require.NoError(t, err) + if isV4 { + require.Nil(t, validateIPv4(datum), "%q should be IPv4", datum) + require.NotNil(t, validateIPv6(datum), "%q should not be IPv6", datum) + } else { + require.NotNil(t, validateIPv4(datum), "%q should not be IPv4", datum) + require.Nil(t, validateIPv6(datum), "%q should be IPv6", datum) + } + } }