| … | … | @@ -0,0 +1,69 @@ | |
| 65 | + | } | |
| 66 | + | } | |
| 67 | + | if (keep <= 0 || value.length <= keep + 4) return null; | |
| 68 | + | return { head: value.slice(0, value.length - keep), tail: value.slice(value.length - keep) }; | |
🟡 Medium ui/middle-truncate.tsx:59
MiddleTruncate corrupts identifiers containing non-BMP characters when the truncation boundary falls inside a surrogate pair, rendering replacement glyphs instead of the original branch name or path. splitForMiddleTruncate uses UTF-16 code-unit offsets and renders the resulting halves separately, so iterate over Unicode code points before calculating and applying the split.
| 1 | - let keep = tail ?? DEFAULT_TAIL; |
| 2 | + const chars = Array.from(value); |
| 3 | + let keep = tail ?? DEFAULT_TAIL; |
| 4 | if (tail === undefined) { |
| 5 | - const slash = value.lastIndexOf("/"); |
| 6 | - if (slash > 0 && slash < value.length - 1) { |
| 7 | - const segment = value.length - slash - 1; |
| 8 | + const slash = chars.lastIndexOf("/"); |
| 9 | + if (slash > 0 && slash < chars.length - 1) { |
| 10 | + const segment = chars.length - slash - 1; |
| 11 | keep = segment <= MAX_SEGMENT_TAIL ? segment : DEFAULT_TAIL; |
| 12 | } |
| 13 | } |
| 14 | - if (keep <= 0 || value.length <= keep + 4) return null; |
| 15 | - return { head: value.slice(0, value.length - keep), tail: value.slice(value.length - keep) }; |
| 16 | + if (keep <= 0 || chars.length <= keep + 4) return null; |
| 17 | + return { head: chars.slice(0, chars.length - keep).join(""), tail: chars.slice(chars.length - keep).join("") }; |
Also found in 1 other location(s)
apps/web/src/components/pullRequest/PullRequestDetailPanel.tsx:2254
The new
MiddleTruncateuse can render a corrupted branch name when the calculated cut falls inside an astral Unicode character (for example, an emoji in a valid branch ref).splitForMiddleTruncateslices by UTF-16 code-unit offsets and the two halves are placed in separate spans, so a surrogate pair split at the boundary becomes two lone surrogates and displays as replacement glyphs rather than the original identifier.
🤖 Copy this AI Prompt to have your agent fix this:
| 1 | In file @apps/web/src/components/ui/middle-truncate.tsx around lines 59-68: |
| 2 | |
| 3 | `MiddleTruncate` corrupts identifiers containing non-BMP characters when the truncation boundary falls inside a surrogate pair, rendering replacement glyphs instead of the original branch name or path. `splitForMiddleTruncate` uses UTF-16 code-unit offsets and renders the resulting halves separately, so iterate over Unicode code points before calculating and applying the split. |
| 4 | |
| 5 | Also found in 1 other location(s): |
| 6 | - apps/web/src/components/pullRequest/PullRequestDetailPanel.tsx:2254 -- The new `MiddleTruncate` use can render a corrupted branch name when the calculated cut falls inside an astral Unicode character (for example, an emoji in a valid branch ref). `splitForMiddleTruncate` slices by UTF-16 code-unit offsets and the two halves are placed in separate spans, so a surrogate pair split at the boundary becomes two lone surrogates and displays as replacement glyphs rather than the original identifier. |
Note
Written by claude-fable-5-1 on behalf of Maria
Fixed in f6b267d: the split walks code points (Array.from) for both the slash search and the cut, so a surrogate pair can no longer be halved.