Skip to content

Sanitize while parsing - #12756

Open
noamr wants to merge 15 commits into
noamr/positional-htmlfrom
noamr/streaming-sanitizer
Open

Sanitize while parsing#12756
noamr wants to merge 15 commits into
noamr/positional-htmlfrom
noamr/streaming-sanitizer

Conversation

@noamr

@noamr noamr commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Instead of parsing into a fragment and then statically sanitizing that fragment, sanitize as we parse.
This entails the following changes:

  • The sanitizer config is propagated to the parser and kept as a new parser flag ("parser sanitizer configuration").
  • The "safe" flavor of sanitization is kept as a boolean flag in the parser ("remove javascript navigation URLs"), as that is a special safety check not kept in the sanitizer configuration.
  • The fragment created to hold the result is created in the inert document when sanitizing to avoid creation-time side effects (see Nodes are made non-inert before sanitizing #12560).
  • Instead of a recursive "sanitize" algorithm operating on a node tree, we define a "sanitize" algorithm that operates on a single Element, along with two helper checks: "sanitizer config allows comments" and "sanitizer config allows processing instruction target" (other node types do not need to check the sanitizer).
  • For "replace with children", we replaced the parser's "root insertion target" flag with an "insertion target redirection map" (mapping a node to an insertion location). This map is used to redirect insertions from the root dummy element to the target DocumentFragment, and also to redirect elements to their nearest non-replaced ancestor when a child is stripped but its children are kept.

Note that this still leaves out important follow ups, where we need to sometimes sanitize before the element is even created (e.g. declarative shadow roots and is), and having a live sanitizer config while parsing gives us the infrastructure for that.

Closes #12560
Closes #12543

(See WHATWG Working Mode: Changes for more details.)


💥 Error: Wattsi server error 💥

PR Preview failed to build. (Last tried on Aug 28, 2026, 2:28 PM UTC).

More

PR Preview relies on a number of web services to run. There seems to be an issue with the following one:

🚨 Wattsi Server - Wattsi Server is the web service used to build the WHATWG HTML spec.

🔗 Related URL

Error output:

      <!DOCTYPE html>
      <html>
      <head>
          <meta name="viewport" content="width=device-width, initial-scale=1">
          <meta name="robots" content="noindex">
          <style>body,html{height:100%;margin:0}body{display:flex;align-items:center;justify-content:center;flex-direction:column;-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility}p{text-align:center;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif;color:#000;font-size:14px;margin-top:-50px}p.code{font-size:24px;font-weight:500;border-bottom:1px solid #e0e1e2;padding:0 20px 15px}p.text{margin:0}a,a:visited{color:#aaa}</style>
      </head>
      <body>
      <p class="code">
        Error code: 503      </p>
      <p class="text">
        Well, This is unexpected. An Error has occurred, and we are working to fix the problem! We will be up and running shortly. Try refreshing the page or try again in a few minutes.
      </p>
        <div style="display:none;">
          <h1>
    upstream_reset_before_response_started{connection_termination} (503 UC)      </h1>
          <p data-translate="connection_timed_out">App Platform failed to forward this request to the application.</p>
      </div>
      </body>
      </html>
    

This seems to be an issue with the Wattsi Server service. PR Preview doesn't manage this service and so has no control over it. If you've identified an issue with it, you can report the issue to the maintainers of Wattsi Server directly. Please be courteous. Thank you!

If you don't have enough information above to solve the error by yourself or if the issue doesn't seem related to Wattsi Server, you can file an issue with PR Preview.

@noamr noamr closed this Aug 4, 2026
@noamr noamr reopened this Aug 4, 2026
@noamr noamr mentioned this pull request Aug 4, 2026
5 tasks
@noamr
noamr force-pushed the noamr/streaming-sanitizer branch from 7b105e3 to e24c23b Compare August 5, 2026 09:31
@noamr
noamr force-pushed the noamr/streaming-sanitizer branch 3 times, most recently from 4ff3705 to 8551681 Compare August 7, 2026 20:17

@zcorpan zcorpan left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing null check; nits.

Comment thread source Outdated
Comment thread source Outdated
Comment thread source Outdated
Comment thread source Outdated
Comment thread source Outdated
Comment thread source Outdated
Comment thread source Outdated
Comment thread source
Comment thread source Outdated
Comment thread source Outdated
Comment thread source Outdated
Comment thread source Outdated
@noamr
noamr force-pushed the noamr/streaming-sanitizer branch 2 times, most recently from 1d9e935 to 4453c2a Compare August 12, 2026 16:07
@noamr noamr closed this Aug 13, 2026
@noamr noamr reopened this Aug 13, 2026
Comment thread source Outdated
@noamr
noamr force-pushed the noamr/streaming-sanitizer branch from 4453c2a to 931141c Compare August 14, 2026 08:52
@noamr
noamr requested a review from zcorpan August 14, 2026 08:57
Comment thread source Outdated
Comment thread source
@noamr
noamr force-pushed the noamr/streaming-sanitizer branch from 32e5b9a to 1b77b8d Compare August 15, 2026 10:04
brave-builds pushed a commit to brave/chromium that referenced this pull request Aug 17, 2026
Sanitization should take place while performing the adoption agency
algorithm, otherwise some nodes can be missed.

Since adoption agency often adds an intermediate element,
the ReplaceWithChildren directive essentially negates it,
while Remove reparents the children into the intermediate
element and removes all of them.

This is in line with spec changes made as part of
whatwg/html#12756

Bug: 498272014
Change-Id: Ieb755555635e197f8ed7daf06a08679a0f2d38c3
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/8250959
Commit-Queue: Noam Rosenthal <nrosenthal@google.com>
Reviewed-by: Daniel Vogelheim <vogelheim@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1680770}
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this pull request Aug 17, 2026
Sanitization should take place while performing the adoption agency
algorithm, otherwise some nodes can be missed.

Since adoption agency often adds an intermediate element,
the ReplaceWithChildren directive essentially negates it,
while Remove reparents the children into the intermediate
element and removes all of them.

This is in line with spec changes made as part of
whatwg/html#12756

Bug: 498272014
Change-Id: Ieb755555635e197f8ed7daf06a08679a0f2d38c3
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/8250959
Commit-Queue: Noam Rosenthal <nrosenthal@google.com>
Reviewed-by: Daniel Vogelheim <vogelheim@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1680770}
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this pull request Aug 17, 2026
Sanitization should take place while performing the adoption agency
algorithm, otherwise some nodes can be missed.

Since adoption agency often adds an intermediate element,
the ReplaceWithChildren directive essentially negates it,
while Remove reparents the children into the intermediate
element and removes all of them.

This is in line with spec changes made as part of
whatwg/html#12756

Bug: 498272014
Change-Id: Ieb755555635e197f8ed7daf06a08679a0f2d38c3
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/8250959
Commit-Queue: Noam Rosenthal <nrosenthal@google.com>
Reviewed-by: Daniel Vogelheim <vogelheim@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1680770}
@noamr
noamr force-pushed the noamr/streaming-sanitizer branch from 1b77b8d to 2eb51b7 Compare August 19, 2026 16:22
@noamr
noamr force-pushed the noamr/streaming-sanitizer branch from be95755 to 50182d4 Compare September 2, 2026 10:26
Comment thread source Outdated
@noamr
noamr force-pushed the noamr/streaming-sanitizer branch from 50182d4 to fd9f9dc Compare September 2, 2026 14:58
Comment thread source Outdated
Comment thread source Outdated
Comment thread source Outdated
Comment thread source Outdated
Comment thread source Outdated
Comment thread source
Comment thread source Outdated
@noamr
noamr force-pushed the noamr/streaming-sanitizer branch from b202606 to 16572fe Compare September 3, 2026 08:18
Comment thread source Outdated
Comment thread source Outdated
@noamr
noamr force-pushed the noamr/streaming-sanitizer branch from 0c49f36 to ca03f6d Compare September 3, 2026 20:52
@noamr
noamr force-pushed the noamr/streaming-sanitizer branch from ca03f6d to 745e3da Compare September 4, 2026 16:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

Nodes are made non-inert before sanitizing Streaming sanitizer support

4 participants