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('