fix: stack overflow in comparer

Signed-off-by: Vincent Biret <vibiret@microsoft.com>
This commit is contained in:
Vincent Biret 2024-09-09 15:05:27 -04:00
Родитель 915c31f8b4
Коммит c7f84acac4
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 619343BAE7D07BBC
3 изменённых файлов: 20 добавлений и 20 удалений

Просмотреть файл

@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed
- Fixed a stack overflow in the core generator caused by circular comparisons. [#5369](https://github.com/microsoft/kiota/issues/5369)
- Fixed a bug where collection/array of primitive types members for union/intersection types would be ignored. [#5283](https://github.com/microsoft/kiota/issues/5283)
- Fixed a when generating a plugin when only an operation is selected in the root node in the extension. [#5300](https://github.com/microsoft/kiota/issues/5300)

Просмотреть файл

@ -27,7 +27,7 @@ internal class OpenApiSchemaComparer : IEqualityComparer<OpenApiSchema>
/// <inheritdoc/>
public bool Equals(OpenApiSchema? x, OpenApiSchema? y)
{
return EqualsInternal(x, y);
return x == null && y == null || x != null && y != null && GetHashCode(x) == GetHashCode(y);
}
/// <inheritdoc/>
public int GetHashCode([DisallowNull] OpenApiSchema obj)
@ -37,25 +37,6 @@ internal class OpenApiSchemaComparer : IEqualityComparer<OpenApiSchema>
return hash.ToHashCode();
}
private bool EqualsInternal(OpenApiSchema? x, OpenApiSchema? y)
{
if (x is null || y is null) return object.Equals(x, y);
return x.Deprecated == y.Deprecated
&& x.Nullable == y.Nullable
&& x.AdditionalPropertiesAllowed == y.AdditionalPropertiesAllowed
&& discriminatorComparer.Equals(x.Discriminator, y.Discriminator)
&& string.Equals(x.Format, y.Format, StringComparison.OrdinalIgnoreCase)
&& string.Equals(x.Type, y.Type, StringComparison.OrdinalIgnoreCase)
&& string.Equals(x.Title, y.Title, StringComparison.Ordinal)
&& openApiAnyComparer.Equals(x.Default, y.Default)
&& EqualsInternal(x.AdditionalProperties, y.AdditionalProperties)
&& EqualsInternal(x.Items, y.Items)
&& Enumerable.SequenceEqual(x.Properties, y.Properties, schemaMapComparer)
&& Enumerable.SequenceEqual(x.AnyOf, y.AnyOf, this)
&& Enumerable.SequenceEqual(x.AllOf, y.AllOf, this)
&& Enumerable.SequenceEqual(x.OneOf, y.OneOf, this);
}
private void GetHashCodeInternal([DisallowNull] OpenApiSchema obj, HashSet<OpenApiSchema> visitedSchemas, ref HashCode hash)
{
if (obj is null) return;

Просмотреть файл

@ -1,5 +1,6 @@
using System;
using Kiota.Builder.Validation;
using Microsoft.OpenApi.Models;
using Xunit;
namespace Kiota.Builder.Tests.Validation;
@ -21,4 +22,21 @@ public class OpenApiSchemaComparerTests
{
Assert.True(_comparer.Equals(new(), new()));
}
[Fact]
public void DoesNotStackOverFlowOnCircularReferencesForEquals()
{
var schema = new OpenApiSchema
{
};
schema.Properties.Add("test", schema);
schema.AnyOf.Add(schema);
var schema2 = new OpenApiSchema
{
};
schema2.Properties.Add("test", schema2);
schema2.AnyOf.Add(schema2);
Assert.True(_comparer.Equals(schema, schema2));
}
}