Pre-existing, found by the review of #12 (R2/R3, P3). (1) The 40-char cap is a UTF-16 slice: data-assistant-name = 'a' + '😀'.repeat(20) yields a lone high surrogate (isWellFormed() false); use Array.from / Intl.Segmenter grapheme counting. (2) A U+202E RTL override in the name reaches the status text node unisolated; wrap the name in or strip bidi controls (U+202A–U+202E, U+2066–U+2069). Both are attacker-controlled only by the site owner, so low severity.
Pre-existing, found by the review of #12 (R2/R3, P3). (1) The 40-char cap is a UTF-16 slice: data-assistant-name = 'a' + '😀'.repeat(20) yields a lone high surrogate (isWellFormed() false); use Array.from / Intl.Segmenter grapheme counting. (2) A U+202E RTL override in the name reaches the status text node unisolated; wrap the name in or strip bidi controls (U+202A–U+202E, U+2066–U+2069). Both are attacker-controlled only by the site owner, so low severity.