Skip to content

OpenApiComparer - Stack OverFlow #505

@AndrewRissing

Description

@AndrewRissing

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 here

Details

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions