Skip to content

Commit ec6a38e

Browse files
authored
Fix for invalid state in JsonBlockValueConverter when an unused layout has a nested array (#19363)
* Fix for invalid state in JsonBlockValueConverter when an unused layout has a nested array * Improved comments as suggested by copilot review, also fixed code style miss * Added check for malformed JSON with more closing array tokens then opening tokens
1 parent ea8ec4e commit ec6a38e

File tree

2 files changed

+58
-2
lines changed

2 files changed

+58
-2
lines changed

src/Umbraco.Infrastructure/Serialization/JsonBlockValueConverter.cs

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -189,9 +189,36 @@ private void DeserializeAndSetLayout(ref Utf8JsonReader reader, JsonSerializerOp
189189
else
190190
{
191191
// ignore this layout - forward the reader to the end of the array and look for the next one
192-
while (reader.TokenType is not JsonTokenType.EndArray)
192+
193+
// Read past the current StartArray token before we start counting
194+
_ = reader.Read();
195+
196+
// Keep track of the number of open arrays to ensure we find the correct EndArray token
197+
var openCount = 0;
198+
while (true)
193199
{
194-
reader.Read();
200+
if (reader.TokenType is JsonTokenType.EndArray && openCount == 0)
201+
{
202+
break;
203+
}
204+
205+
if (reader.TokenType is JsonTokenType.StartArray)
206+
{
207+
openCount++;
208+
}
209+
else if (reader.TokenType is JsonTokenType.EndArray)
210+
{
211+
openCount--;
212+
if (openCount < 0)
213+
{
214+
throw new JsonException($"Malformed JSON: Encountered more closing array tokens than opening ones while processing block editor alias: {blockEditorAlias}.");
215+
}
216+
}
217+
218+
if (!reader.Read())
219+
{
220+
throw new JsonException($"Unexpected end of JSON while looking for the end of the layout items array for block editor alias: {blockEditorAlias}.");
221+
}
195222
}
196223
}
197224
}

tests/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Serialization/JsonBlockValueConverterTests.cs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -441,4 +441,33 @@ public void Ignores_Other_Layouts()
441441
Assert.AreEqual(settingsElementKey1, layoutItems.First().SettingsKey);
442442
});
443443
}
444+
445+
[Test]
446+
public void Try_Deserialize_Unknown_Block_Layout_With_Nested_Array()
447+
{
448+
var json = """
449+
{
450+
"layout": {
451+
"Umbraco.BlockGrid": [{
452+
"contentUdi": "umb://element/1304E1DDAC87439684FE8A399231CB3D",
453+
"rowSpan": 1,
454+
"areas": [],
455+
"columnSpan": 12
456+
}
457+
],
458+
"Umbraco.BlockList": [{
459+
"contentUdi": "umb://element/1304E1DDAC87439684FE8A399231CB3D"
460+
}
461+
],
462+
"Some.Custom.BlockEditor": [{
463+
"contentUdi": "umb://element/1304E1DDAC87439684FE8A399231CB3D"
464+
}
465+
]
466+
}
467+
}
468+
""";
469+
470+
var serializer = new SystemTextJsonSerializer();
471+
Assert.DoesNotThrow(() => serializer.Deserialize<BlockListValue>(json));
472+
}
444473
}

0 commit comments

Comments
 (0)