Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Path item internalization context issue #831

Closed
radwaretaltr opened this issue Aug 30, 2023 · 1 comment · Fixed by #832
Closed

Path item internalization context issue #831

radwaretaltr opened this issue Aug 30, 2023 · 1 comment · Fixed by #832

Comments

@radwaretaltr
Copy link
Contributor

radwaretaltr commented Aug 30, 2023

Hi,

Looks like there is a slight issue in the ref internalization code.

func (doc *T) derefPaths(paths map[string]*PathItem, refNameResolver RefNameResolver, parentIsExternal bool) {

It seems that parentIsExternal is modified inside the for loop and the modification persists causing it to effect other iterations of the loop.

if isExternalRef(ops.Ref, parentIsExternal) { parentIsExternal = true }

Meaning, if a previous path item (ops) was an external reference, parentIsExternal will be also set to true for the next path item even if the next path item isn't an external reference.

The effect of the issue is especially seen when customizing refNameResolver but I was also able to create an example with the default refNameResolver:

For example, for a root document:

openapi: "3.0.3"
info:
  title: Recursive refs example
  version: "1.0"
paths:
  /bar:
    $ref: ./path.yml
  /foo:
    post:
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/requestBodies/test/content/application~1json/schema"
      responses:
        '200':
          description: Expected response to a valid request
components:
  requestBodies:
    test:
      content:
        application/json:
          schema:
            type: string

And a document named 'path.yaml' under the same folder:

get:
  responses:
    "200":
      description: OK

The result is:

{
   "components":{
      "requestBodies":{
         "test":{
            "content":{
               "application/json":{
                  "schema":{
                     "type":"string"
                  }
               }
            }
         }
      },
      "schemas":{
         "schema":{
            "type":"string"
         }
      }
   },
   "info":{
      "title":"Recursive refs example",
      "version":"1.0"
   },
   "openapi":"3.0.3",
   "paths":{
      "/bar":{
         "get":{
            "responses":{
               "200":{
                  "description":"OK"
               }
            }
         }
      },
      "/foo":{
         "post":{
            "requestBody":{
               "content":{
                  "application/json":{
                     "schema":{
                        **"$ref":"#/components/schemas/schema"**
                     }
                  }
               }
            },
            "responses":{
               "200":{
                  "description":"Expected response to a valid request"
               }
            }
         }
      }
   }
}

/foo was processed after /bar which set parentIsExternal to true. This caused everything under /foo to be processed as if it has an external reference parent: $ref: "#/components/requestBodies/test/content/application~1json/schema" was "internalized" and replaced with "$ref":"#/components/schemas/schema".

@radwaretaltr
Copy link
Contributor Author

Hi @fenollp @jhwz,
Could you please take a look?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant