Skip to content

Add opt-in DTD ignoring - #11

Merged
xoofx merged 1 commit into
xoofx:mainfrom
mamoreau-devolutions:add-dtd-ignore-option
Jul 13, 2026
Merged

xoofx merged 1 commit into
xoofx:mainfrom
mamoreau-devolutions:add-dtd-ignore-option

Conversation

@mamoreau-devolutions

@mamoreau-devolutions mamoreau-devolutions commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Summary

TurboXml currently rejects every <!DOCTYPE ...> declaration. Some consumers intentionally use the XmlReaderSettings.DtdProcessing = Ignore model instead: accept a legal document containing a DOCTYPE, but do not load, interpret, or expand its DTD.

This PR adds that narrow, opt-in behavior without adding general DTD support.

API

var options = new XmlParserOptions
{
    IgnoreDtd = true,
};

IgnoreDtd defaults to false, so the current secure behavior—rejecting DOCTYPE declarations—remains unchanged. Matching string XmlParser.Parse overloads accepting XmlParserOptions are also added, bringing them in line with the stream overloads.

Behavior when enabled

The parser recognizes and skips the lexical form of legal document type declarations, including:

  • a simple <!DOCTYPE root> declaration;
  • SYSTEM external identifiers;
  • PUBLIC identifiers;
  • quoted literals; and
  • internal subsets containing markup declarations, comments, and processing instructions.

It deliberately does not:

  • retrieve external DTDs or other resources;
  • process or validate DTD declarations;
  • make declared entities available; or
  • expand custom entities.

Consequently, &custom; remains an error even if it was declared inside the skipped internal subset. This preserves the parser's existing entity model and prevents the option from becoming a DTD-processing or resource-resolution feature.

Malformed DOCTYPE syntax is still rejected. This is a safe acceptance mode for callers that explicitly need DtdProcessing.Ignore-style compatibility, not general DTD support.

Tests

Added regression coverage for:

  • default DOCTYPE rejection;
  • opt-in parsing through both string and stream paths;
  • simple, SYSTEM, PUBLIC, and internal-subset declarations;
  • malformed declaration rejection; and
  • proof that an ignored internal subset does not declare or expand custom entities.

Validation

cd src
dotnet build -c Release
dotnet test -c Release

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@xoofx
xoofx force-pushed the add-dtd-ignore-option branch from 8040557 to 2d1a32c Compare July 13, 2026 13:36
@xoofx
xoofx merged commit 62faacc into xoofx:main Jul 13, 2026
1 check passed
@xoofx

xoofx commented Jul 13, 2026

Copy link
Copy Markdown
Owner

Thanks!

@mamoreau-devolutions

Copy link
Copy Markdown
Contributor Author

wow, thanks for being this quick, and even creating a new release! this will make our switch from XmlReader to TurboXml much simpler

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.

2 participants