From 43044d59409fb14d89e2a52a13995ae1521423a3 Mon Sep 17 00:00:00 2001 From: Carsten Brandt Date: Wed, 9 Feb 2022 14:29:52 +0100 Subject: [PATCH] Catch recursion when resolving inside included file fixes #144 --- Makefile | 2 +- src/spec/Reference.php | 11 +++++++- tests/spec/data/recursion3_index.yaml | 31 +++++++++++++++++++++ tests/spec/data/recursion3_menu_tree.yaml | 33 +++++++++++++++++++++++ 4 files changed, 75 insertions(+), 2 deletions(-) create mode 100644 tests/spec/data/recursion3_index.yaml create mode 100644 tests/spec/data/recursion3_menu_tree.yaml diff --git a/Makefile b/Makefile index a1810c8..ee99b2a 100644 --- a/Makefile +++ b/Makefile @@ -41,7 +41,7 @@ install: composer.lock yarn.lock $(DOCKER_PHP) composer install --prefer-dist --no-interaction --no-progress --ansi $(DOCKER_NODE) yarn install -test: unit test-recursion.json test-recursion2.yaml test-empty-maps.json +test: unit test-recursion.json test-recursion2.yaml test-recursion3_index.yaml test-empty-maps.json unit: $(DOCKER_PHP) php $(PHPARGS) $(XPHPARGS) vendor/bin/phpunit --verbose --colors=always $(TESTCASE) diff --git a/src/spec/Reference.php b/src/spec/Reference.php index ce99d9e..cda612a 100644 --- a/src/spec/Reference.php +++ b/src/spec/Reference.php @@ -289,6 +289,8 @@ private function resolveTransitiveReference(Reference $referencedObject, Referen return $transitiveRefResult; } + private $_recursingInsideFile = false; + /** * Adjust relative references inside of the file to match the context of the base file */ @@ -306,7 +308,14 @@ private function adjustRelativeReferences($referencedDocument, $basePath, $baseD // direcly inline references in the same document, // these are not going to be valid in the new context anymore $inlineDocument = (new JsonPointer(substr($value, 1)))->evaluate($baseDocument); - return $this->adjustRelativeReferences($inlineDocument, $basePath, $baseDocument, $oContext); + if ($this->_recursingInsideFile) { + // keep reference when it is a recursive reference + return ['$ref' => $basePath . $value]; + } + $this->_recursingInsideFile = true; + $return = $this->adjustRelativeReferences($inlineDocument, $basePath, $baseDocument, $oContext); + $this->_recursingInsideFile = false; + return $return; } $referencedDocument[$key] = $context->resolveRelativeUri($value); $parts = explode('#', $referencedDocument[$key], 2); diff --git a/tests/spec/data/recursion3_index.yaml b/tests/spec/data/recursion3_index.yaml new file mode 100644 index 0000000..dff63d6 --- /dev/null +++ b/tests/spec/data/recursion3_index.yaml @@ -0,0 +1,31 @@ +openapi: 3.0.3 +info: + title: Link Example + version: 1.0.0 +#components: +# parameters: +# "Parameter.PetId": +# "$ref": "./subdir/Parameter.PetId.json" +paths: + /contents/menus/{id}/trees: + put: + tags: + - menus + operationId: updateMenuTrees + summary: '123' + description: '456' +# parameters: +# - $ref: '#/components/parameters/PathId' + requestBody: + required: true + content: + application/json: + schema: + $ref: './recursion3_menu_tree.yaml#/UpdateMenuTreesRequest' + responses: + "200": + description: Успешный ответ + content: + application/json: + schema: + $ref: './recursion3_menu_tree.yaml#/UpdateMenuTreesResponse' diff --git a/tests/spec/data/recursion3_menu_tree.yaml b/tests/spec/data/recursion3_menu_tree.yaml new file mode 100644 index 0000000..bce418d --- /dev/null +++ b/tests/spec/data/recursion3_menu_tree.yaml @@ -0,0 +1,33 @@ +MenuTree: + type: object + properties: + name: + type: string + description: 'Name' + example: 'Home' + url: + type: string + description: Link + nullable: true + example: '/about/' + children: + type: array + items: + $ref: '#/MenuTree' + example: [] +UpdateMenuTreesRequest: + type: object + properties: + items: + type: array + items: + $ref: '#/MenuTree' +UpdateMenuTreesResponse: + type: object + properties: + data: + type: array + items: + $ref: '#/MenuTree' + required: + - data