fix(line): truncate template title/altText on grapheme boundaries, not raw UTF-16#96395
fix(line): truncate template title/altText on grapheme boundaries, not raw UTF-16#96395ly-wang19 wants to merge 1 commit into
Conversation
…t raw UTF-16 createConfirmTemplate/createButtonTemplate/createTemplateCarousel/createCarouselColumn/ createImageCarousel truncated title and altText with a raw `.slice(0, N)`, so an emoji straddling a LINE field limit (e.g. a 40-char button title) was cut in half, leaving a lone high surrogate that LINE renders as the replacement char or rejects. Route those fields through the file's existing grapheme-safe truncateTemplateText (already used for the text body) via a small truncateOptionalTemplateText wrapper. Byte-identical for all-BMP input; only straddling-emoji truncation changes. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
Codex review: needs real behavior proof before merge. Reviewed June 24, 2026, 8:09 AM ET / 12:09 UTC. Summary PR surface: Source +6, Tests +10. Total +16 across 2 files. Reproducibility: yes. from source inspection and a focused Node check: current main can split an emoji surrogate pair when raw Review metrics: none identified. Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Proof guidance:
Risk before merge
Maintainer options:
Next step before merge
Security Review detailsBest possible solution: Merge this focused LINE template fix after real behavior proof or maintainer override, and track any broader LINE flex altText truncation cleanup separately if maintainers want full channel-wide consistency. Do we have a high-confidence way to reproduce the issue? Yes from source inspection and a focused Node check: current main can split an emoji surrogate pair when raw Is this the best way to solve the issue? Yes for the template-message surface: the PR reuses the existing local grapheme-aware helper already used for template body text, keeps the extension boundary local, and avoids new dependencies. It is intentionally narrower than a channel-wide LINE altText cleanup. AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against 2a484a3ff10d. Label changesLabel changes:
Label justifications:
Evidence reviewedPR surface: Source +6, Tests +10. Total +16 across 2 files. View PR surface stats
What I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
|
|
Closing to stay under the repo's active-PR limit and keep my queue focused on changes I can fully prove headlessly. This channel fix needs live-channel proof I can't generate in my current environment; the code change itself stands and I'll resubmit with live proof when I can run the channel. |
What Problem This Solves
createConfirmTemplate/createButtonTemplate/createTemplateCarousel/createCarouselColumn/createImageCarousel(extensions/line/src/template-messages.ts) truncate thetitleandaltTextfields with a raw UTF-16 slice:When an emoji / astral char straddles the limit (e.g. a 40-char button title ending in an emoji),
.slicekeeps only the leading high surrogate, producing a lone\uD83Dthat LINE renders as�or rejects:These builders are exported and feed live LINE outbound payloads (
buildTemplateMessageFromPayload→deliverLineAutoReply). Thetextbody already uses the grapheme-safetruncateTemplateText; onlytitle/altText(and the confirm-templatetext) were still slicing raw.Fix
Route every
title/altText/confirm-texttruncation through the file's existing grapheme-safetruncateTemplateText(plus a smalltruncateOptionalTemplateTextwrapper for the optional fields). No new import; this just makes the whole file consistent with how thetextbody is already handled.truncateTemplateText(s, n)is byte-identical tos.slice(0, n)for all-BMP input, so existing behavior is preserved.Evidence
Added a regression test on
createButtonTemplate; verified the grapheme-safe truncation:The existing
truncates title to 40 characterstest (all-ASCII) stays green; only the straddling-emoji case changes, and no fixed output contains a lone surrogate. (The array.slice(0, N)calls that cap action/column counts are unrelated and untouched.)