@angular/platform-server 22.2.0-next.4 → 22.2.0-next.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -944,18 +944,41 @@ function requireNodeUtils () {
944
944
 
945
945
  const CLOSING_COMMENT_REGEXP = /--!?>/;
946
946
 
947
+ /**
948
+ * Escapes a comment content that abruptly closes the comment.
949
+ *
950
+ * A comment can not carry content that starts with `>` or `->`: the parser
951
+ * closes the comment as soon as it comes across such a sequence right after
952
+ * `<!--` (the "abrupt-closing-of-empty-comment" parse error). For example,
953
+ * `#comment('><img src=x onerror=alert(1)>')` would otherwise serialize into
954
+ * `<!--><img src=x onerror=alert(1)>-->`, which de-serializes into an empty
955
+ * comment followed by a live `<img>` element. Escaping the leading `>` keeps
956
+ * the content inside the comment, where it stays inert.
957
+ */
958
+ function escapeAbruptClosingCommentTag(rawContent) {
959
+ if (rawContent.startsWith('>')) {
960
+ return '&gt;' + rawContent.slice(1);
961
+ }
962
+ if (rawContent.startsWith('->')) {
963
+ return '-&gt;' + rawContent.slice(2);
964
+ }
965
+ return rawContent; // fast path
966
+ }
967
+
947
968
  /**
948
969
  * Escapes closing comment tag in a comment content.
949
970
  *
950
971
  * For example, given `#comment('-->')`, the content of a comment would be
951
972
  * updated to `--&gt;` to avoid unexpected and unsafe behavior after
952
- * de-serialization.
973
+ * de-serialization. Content that abruptly closes an empty comment is
974
+ * escaped as well, see `escapeAbruptClosingCommentTag()`.
953
975
  */
954
976
  function escapeClosingCommentTag(rawContent) {
955
- if (!CLOSING_COMMENT_REGEXP.test(rawContent)) {
956
- return rawContent; // fast path
977
+ const content = escapeAbruptClosingCommentTag(rawContent);
978
+ if (!CLOSING_COMMENT_REGEXP.test(content)) {
979
+ return content; // fast path
957
980
  }
958
- return rawContent.replace(/(--\!?)>/g, '$1&gt;');
981
+ return content.replace(/(--\!?)>/g, '$1&gt;');
959
982
  }
960
983
 
961
984
  /**