diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml
index 44ae4d602..27eb18d23 100644
--- a/.github/workflows/docker.yml
+++ b/.github/workflows/docker.yml
@@ -30,13 +30,13 @@ jobs:
id: getversion
- name: Push to GitHub Packages - Nightly
if: ${{ github.ref == 'refs/heads/vnext' }}
- uses: docker/build-push-action@v5.4.0
+ uses: docker/build-push-action@v6.1.0
with:
push: true
tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:nightly
- name: Push to GitHub Packages - Release
if: ${{ github.ref == 'refs/heads/master' }}
- uses: docker/build-push-action@v5.4.0
+ uses: docker/build-push-action@v6.1.0
with:
push: true
tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest,${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.getversion.outputs.version }}
diff --git a/src/Microsoft.OpenApi.Hidi/Microsoft.OpenApi.Hidi.csproj b/src/Microsoft.OpenApi.Hidi/Microsoft.OpenApi.Hidi.csproj
index 01e5c1427..7162a07e9 100644
--- a/src/Microsoft.OpenApi.Hidi/Microsoft.OpenApi.Hidi.csproj
+++ b/src/Microsoft.OpenApi.Hidi/Microsoft.OpenApi.Hidi.csproj
@@ -9,7 +9,7 @@
enable
hidi
./../../artifacts
- 1.4.5
+ 1.4.6
OpenAPI.NET CLI tool for slicing OpenAPI documents
true
@@ -35,7 +35,7 @@
-
+
diff --git a/src/Microsoft.OpenApi.Readers/V2/OpenApiV2Deserializer.cs b/src/Microsoft.OpenApi.Readers/V2/OpenApiV2Deserializer.cs
index 8b10bb83f..790940759 100644
--- a/src/Microsoft.OpenApi.Readers/V2/OpenApiV2Deserializer.cs
+++ b/src/Microsoft.OpenApi.Readers/V2/OpenApiV2Deserializer.cs
@@ -1,4 +1,4 @@
-// Copyright (c) Microsoft Corporation. All rights reserved.
+// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
using System.Collections.Generic;
@@ -113,11 +113,11 @@ public static IOpenApiAny LoadAny(ParseNode node)
private static IOpenApiExtension LoadExtension(string name, ParseNode node)
{
- if (node.Context.ExtensionParsers.TryGetValue(name, out var parser))
+ if (node.Context.ExtensionParsers.TryGetValue(name, out var parser) && parser(
+ OpenApiAnyConverter.GetSpecificOpenApiAny(node.CreateAny()),
+ OpenApiSpecVersion.OpenApi2_0) is { } result)
{
- return parser(
- OpenApiAnyConverter.GetSpecificOpenApiAny(node.CreateAny()),
- OpenApiSpecVersion.OpenApi2_0);
+ return result;
}
else
{
diff --git a/src/Microsoft.OpenApi.Readers/V3/OpenApiV3Deserializer.cs b/src/Microsoft.OpenApi.Readers/V3/OpenApiV3Deserializer.cs
index 79b5f0671..558864854 100644
--- a/src/Microsoft.OpenApi.Readers/V3/OpenApiV3Deserializer.cs
+++ b/src/Microsoft.OpenApi.Readers/V3/OpenApiV3Deserializer.cs
@@ -171,11 +171,11 @@ public static IOpenApiAny LoadAny(ParseNode node)
private static IOpenApiExtension LoadExtension(string name, ParseNode node)
{
- if (node.Context.ExtensionParsers.TryGetValue(name, out var parser))
+ if (node.Context.ExtensionParsers.TryGetValue(name, out var parser) && parser(
+ OpenApiAnyConverter.GetSpecificOpenApiAny(node.CreateAny()),
+ OpenApiSpecVersion.OpenApi3_0) is { } result)
{
- return parser(
- OpenApiAnyConverter.GetSpecificOpenApiAny(node.CreateAny()),
- OpenApiSpecVersion.OpenApi3_0);
+ return result;
}
else
{
diff --git a/src/Microsoft.OpenApi/MicrosoftExtensions/OpenApiDeprecationExtension.cs b/src/Microsoft.OpenApi/MicrosoftExtensions/OpenApiDeprecationExtension.cs
index 25a3b56a5..683082e2c 100644
--- a/src/Microsoft.OpenApi/MicrosoftExtensions/OpenApiDeprecationExtension.cs
+++ b/src/Microsoft.OpenApi/MicrosoftExtensions/OpenApiDeprecationExtension.cs
@@ -78,7 +78,7 @@ public void Write(IOpenApiWriter writer, OpenApiSpecVersion specVersion)
/// When the source element is not an object
public static OpenApiDeprecationExtension Parse(IOpenApiAny source)
{
- if (source is not OpenApiObject rawObject) throw new ArgumentOutOfRangeException(nameof(source));
+ if (source is not OpenApiObject rawObject) return null;
var extension = new OpenApiDeprecationExtension();
if (rawObject.TryGetValue(nameof(RemovalDate).ToFirstCharacterLowerCase(), out var removalDate) && removalDate is OpenApiDateTime removalDateValue)
extension.RemovalDate = removalDateValue.Value;
diff --git a/src/Microsoft.OpenApi/MicrosoftExtensions/OpenApiEnumFlagsExtension.cs b/src/Microsoft.OpenApi/MicrosoftExtensions/OpenApiEnumFlagsExtension.cs
index e7dcf88f8..946537478 100644
--- a/src/Microsoft.OpenApi/MicrosoftExtensions/OpenApiEnumFlagsExtension.cs
+++ b/src/Microsoft.OpenApi/MicrosoftExtensions/OpenApiEnumFlagsExtension.cs
@@ -45,7 +45,7 @@ public void Write(IOpenApiWriter writer, OpenApiSpecVersion specVersion)
/// When the source element is not an object
public static OpenApiEnumFlagsExtension Parse(IOpenApiAny source)
{
- if (source is not OpenApiObject rawObject) throw new ArgumentOutOfRangeException(nameof(source));
+ if (source is not OpenApiObject rawObject) return null;
var extension = new OpenApiEnumFlagsExtension();
if (rawObject.TryGetValue(nameof(IsFlags).ToFirstCharacterLowerCase(), out var flagsValue) && flagsValue is OpenApiBoolean isFlags)
{
diff --git a/src/Microsoft.OpenApi/MicrosoftExtensions/OpenApiEnumValuesDescriptionExtension.cs b/src/Microsoft.OpenApi/MicrosoftExtensions/OpenApiEnumValuesDescriptionExtension.cs
index 5c7c1ba31..272f4b313 100644
--- a/src/Microsoft.OpenApi/MicrosoftExtensions/OpenApiEnumValuesDescriptionExtension.cs
+++ b/src/Microsoft.OpenApi/MicrosoftExtensions/OpenApiEnumValuesDescriptionExtension.cs
@@ -64,7 +64,7 @@ public void Write(IOpenApiWriter writer, OpenApiSpecVersion specVersion)
/// When the source element is not an object
public static OpenApiEnumValuesDescriptionExtension Parse(IOpenApiAny source)
{
- if (source is not OpenApiObject rawObject) throw new ArgumentOutOfRangeException(nameof(source));
+ if (source is not OpenApiObject rawObject) return null;
var extension = new OpenApiEnumValuesDescriptionExtension();
if (rawObject.TryGetValue("values", out var values) && values is OpenApiArray valuesArray)
{
diff --git a/src/Microsoft.OpenApi/MicrosoftExtensions/OpenApiPagingExtension.cs b/src/Microsoft.OpenApi/MicrosoftExtensions/OpenApiPagingExtension.cs
index a73ecf005..9b81e2561 100644
--- a/src/Microsoft.OpenApi/MicrosoftExtensions/OpenApiPagingExtension.cs
+++ b/src/Microsoft.OpenApi/MicrosoftExtensions/OpenApiPagingExtension.cs
@@ -73,7 +73,7 @@ public void Write(IOpenApiWriter writer, OpenApiSpecVersion specVersion)
/// When the source element is not an object
public static OpenApiPagingExtension Parse(IOpenApiAny source)
{
- if (source is not OpenApiObject rawObject) throw new ArgumentOutOfRangeException(nameof(source));
+ if (source is not OpenApiObject rawObject) return null;
var extension = new OpenApiPagingExtension();
if (rawObject.TryGetValue(nameof(NextLinkName).ToFirstCharacterLowerCase(), out var nextLinkName) && nextLinkName is OpenApiString nextLinkNameStr)
{
diff --git a/src/Microsoft.OpenApi/MicrosoftExtensions/OpenApiPrimaryErrorMessageExtension.cs b/src/Microsoft.OpenApi/MicrosoftExtensions/OpenApiPrimaryErrorMessageExtension.cs
index fde7a54ea..0250af758 100644
--- a/src/Microsoft.OpenApi/MicrosoftExtensions/OpenApiPrimaryErrorMessageExtension.cs
+++ b/src/Microsoft.OpenApi/MicrosoftExtensions/OpenApiPrimaryErrorMessageExtension.cs
@@ -1,4 +1,4 @@
-// ------------------------------------------------------------
+// ------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
// ------------------------------------------------------------
@@ -39,7 +39,7 @@ public void Write(IOpenApiWriter writer, OpenApiSpecVersion specVersion)
/// The .
public static OpenApiPrimaryErrorMessageExtension Parse(IOpenApiAny source)
{
- if (source is not OpenApiBoolean rawObject) throw new ArgumentOutOfRangeException(nameof(source));
+ if (source is not OpenApiBoolean rawObject) return null;
return new()
{
IsPrimaryErrorMessage = rawObject.Value
diff --git a/src/Microsoft.OpenApi/MicrosoftExtensions/OpenApiReservedParameterExtension.cs b/src/Microsoft.OpenApi/MicrosoftExtensions/OpenApiReservedParameterExtension.cs
index 77428e186..e45d9e7e9 100644
--- a/src/Microsoft.OpenApi/MicrosoftExtensions/OpenApiReservedParameterExtension.cs
+++ b/src/Microsoft.OpenApi/MicrosoftExtensions/OpenApiReservedParameterExtension.cs
@@ -41,7 +41,7 @@ public bool? IsReserved
///
public static OpenApiReservedParameterExtension Parse(IOpenApiAny source)
{
- if (source is not OpenApiBoolean rawBoolean) throw new ArgumentOutOfRangeException(nameof(source));
+ if (source is not OpenApiBoolean rawBoolean) return null;
return new()
{
IsReserved = rawBoolean.Value
diff --git a/src/Microsoft.OpenApi/Properties/SRResource.Designer.cs b/src/Microsoft.OpenApi/Properties/SRResource.Designer.cs
index abf945258..1a9ab3014 100644
--- a/src/Microsoft.OpenApi/Properties/SRResource.Designer.cs
+++ b/src/Microsoft.OpenApi/Properties/SRResource.Designer.cs
@@ -124,7 +124,7 @@ internal static string InvalidReferenceId {
}
///
- /// Looks up a localized string similar to Invalid Reference Type..
+ /// Looks up a localized string similar to Invalid Reference Type '{0}'..
///
internal static string InvalidReferenceType {
get {
@@ -340,7 +340,7 @@ internal static string Validation_PathItemMustBeginWithSlash {
}
///
- /// Looks up a localized string similar to The path signature '{0}' MUST begin be unique..
+ /// Looks up a localized string similar to The path signature '{0}' MUST be unique..
///
internal static string Validation_PathSignatureMustBeUnique {
get {
diff --git a/src/Microsoft.OpenApi/Properties/SRResource.resx b/src/Microsoft.OpenApi/Properties/SRResource.resx
index 38c4763d4..f0bb497d3 100644
--- a/src/Microsoft.OpenApi/Properties/SRResource.resx
+++ b/src/Microsoft.OpenApi/Properties/SRResource.resx
@@ -139,7 +139,7 @@
Invalid Reference identifier '{0}'.
- Invalid Reference Type.
+ Invalid Reference Type '{0}'.
Local reference must have type specified.
diff --git a/src/Microsoft.OpenApi/Services/OpenApiReferenceResolver.cs b/src/Microsoft.OpenApi/Services/OpenApiReferenceResolver.cs
index dd98b4317..00c069f30 100644
--- a/src/Microsoft.OpenApi/Services/OpenApiReferenceResolver.cs
+++ b/src/Microsoft.OpenApi/Services/OpenApiReferenceResolver.cs
@@ -259,6 +259,13 @@ private void ResolveTags(IList tags)
{
try
{
+ var referencedObject = typeof(T).Name;
+ var referenceType = reference?.Type.ToString();
+ if (referenceType is not null && !referencedObject.Contains(referenceType))
+ {
+ throw new OpenApiException(string.Format(Properties.SRResource.InvalidReferenceType, referenceType));
+ }
+
return _currentDocument.ResolveReference(reference, false) as T;
}
catch (OpenApiException ex)
diff --git a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiDocumentTests.cs b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiDocumentTests.cs
index a9401897b..d67c0054f 100644
--- a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiDocumentTests.cs
+++ b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/OpenApiDocumentTests.cs
@@ -9,8 +9,10 @@
using System.Threading;
using FluentAssertions;
using Microsoft.OpenApi.Any;
+using Microsoft.OpenApi.Exceptions;
using Microsoft.OpenApi.Interfaces;
using Microsoft.OpenApi.Models;
+using Microsoft.OpenApi.Readers.Interface;
using Microsoft.OpenApi.Validations;
using Microsoft.OpenApi.Validations.Rules;
using Microsoft.OpenApi.Writers;
@@ -1355,5 +1357,15 @@ public void ValidateExampleShouldNotHaveDataTypeMismatch()
var warnings = diagnostic.Warnings;
Assert.False(warnings.Any());
}
+
+ [Fact]
+ public void ParseDocumetWithWrongReferenceTypeShouldReturnADiagnosticError()
+ {
+ using var stream = Resources.GetStream(Path.Combine(SampleFolderPath, "docWithWrongRef.json"));
+ _ = new OpenApiStreamReader().Read(stream, out var diagnostic);
+
+ diagnostic.Errors.Should().BeEquivalentTo(new List {
+ new( new OpenApiException("Invalid Reference Type 'Schema'.")) });
+ }
}
}
diff --git a/test/Microsoft.OpenApi.Readers.Tests/V3Tests/Samples/OpenApiDocument/docWithWrongRef.json b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/Samples/OpenApiDocument/docWithWrongRef.json
new file mode 100644
index 000000000..6edf46be8
--- /dev/null
+++ b/test/Microsoft.OpenApi.Readers.Tests/V3Tests/Samples/OpenApiDocument/docWithWrongRef.json
@@ -0,0 +1,27 @@
+{
+ "openapi":"3.0.0",
+ "info":{
+ "title":"some api",
+ "description":"some description",
+ "version": "1"
+ },
+ "servers":[{"url":"https://localhost"}],
+ "paths":{
+ "/count":{
+ "get":{
+ "responses":{
+ "200":{
+ "$ref":"#/components/schemas/count"
+ },
+ },
+ }
+ }
+ },
+ "components":{
+ "schemas":{
+ "count":{
+ "type": "number"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/Microsoft.OpenApi.Tests/Microsoft.OpenApi.Tests.csproj b/test/Microsoft.OpenApi.Tests/Microsoft.OpenApi.Tests.csproj
index a516ec7e5..351a72df4 100644
--- a/test/Microsoft.OpenApi.Tests/Microsoft.OpenApi.Tests.csproj
+++ b/test/Microsoft.OpenApi.Tests/Microsoft.OpenApi.Tests.csproj
@@ -15,7 +15,7 @@
-
+
diff --git a/test/Microsoft.OpenApi.Tests/MicrosoftExtensions/OpenApiReservedParameterExtensionTests.cs b/test/Microsoft.OpenApi.Tests/MicrosoftExtensions/OpenApiReservedParameterExtensionTests.cs
index ca7870bc0..0ebeea11a 100644
--- a/test/Microsoft.OpenApi.Tests/MicrosoftExtensions/OpenApiReservedParameterExtensionTests.cs
+++ b/test/Microsoft.OpenApi.Tests/MicrosoftExtensions/OpenApiReservedParameterExtensionTests.cs
@@ -17,6 +17,19 @@ public void Parses()
Assert.NotNull(value);
Assert.True(value.IsReserved);
}
+
+ [Fact]
+ public void DoesNotThrowExceptionIfValueIsNull()
+ {
+ var oaiValue = new OpenApiObject
+ {
+ ["foo"] = new OpenApiString("foo")
+ };
+
+ var value = OpenApiReservedParameterExtension.Parse(oaiValue);
+ Assert.Null(value);
+ }
+
[Fact]
public void Serializes()
{