Visitar URL original
fix/boolean schemas to v2 by baywet · Pull Request #2840 · microsoft/OpenAPI.NET · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
fix: null reference exception for boolean component schemas
Co-authored-by: Copilot <copilot@github.com>
Signed-off-by: Vincent Biret <vibiret@microsoft.com>
(cherry picked from commit fe0b50a)
  • Loading branch information
baywet and Copilot committed Apr 27, 2026
commit cc13028ab39a4d39c844e0e835557e07fb5db4bf
10 changes: 10 additions & 0 deletions src/Microsoft.OpenApi/Services/OpenApiWorkspace.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ public void RegisterComponents(OpenApiDocument document)
{
foreach (var item in document.Components.Schemas)
{
if (item.Value == null) continue;
location = item.Value.Id ?? baseUri + ReferenceType.Schema.GetDisplayName() + ComponentSegmentSeparator + item.Key;
RegisterComponent(location, item.Value);
}
Expand All @@ -103,6 +104,7 @@ public void RegisterComponents(OpenApiDocument document)
{
foreach (var item in document.Components.Parameters)
{
if (item.Value == null) continue;
location = baseUri + ReferenceType.Parameter.GetDisplayName() + ComponentSegmentSeparator + item.Key;
RegisterComponent(location, item.Value);
}
Expand All @@ -113,6 +115,7 @@ public void RegisterComponents(OpenApiDocument document)
{
foreach (var item in document.Components.Responses)
{
if (item.Value == null) continue;
location = baseUri + ReferenceType.Response.GetDisplayName() + ComponentSegmentSeparator + item.Key;
RegisterComponent(location, item.Value);
}
Expand All @@ -123,6 +126,7 @@ public void RegisterComponents(OpenApiDocument document)
{
foreach (var item in document.Components.RequestBodies)
{
if (item.Value == null) continue;
location = baseUri + ReferenceType.RequestBody.GetDisplayName() + ComponentSegmentSeparator + item.Key;
RegisterComponent(location, item.Value);
}
Expand All @@ -133,6 +137,7 @@ public void RegisterComponents(OpenApiDocument document)
{
foreach (var item in document.Components.Links)
{
if (item.Value == null) continue;
location = baseUri + ReferenceType.Link.GetDisplayName() + ComponentSegmentSeparator + item.Key;
RegisterComponent(location, item.Value);
}
Expand All @@ -143,6 +148,7 @@ public void RegisterComponents(OpenApiDocument document)
{
foreach (var item in document.Components.Callbacks)
{
if (item.Value == null) continue;
location = baseUri + ReferenceType.Callback.GetDisplayName() + ComponentSegmentSeparator + item.Key;
RegisterComponent(location, item.Value);
}
Expand All @@ -153,6 +159,7 @@ public void RegisterComponents(OpenApiDocument document)
{
foreach (var item in document.Components.PathItems)
{
if (item.Value == null) continue;
location = baseUri + ReferenceType.PathItem.GetDisplayName() + ComponentSegmentSeparator + item.Key;
RegisterComponent(location, item.Value);
}
Expand All @@ -163,6 +170,7 @@ public void RegisterComponents(OpenApiDocument document)
{
foreach (var item in document.Components.Examples)
{
if (item.Value == null) continue;
location = baseUri + ReferenceType.Example.GetDisplayName() + ComponentSegmentSeparator + item.Key;
RegisterComponent(location, item.Value);
}
Expand All @@ -173,6 +181,7 @@ public void RegisterComponents(OpenApiDocument document)
{
foreach (var item in document.Components.Headers)
{
if (item.Value == null) continue;
location = baseUri + ReferenceType.Header.GetDisplayName() + ComponentSegmentSeparator + item.Key;
RegisterComponent(location, item.Value);
}
Expand All @@ -183,6 +192,7 @@ public void RegisterComponents(OpenApiDocument document)
{
foreach (var item in document.Components.SecuritySchemes)
{
if (item.Value == null) continue;
location = baseUri + ReferenceType.SecurityScheme.GetDisplayName() + ComponentSegmentSeparator + item.Key;
RegisterComponent(location, item.Value);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -611,5 +611,42 @@ public async Task ValidateReferencedExampleInSchemaWorks()
Assert.Empty(result.Diagnostic.Errors);
Assert.Empty(result.Diagnostic.Warnings);
}

[Fact]
public async Task ParseDocumentWithSelfExtensionWorks()
{
// Arrange && Act
var path = Path.Combine(SampleFolderPath, "documentWithSelfExtension.yaml");
var result = await OpenApiDocument.LoadAsync(path, SettingsFixture.ReaderSettings);

// Assert
Assert.NotNull(result.Document);
Assert.NotNull(result.Document.Self);
Assert.Equal("https://example.org/api/openapi.yaml", result.Document.Self.ToString());
Assert.Equal("API with x-oai-$self extension", result.Document.Info.Title);
Assert.Equal("1.0.0", result.Document.Info.Version);
// The x-oai-$self extension should be moved to the Self property and not remain in extensions
Assert.Null(result.Document.Extensions);
Assert.Empty(result.Diagnostic.Errors);
Assert.Empty(result.Diagnostic.Warnings);
}

[Fact]
public void LoadDocumentWithBooleanSchemaShouldNotThrowNullReferenceException()
{
// Arrange - OpenAPI 3.1 with a boolean schema in components/schemas (spec-valid per JSON Schema 2020-12)
var bytes = "{\"openapi\":\"3.1.0\",\"components\":{\"schemas\":{\"X\":true}}}"u8.ToArray();
using var ms = new MemoryStream(bytes);

// Act & Assert - should not throw NullReferenceException
var exception = Record.Exception(() => OpenApiDocument.Load(ms, format: null, new OpenApiReaderSettings()));

// The parser should handle the boolean schema gracefully
// Either accepting it or surfacing a structured diagnostic, but not throwing NullReferenceException
if (exception != null)
{
Assert.IsNotType<NullReferenceException>(exception);
}
}
}
}