-
Notifications
You must be signed in to change notification settings - Fork 280
Description
Steps to Reproduce
Commit: cb3c26b (vnext)
Code:
var input = await new HttpClient().GetStringAsync("https://petstore.swagger.io/v2/swagger.json");
var doc = new OpenApiStringReader().Read(input, out _);
var result = OpenApiComparer.Compare(doc, doc); // StackOverFlowException hereDetails
While testing out the OpenApiComparer against a fairly vanilla example (Swagger's Petstore), I noticed that the code kept failing with a stack overflow.
Digging into it, the calls kept bouncing between the OpenApiSecuritySchemeComparer and OpenApiReferenceComparer trying to dereference a self-referencing element.
The self-reference is due to this logic in the MapNode class that replaces any null Reference with a reference to itself.
This hasn't been caught before due to all of the unit tests creating a C# OpenApiDocument by hand, which doesn't exhibit the same self-referencing produced by the MapNode class.
Suggested Solution
I'm currently working on a PR to resolve the above, but any comments before I get there would be appreciated if the below approach isn't the desirable path.
I've recreated the problem within the OpenApiComparerTests by creating a visitor that updates all of the Component IOpenApiReferenceable collections with a self-reference that mirrors the behavior of MapNode.
I've replaced the OpenApiSecuritySchemeComparer's logic here with the following:
if (sourceSecurityScheme.Reference != null)
{
sourceSecurityScheme = (OpenApiSecurityScheme)comparisonContext.SourceDocument.ResolveReference(
sourceSecurityScheme.Reference);
}
if (targetSecurityScheme.Reference != null)
{
targetSecurityScheme = (OpenApiSecurityScheme)comparisonContext.TargetDocument.ResolveReference(
targetSecurityScheme.Reference);
}This corrects the problem with the provided 'PetStore' example, but the remaining tests are failing. I'll apply a similar change to the other impacted comparers and create the PR once done.
This issue seems to exist in the following as well:
As a side note, I'm not sure how crucial that self-reference is, but if it could be removed that might benefit the codebase and potentially those trying to walk the OpenApiDocument themselves.