Skip to content

ArgumentOutOfRangeException thrown if empty stream passed to OpenApiDocument.Load #2130

@martincostello

Description

@martincostello

Describe the bug

If an empty MemoryStream is passed to OpenApiDocument.Load(), an ArgumentOutOfRangeException is thrown from down in the internal call stack of the method:

System.ArgumentOutOfRangeException : Index was out of range. Must be non-negative and less than the size of the collection. (Parameter 'index')

  Stack Trace: 
List`1.get_Item(Int32 index)
OpenApiYamlReader.LoadJsonNodesFromYamlDocument(TextReader input)
OpenApiYamlReader.Read(MemoryStream input, OpenApiReaderSettings settings)
OpenApiModelFactory.InternalLoad(MemoryStream input, String format, OpenApiReaderSettings settings)
OpenApiModelFactory.Load(MemoryStream stream, String format, OpenApiReaderSettings settings)
OpenApiDocument.Load(MemoryStream stream, String format, OpenApiReaderSettings settings)

The public surface of the API should perform some basic validation to provide a more useful exception/message to the user, or at a minimum this line of code should check the array contains at least 1 element:

var yamlDocument = yamlStream.Documents[0];

OpenApi File To Reproduce

N/A

Expected behavior

A useful exception is thrown to the user.

Screenshots/Code Snippets

OpenApiDocument.Load(new MemoryStream());

Additional context

Discovered while migrating to Microsoft.OpenApi 2.0.0-preview.5 in domaindrivendev/Swashbuckle.AspNetCore#3252 due to forgetting to update the stream position after copying a FileStream to a MemoryStream.

public static void AddOpenApiFile(this ApiTestRunnerOptions options, string documentName, string filePath)
{
    using var fileStream = File.OpenRead(filePath);
+   using var memoryStream = new MemoryStream();

    fileStream.CopyTo(memoryStream);
+   // Line below was missing
+   //memoryStream.Seek(0, SeekOrigin.Begin);

-   var openApiDocument = new OpenApiStreamReader().Read(fileStream, out var diagnostic);
-   options.OpenApiDocs.Add(documentName, openApiDocument);
+   var result = OpenApiDocument.Load(memoryStream);
+   options.OpenApiDocs.Add(documentName, result.Document);
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions