Repository navigation
.Net: Bound element nesting depth in XML prompt parsing - #14504
Roger Barreto (rogerbarreto) merged 2 commits into
Conversation
Each parsed prompt node keeps its serialized subtree, so parse work grew with nesting depth times prompt size. Reject prompts nested deeper than 64 elements before building nodes; they take the existing invalid-XML path and are sent as plain text.
There was a problem hiding this comment.
Copilot review overview
🟢 Approval recommended
The iterative limit is correctly enforced before recursive node construction and has appropriate boundary coverage.
Review effort: Balanced
Findings: None
What changed in this PR
Bounds XML prompt nesting depth to prevent excessive parsing work and recursion.
Changes:
- Adds a 64-element depth limit with iterative validation.
- Adds boundary, excessive-depth, and sibling traversal tests.
- Verifies over-depth chat prompts fail parsing.
| File | Description |
|---|---|
XmlPromptParser.cs |
Implements and documents depth validation. |
XmlPromptParserTests.cs |
Tests depth boundaries and sibling traversal. |
ChatPromptParserTests.cs |
Tests rejection through chat parsing. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
There was a problem hiding this comment.
MAF Automated Review — Iteration 1
Result: No findings
Scope: full PR (1 commit(s)): e306e970769a
Model: gpt-5.6-sol-fast
Overview
The PR adds a non-recursive, full-document element-depth check before recursive PromptNode construction and repeated subtree serialization. Boundary, sibling-traversal, deep-input, and chat-layer tests support the intended 64-element limit, while existing callers preserve rejected prompts through their plain-text fallback. No publishable Critical, High, or Medium defect was established.
Reviewed the supplied pull-request change set across correctness, security/reliability, architecture, and failure behavior.
No publishable findings remained after source verification for this scope.
Motivation and Context
XmlPromptParserconverts chat prompts such as<message role="user">...</message>intoPromptNodetrees thatChatPromptParserturns into aChatHistory. EachPromptNodestores the serialized inner XML of its element, so the parser re-serializes and decodes the whole remaining subtree at every nesting level. Parse work therefore grows with nesting depth multiplied by prompt size, and the recursive node builder had no depth bound.Supported chat prompt structure is shallow: message elements with optional
text,image,audio, andbinarychildren, plus encoded or CDATA text. This change bounds element nesting so parsing cost stays proportional to prompt size.Description
XmlPromptParser.MaxElementDepth(internal,64, top-level prompt elements count as depth 1, matching theSystem.Text.Jsondefault maximum depth).PromptNodeis built, a single non-recursive walk checks element depth. Prompts nested deeper than the limit returnfalsefromTryParse.GetChatMessageContentsAsync(string)send the whole prompt as one user text message, exactly as they already do for malformed XML.GetPromptNodeis bounded.Tests:
XmlPromptParserTests: parses two prompts at exactly the maximum depth; rejects one level over and far over the limit; rejects when only a later top-level node exceeds the limit (covers sibling traversal after a max-depth subtree).ChatPromptParserTests: a user message whose content exceeds the limit makesChatPromptParser.TryParsereturnfalse.Validation
All local runs use
-c Debugon .NET SDK 10.0.401.--warnaserror:SemanticKernel.Abstractions(net10.0,net8.0,netstandard2.0),SemanticKernel.UnitTests,Extensions.UnitTests,PromptTemplates.Liquid.UnitTests,Agents.UnitTests,IntegrationTests: 0 warnings, 0 errors.dotnet format --verify-no-changesinmcr.microsoft.com/dotnet/sdk:10.0for both changed projects: clean.SemanticKernel.UnitTests: 1614/1614 pass, including the 5 new tests. The new over-limit tests fail without the parser change.Extensions.UnitTests(Handlebars) 90/90,PromptTemplates.Liquid.UnitTests16/16,Agents.UnitTests504/504 executed tests pass,IntegrationTestsCrossLanguage (offline, stubbed HTTP request shape) 37/37.ChatHistoryonnet10.0,net8.0, and .NET Framework 4.8 (netstandard2.0asset), and the largest prompts still accepted parse in time proportional to their size.Contribution Checklist