Skip to content

Infinite loop if circular reference doesn't start with top-level definition #775

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

Open
mikeharder opened this issue Mar 21, 2025 · 0 comments

Comments

@mikeharder
Copy link
Member

mikeharder commented Mar 21, 2025

In this PR, LintDiff was hanging because @stoplight/json-ref-resolver was in an infinite loop of circular references.

Azure/azure-rest-api-specs#32573 (comment)

I believe @stoplight/json-ref-resolver can only reliably handle circular references, if the cycle includes the top-level definition in the file you are trying to resolve.

https://github.com/stoplightio/json-ref-resolver/blob/e4e2410e86edcc7a96e01d309039ad319ca40f2c/src/crawler.ts#L115-L118

In the example PR, if CommunicationErrorResponse is in a different JSON file than CommunicationError (which has a circular reference to CommunicationError), the cycle can be detected immediately. So instead of running forever, it completes on the spec in 3 seconds.

But if CommunicationErrorResponse and CommunicationError are siblings in the same JSON file, json-ref-resolver falls into a different codepath where it can't detect the cycle.

This example doesn't hang, because the cycle is ErrorResponse->ErrorResponse, and ErrorResponse is the top-level object under definitions we are resolving:

"definitions": {
"ErrorResponse": {
"properties": {
"code": {
"type": "string"
},
"detail": {
"$ref": "#/definitions/ErrorResponse"
}
}
}

However, this example should hang when trying to resolve ErrorResponse, since the cycle is ErrorResponse->Error->Error..., but since the cycle doesn't go through ErrorResponse, it isn't detected by json-ref-resolver.

  "definitions": {
    "ErrorResponse": {
      "properties": {
        "code": {
          "type": "string"
        },
        "detail": {
          "$ref": "#/definitions/Error"
        }
      },
    "Error": {
      "properties": {
        "code": {
          "type": "string"
        },
        "detail": {
          "$ref": "#/definitions/Error"
        }
      }
    }
@mikeharder mikeharder changed the title Infinite loop if circular reference doesn't start with a top-level definition Infinite loop if circular reference doesn't start with top-level definition Mar 21, 2025
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

No branches or pull requests

1 participant