Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

# 0.12.3 2025-10-13

- Fix crash in logging when property named "$ref"

## 0.12.2 2025-09-22

- bump dependency `js-yaml` from `^3.13.0` to `^4.1.0`
Expand Down
18 changes: 16 additions & 2 deletions openapi-diff/src/core/OpenApiDiff.Core/Logging/ObjectPath.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,23 @@ private static JToken FromObject(JObject o, string name)
{
return null;
}

var @ref = o["$ref"];
var unrefed = @ref != null ? ParseRef(@ref.Value<string>()).CompletePath(o.Root).Last().token : o;
return unrefed[name];

// Handle $ref resolution based on its type
if (@ref != null && @ref.Type == JTokenType.String)
{
// Case 1: $ref is a string reference (e.g., "#/definitions/FieldType")
// Resolve the reference by parsing the path and following it to the target
var unrefed = ParseRef(@ref.Value<string>()).CompletePath(o.Root).Last().token;
return unrefed[name];
}
else
{
// Case 2: $ref is not a string (e.g., a JSON object defining a schema)
// or $ref doesn't exist - use the current object directly
return o[name];
}
}

private static IEnumerable<(JToken token, string name)> CompletePath(IEnumerable<Func<JToken, string>> path, JToken token)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
{
"swagger": 2.0,
"info": {
"title": "type_changed",
"version": "1.0"
},
"host": "localhost:8000",
"schemes": [ "http", "https" ],
"consumes": [ "text/plain", "text/json" ],
"produces": [ "text/plain" ],
"paths": {
"/api/Parameters": {
"put": {
"tag": [ "Parameters" ],
"operationId": "Parameters_Put",
"produces": [
"text/plain"
],
"parameters": [
{
"name": "database",
"in": "body",
"required": true,
"type": "object",
"schema": { "$ref": "#/definitions/Database" }
}
]
}
}
},
"definitions": {
"Database": {
"properties": {
"$ref": {
"type": "integer",
"readOnly": true,
"description": "Property named '$ref'. Unusual but valid."
},
"b": {
"type": "integer",
"readOnly": true,
"default": 0,
"description": "This property shows the number of databases returned."
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
{
"swagger": 2.0,
"info": {
"title": "type_changed",
"version": "1.0"
},
"host": "localhost:8000",
"schemes": [ "http", "https" ],
"consumes": [ "text/plain", "text/json" ],
"produces": [ "text/plain" ],
"paths": {
"/api/Parameters": {
"put": {
"tag": [ "Parameters" ],
"operationId": "Parameters_Put",
"produces": [
"text/plain"
],
"parameters": [
{
"name": "database",
"in": "body",
"required": true,
"type": "object",
"schema": { "$ref": "#/definitions/Database" }
}
]
}
}
},
"definitions": {
"Database": {
"properties": {
"$ref": {
"type": "string",
"readOnly": true,
"description": "Property named '$ref'. Unusual but valid."
},
"b": {
"type": "integer",
"readOnly": true,
"default": 0,
"description": "This property shows the number of databases returned."
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,21 @@ public void TypeObjectChanged()
Assert.Equal("new/type_changed_01.json#/definitions/Database/properties/a", error.NewJsonRef);
}

/// <summary>
/// Verifies that if you change the type of a schema property named "$ref" (unusual but valid), it's caught.
/// </summary>
[Fact]
public void PropertyNamedRefTypeChanged()
{
var messages = CompareSwagger("type_changed_02.json").ToArray();
var missing = messages.Where(m => m.Id == ComparisonMessages.TypeChanged.Id);
Assert.NotEmpty(missing);
var error = missing.Where(err => err.NewJsonRef.StartsWith("new/type_changed_02.json#/definitions/")).FirstOrDefault();
Assert.NotNull(error);
Assert.Equal(Category.Error, error.Severity);
Assert.Equal("new/type_changed_02.json#/definitions/Database/properties/$ref", error.NewJsonRef);
}

/// <summary>
/// Verifies that if you change the default value of a schema, it's caught.
/// </summary>
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@azure/oad",
"version": "0.12.2",
"version": "0.12.3",
"author": {
"name": "Microsoft Corporation",
"email": "azsdkteam@microsoft.com",
Expand Down
Loading