From 256193b15085a6c921a14d03f8f963cddeb582e5 Mon Sep 17 00:00:00 2001 From: Vincent Behar Date: Thu, 16 Sep 2021 14:44:33 +0200 Subject: [PATCH 1/4] fix: conversion with a parameter schema ref converting from v3 to v2 with an endpoint using a parameter with a schema ref used to fail with the following error: ``` --- FAIL: TestConvOpenAPIV3ToV2 (0.00s) panic: runtime error: invalid memory address or nil pointer dereference [recovered] panic: runtime error: invalid memory address or nil pointer dereference [signal SIGSEGV: segmentation violation code=0x2 addr=0x58 pc=0x100f71688] goroutine 4 [running]: testing.tRunner.func1.2({0x101035da0, 0x1012b6160}) /opt/homebrew/Cellar/go/1.17/libexec/src/testing/testing.go:1209 +0x258 testing.tRunner.func1(0x14000117380) /opt/homebrew/Cellar/go/1.17/libexec/src/testing/testing.go:1212 +0x284 panic({0x101035da0, 0x1012b6160}) /opt/homebrew/Cellar/go/1.17/libexec/src/runtime/panic.go:1038 +0x21c github.com/getkin/kin-openapi/openapi2conv.FromV3Parameter(0x140001ce7c8, 0x1400007da18) /Users/vbehar/projects/oss/kin-openapi/openapi2conv/openapi2_conv.go:979 +0x138 github.com/getkin/kin-openapi/openapi2conv.FromV3Operation(0x1400007da00, 0x14000129c20) /Users/vbehar/projects/oss/kin-openapi/openapi2conv/openapi2_conv.go:895 +0x250 github.com/getkin/kin-openapi/openapi2conv.FromV3(0x1400007da00) /Users/vbehar/projects/oss/kin-openapi/openapi2conv/openapi2_conv.go:586 +0xddc github.com/getkin/kin-openapi/openapi2conv.TestConvOpenAPIV3ToV2(0x14000117380) /Users/vbehar/projects/oss/kin-openapi/openapi2conv/openapi2_conv_test.go:26 +0x19c testing.tRunner(0x14000117380, 0x1010870e8) /opt/homebrew/Cellar/go/1.17/libexec/src/testing/testing.go:1259 +0x104 created by testing.(*T).Run /opt/homebrew/Cellar/go/1.17/libexec/src/testing/testing.go:1306 +0x328 FAIL github.com/getkin/kin-openapi/openapi2conv 0.840s FAIL ``` This change fixes the issue by ensuring that we correctly handle a schema ref. --- openapi2conv/openapi2_conv.go | 42 ++++++++++--------- openapi2conv/openapi2_conv_test.go | 66 ++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+), 19 deletions(-) diff --git a/openapi2conv/openapi2_conv.go b/openapi2conv/openapi2_conv.go index 6877e88e8..e60e31da5 100644 --- a/openapi2conv/openapi2_conv.go +++ b/openapi2conv/openapi2_conv.go @@ -971,25 +971,29 @@ func FromV3Parameter(ref *openapi3.ParameterRef, components *openapi3.Components } if schemaRef := parameter.Schema; schemaRef != nil { schemaRef, _ = FromV3SchemaRef(schemaRef, components) - schema := schemaRef.Value - result.Type = schema.Type - result.Format = schema.Format - result.Enum = schema.Enum - result.Minimum = schema.Min - result.Maximum = schema.Max - result.ExclusiveMin = schema.ExclusiveMin - result.ExclusiveMax = schema.ExclusiveMax - result.MinLength = schema.MinLength - result.MaxLength = schema.MaxLength - result.Pattern = schema.Pattern - result.Default = schema.Default - result.Items = schema.Items - result.MinItems = schema.MinItems - result.MaxItems = schema.MaxItems - result.AllowEmptyValue = schema.AllowEmptyValue - // result.CollectionFormat = schema.CollectionFormat - result.UniqueItems = schema.UniqueItems - result.MultipleOf = schema.MultipleOf + if ref := schemaRef.Ref; ref != "" { + result.Schema = &openapi3.SchemaRef{Ref: FromV3Ref(ref)} + } + if schema := schemaRef.Value; schema != nil { + result.Type = schema.Type + result.Format = schema.Format + result.Enum = schema.Enum + result.Minimum = schema.Min + result.Maximum = schema.Max + result.ExclusiveMin = schema.ExclusiveMin + result.ExclusiveMax = schema.ExclusiveMax + result.MinLength = schema.MinLength + result.MaxLength = schema.MaxLength + result.Pattern = schema.Pattern + result.Default = schema.Default + result.Items = schema.Items + result.MinItems = schema.MinItems + result.MaxItems = schema.MaxItems + result.AllowEmptyValue = schema.AllowEmptyValue + // result.CollectionFormat = schema.CollectionFormat + result.UniqueItems = schema.UniqueItems + result.MultipleOf = schema.MultipleOf + } } return result, nil } diff --git a/openapi2conv/openapi2_conv_test.go b/openapi2conv/openapi2_conv_test.go index adb9b0814..7699076bf 100644 --- a/openapi2conv/openapi2_conv_test.go +++ b/openapi2conv/openapi2_conv_test.go @@ -79,6 +79,14 @@ const exampleV2 = ` "ItemExtension": { "description": "It could be anything.", "type": "boolean" + }, + "foo": { + "description": "foo description", + "enum": [ + "bar", + "baz" + ], + "type": "string" } }, "externalDocs": { @@ -305,6 +313,29 @@ const exampleV2 = ` }, "x-path": "path extension 1", "x-path2": "path extension 2" + }, + "/foo": { + "get": { + "operationId": "getFoo", + "parameters": [ + { + "in": "query", + "name": "foo", + "schema": { + "$ref": "#/definitions/foo" + } + } + ], + "responses": { + "default": { + "description": "OK", + "schema": { + "$ref": "#/definitions/foo" + } + } + }, + "summary": "get foo" + } } }, "responses": { @@ -420,6 +451,14 @@ const exampleV3 = ` "type": "string", "x-formData-name": "fileUpload2", "x-mimetype": "text/plain" + }, + "foo": { + "description": "foo description", + "enum": [ + "bar", + "baz" + ], + "type": "string" } } }, @@ -646,6 +685,33 @@ const exampleV3 = ` }, "x-path": "path extension 1", "x-path2": "path extension 2" + }, + "/foo": { + "get": { + "operationId": "getFoo", + "parameters": [ + { + "in": "query", + "name": "foo", + "schema": { + "$ref": "#/components/schemas/foo" + } + } + ], + "responses": { + "default": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/foo" + } + } + }, + "description": "OK" + } + }, + "summary": "get foo" + } } }, "security": [ From 2116bb2244eaa808920cef98a9811aaec9e505d6 Mon Sep 17 00:00:00 2001 From: Pierre Fenoll Date: Thu, 2 Dec 2021 17:24:17 +0100 Subject: [PATCH 2/4] make tests valid Signed-off-by: Pierre Fenoll --- openapi2conv/openapi2_conv_test.go | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/openapi2conv/openapi2_conv_test.go b/openapi2conv/openapi2_conv_test.go index 466a1a7bd..f8f287836 100644 --- a/openapi2conv/openapi2_conv_test.go +++ b/openapi2conv/openapi2_conv_test.go @@ -317,9 +317,14 @@ const exampleV2 = ` "/foo": { "get": { "operationId": "getFoo", + "consumes": [ + "application/json", + "application/xml" + ], "parameters": [ { - "in": "query", + "x-originalParamName": "foo", + "in": "body", "name": "foo", "schema": { "$ref": "#/definitions/foo" @@ -689,15 +694,21 @@ const exampleV3 = ` "/foo": { "get": { "operationId": "getFoo", - "parameters": [ - { - "in": "query", - "name": "foo", - "schema": { - "$ref": "#/components/schemas/foo" + "requestBody": { + "x-originalParamName": "foo", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/foo" + } + }, + "application/xml": { + "schema": { + "$ref": "#/components/schemas/foo" + } } } - ], + }, "responses": { "default": { "content": { From 53c0b12f6b058d082df50592975fb1eb7fa44f00 Mon Sep 17 00:00:00 2001 From: Pierre Fenoll Date: Thu, 2 Dec 2021 17:24:33 +0100 Subject: [PATCH 3/4] a smaller diff Signed-off-by: Pierre Fenoll --- openapi2conv/openapi2_conv.go | 42 +++++++++++++++++------------------ 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/openapi2conv/openapi2_conv.go b/openapi2conv/openapi2_conv.go index b2fe78464..c61a985ed 100644 --- a/openapi2conv/openapi2_conv.go +++ b/openapi2conv/openapi2_conv.go @@ -982,27 +982,27 @@ func FromV3Parameter(ref *openapi3.ParameterRef, components *openapi3.Components schemaRef, _ = FromV3SchemaRef(schemaRef, components) if ref := schemaRef.Ref; ref != "" { result.Schema = &openapi3.SchemaRef{Ref: FromV3Ref(ref)} - } - if schema := schemaRef.Value; schema != nil { - result.Type = schema.Type - result.Format = schema.Format - result.Enum = schema.Enum - result.Minimum = schema.Min - result.Maximum = schema.Max - result.ExclusiveMin = schema.ExclusiveMin - result.ExclusiveMax = schema.ExclusiveMax - result.MinLength = schema.MinLength - result.MaxLength = schema.MaxLength - result.Pattern = schema.Pattern - result.Default = schema.Default - result.Items = schema.Items - result.MinItems = schema.MinItems - result.MaxItems = schema.MaxItems - result.AllowEmptyValue = schema.AllowEmptyValue - // result.CollectionFormat = schema.CollectionFormat - result.UniqueItems = schema.UniqueItems - result.MultipleOf = schema.MultipleOf - } + return result, nil + } + schema := schemaRef.Value + result.Type = schema.Type + result.Format = schema.Format + result.Enum = schema.Enum + result.Minimum = schema.Min + result.Maximum = schema.Max + result.ExclusiveMin = schema.ExclusiveMin + result.ExclusiveMax = schema.ExclusiveMax + result.MinLength = schema.MinLength + result.MaxLength = schema.MaxLength + result.Pattern = schema.Pattern + result.Default = schema.Default + result.Items = schema.Items + result.MinItems = schema.MinItems + result.MaxItems = schema.MaxItems + result.AllowEmptyValue = schema.AllowEmptyValue + // result.CollectionFormat = schema.CollectionFormat + result.UniqueItems = schema.UniqueItems + result.MultipleOf = schema.MultipleOf } return result, nil } From 25ce82dad876bafd4aee478f2b5b91028810238d Mon Sep 17 00:00:00 2001 From: Pierre Fenoll Date: Thu, 2 Dec 2021 17:24:42 +0100 Subject: [PATCH 4/4] pass tests Signed-off-by: Pierre Fenoll --- openapi2conv/openapi2_conv.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/openapi2conv/openapi2_conv.go b/openapi2conv/openapi2_conv.go index c61a985ed..04cb18d2e 100644 --- a/openapi2conv/openapi2_conv.go +++ b/openapi2conv/openapi2_conv.go @@ -298,6 +298,10 @@ func ToV3Parameter(components *openapi3.Components, parameter *openapi2.Paramete required = true } + var schemaRefRef string + if schemaRef := parameter.Schema; schemaRef != nil && schemaRef.Ref != "" { + schemaRefRef = schemaRef.Ref + } result := &openapi3.Parameter{ In: parameter.In, Name: parameter.Name, @@ -322,7 +326,9 @@ func ToV3Parameter(components *openapi3.Components, parameter *openapi2.Paramete AllowEmptyValue: parameter.AllowEmptyValue, UniqueItems: parameter.UniqueItems, MultipleOf: parameter.MultipleOf, - }}), + }, + Ref: schemaRefRef, + }), } return &openapi3.ParameterRef{Value: result}, nil, nil, nil }