Skip to content

Reject processing instructions with reserved xml target - #1037

Closed
johnozler-hunt wants to merge 1 commit into
tafia:masterfrom
johnozler-hunt:reject-reserved-pi-target
Closed

johnozler-hunt wants to merge 1 commit into
tafia:masterfrom
johnozler-hunt:reject-reserved-pi-target

Conversation

@johnozler-hunt

Copy link
Copy Markdown
Contributor

When the reader splits <? ... ?>, emit_question_mark decides between a declaration and a processing instruction by testing the target with a case-sensitive starts_with(b"xml"). Only the exact lowercase form becomes a Decl; every other spelling of the target falls through to the PI branch, so <?XML?>, <?XmL?> and <?xMl?> were emitted as ordinary PI events. The PITarget production reserves xml in any combination of upper and lower case (it is kept for the declaration), so these are not well-formed: libxml2 and expat reject them as an invalid token, while quick-xml accepted them. That disagreement is the kind of parser differential that lets a crafted <?XML ...?> slip past a quick-xml based tool and be read as a declaration by the next parser in a pipeline. I hit it while probing PI handling against expat. The fix returns a new IllFormedError::ReservedPiTarget when the target equals xml ignoring ASCII case; the lowercase <?xml?> declaration and targets like xmlx are unchanged.

emit_question_mark routed a processing instruction to a Decl event only
when its target was the exact lowercase `xml`, and emitted every other
spelling (`<?XML?>`, `<?XmL?>`, `<?xMl?>`) as a PI event. The PITarget
production reserves `xml` in any combination of case, so conforming
parsers reject those while quick-xml accepted them.

Return the new IllFormedError::ReservedPiTarget when a PI target equals
`xml` ignoring ASCII case. The lowercase declaration is unaffected.
@codecov-commenter

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

❌ Patch coverage is 80.00000% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 53.82%. Comparing base (4a56631) to head (6cf3cd2).
⚠️ Report is 23 commits behind head on master.

Files with missing lines Patch % Lines
src/errors.rs 0.00% 2 Missing ⚠️
❗ Your organization needs to install the Codecov GitHub app to enable full functionality.
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1037      +/-   ##
==========================================
+ Coverage   53.71%   53.82%   +0.10%     
==========================================
  Files          51       51              
  Lines       19412    19522     +110     
==========================================
+ Hits        10428    10508      +80     
- Misses       8984     9014      +30     
Flag Coverage Δ
unittests 53.82% <80.00%> (+0.10%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@Mingun

Mingun commented Nov 7, 2026

Copy link
Copy Markdown
Collaborator

Unfortunately not, some quick-xml consumers rely on the fact that they will have access to the XML processing instruction, in particular, Ruffle, see #927. They emulate Flash bugs and Flash parser accepts any case as declaration.

We do not want to restrict PI on core parser level. That should be done in the explicit validation pass. I have some thoughts in my validation branch, how that could look.

@Mingun Mingun closed this Nov 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants