From d9b0837975cecb7e3a7d2635f152c952b5791f17 Mon Sep 17 00:00:00 2001
From: snowingfox <1503401882@qq.com>
Date: Tue, 11 Aug 2026 23:20:18 +0000
Subject: [PATCH] fix: escape processing-instruction content under fallback
raw-content elements
Fixes #70146
---
lib/NodeUtils.js | 8 +++++++-
test/domino.js | 42 ++++++++++++++++++++++++++++++++++++++++++
2 files changed, 49 insertions(+), 1 deletion(-)
diff --git a/lib/NodeUtils.js b/lib/NodeUtils.js
index a0a4962..7900a99 100644
--- a/lib/NodeUtils.js
+++ b/lib/NodeUtils.js
@@ -309,7 +309,13 @@ function serializeOne(kid, parent) {
s += '';
break;
case 7: //PROCESSING_INSTRUCTION_NODE
- const content = escapeProcessingInstructionContent(kid.data);
+ let content = escapeProcessingInstructionContent(kid.data);
+ if (content.includes('')) {
+ const fallbackTags = fallbackRawContentTags(parent);
+ for (const fallbackTag of fallbackTags) {
+ content = escapeMatchingClosingTag(content, fallbackTag);
+ }
+ }
s += '' + kid.target + ' ' + content + '?>';
break;
case 10: //DOCUMENT_TYPE_NODE
diff --git a/test/domino.js b/test/domino.js
index 916e09d..8122768 100644
--- a/test/domino.js
+++ b/test/domino.js
@@ -1556,3 +1556,45 @@ exports.worksWithBase64DataImages = function () {
'iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII);">'
);
};
+
+exports.processingInstructionClosingTagEscapedInNoscript = function () {
+ // A processing-instruction payload that begins with a fallback raw-content
+ // closing tag (e.g. `
+ // element early in the receiving browser (RAWTEXT) and the sibling
+ // is re-parsed as live HTML.
+ // Regression for angular/angular#70146: the fc7e40a (#70050) and e0779df
+ // (#70055) fixes escaped element/text/comment branches of serializeOne()
+ // but the PROCESSING_INSTRUCTION_NODE branch (case 7) never called
+ // fallbackRawContentTags(), and escapeProcessingInstructionContent()
+ // only escapes `>` (leaving `<` alone).
+ const document = domino.createDocument('