Azure / Azure/azure-openapi-validator
Infinite loop if circular reference doesn't start with top-level definition
- Dominant language
- TypeScript
- Stars
- 53
- Forks
- 57
- Avg merge
- 1d 23h
- Merged PRs (30d)
- 2
Description
In this PR, LintDiff was hanging because `@stoplight/json-ref-resolver` was in an infinite loop of circular references.
https://github.com/Azure/azure-rest-api-specs/pull/32573#issuecomment-2742225135
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:
https://github.com/Azure/azure-openapi-validator/blob/61cc5718e5520ac3afe6406593c9a4cc2e1ec63b/packages/rulesets/src/native/tests/resources/references/circular-ref.json#L15-L25
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"
}
}
}
```
Contributor guide
Assessment
This issue has not been assessed yet.