@angular/platform-server 20.3.30 → 20.3.31

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.
package/fesm2022/init.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Angular v20.3.30
2
+ * @license Angular v20.3.31
3
3
  * (c) 2010-2025 Google LLC. https://angular.dev/
4
4
  * License: MIT
5
5
  */
@@ -950,18 +950,41 @@ function requireNodeUtils () {
950
950
 
951
951
  const CLOSING_COMMENT_REGEXP = /--!?>/;
952
952
 
953
+ /**
954
+ * Escapes a comment content that abruptly closes the comment.
955
+ *
956
+ * A comment can not carry content that starts with `>` or `->`: the parser
957
+ * closes the comment as soon as it comes across such a sequence right after
958
+ * `<!--` (the "abrupt-closing-of-empty-comment" parse error). For example,
959
+ * `#comment('><img src=x onerror=alert(1)>')` would otherwise serialize into
960
+ * `<!--><img src=x onerror=alert(1)>-->`, which de-serializes into an empty
961
+ * comment followed by a live `<img>` element. Escaping the leading `>` keeps
962
+ * the content inside the comment, where it stays inert.
963
+ */
964
+ function escapeAbruptClosingCommentTag(rawContent) {
965
+ if (rawContent.startsWith('>')) {
966
+ return '&gt;' + rawContent.slice(1);
967
+ }
968
+ if (rawContent.startsWith('->')) {
969
+ return '-&gt;' + rawContent.slice(2);
970
+ }
971
+ return rawContent; // fast path
972
+ }
973
+
953
974
  /**
954
975
  * Escapes closing comment tag in a comment content.
955
976
  *
956
977
  * For example, given `#comment('-->')`, the content of a comment would be
957
978
  * updated to `--&gt;` to avoid unexpected and unsafe behavior after
958
- * de-serialization.
979
+ * de-serialization. Content that abruptly closes an empty comment is
980
+ * escaped as well, see `escapeAbruptClosingCommentTag()`.
959
981
  */
960
982
  function escapeClosingCommentTag(rawContent) {
961
- if (!CLOSING_COMMENT_REGEXP.test(rawContent)) {
962
- return rawContent; // fast path
983
+ const content = escapeAbruptClosingCommentTag(rawContent);
984
+ if (!CLOSING_COMMENT_REGEXP.test(content)) {
985
+ return content; // fast path
963
986
  }
964
- return rawContent.replace(/(--\!?)>/g, '$1&gt;');
987
+ return content.replace(/(--\!?)>/g, '$1&gt;');
965
988
  }
966
989
 
967
990
  /**
@@ -14233,6 +14256,8 @@ function requireHTMLParser () {
14233
14256
  emitDoctype();
14234
14257
  break;
14235
14258
  case -1: // EOF
14259
+ // Lookahead states must consume the EOF marker explicitly.
14260
+ nextchar += 1;
14236
14261
  forcequirks();
14237
14262
  emitDoctype();
14238
14263
  emitEOF();