fix(line): truncate action label/data on code-point boundaries#96413
Closed
ly-wang19 wants to merge 1 commit into
Closed
fix(line): truncate action label/data on code-point boundaries#96413ly-wang19 wants to merge 1 commit into
ly-wang19 wants to merge 1 commit into
Conversation
The LINE action builders truncated label (20) and data/displayText (300) with a raw `String.prototype.slice`, which cuts an emoji apart when the limit falls inside a surrogate pair. A 19-char label followed by 😀 (U+1F600) yielded a label ending in a lone high surrogate (\uD83D), which LINE renders as a replacement glyph or rejects. Truncate with `truncateUtf16Safe` instead so a dangling half-emoji is dropped, matching how this plugin already truncates LINE template titles. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
Closing this PR because the author has more than 20 active PRs in this repo. Please reduce the active PR queue and reopen or resubmit once it is back under the limit. You can close your own PRs to get back under the limit. |
This was referenced Jun 24, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What Problem This Solves
The LINE action builders in
extensions/line/src/actions.tsenforce LINE'sfield limits by calling
String.prototype.slicedirectly:messageAction/uriAction/postbackAction/datetimePickerAction→label.slice(0, 20)postbackAction/datetimePickerAction→data.slice(0, 300)anddisplayText?.slice(0, 300)A raw UTF-16 slice cuts an emoji in half whenever the limit lands inside a
surrogate pair. The returned
labelthen ends in an unpaired highsurrogate, which LINE renders as a replacement character (or rejects the
payload).
Repro:
messageAction("1234567890123456789😀")— 19 ASCII chars + 😀(U+1F600, 2 UTF-16 code units) = 21 code units.
labelreturned"1234567890123456789\uD83D"— trailing lone high surrogate"1234567890123456789"— half-emoji dropped, no lone surrogateThe fix swaps the raw slices for
truncateUtf16Safe(value, limit)fromopenclaw/plugin-sdk/text-utility-runtime, which drops a dangling surrogateinstead of emitting it. This matches how this plugin already truncates LINE
template titles (
truncateTemplateTextintemplate-messages.ts). Normalinputs (short labels, exactly-at-limit ASCII, fully-fitting emoji) are
unchanged, and
displayTextstaysundefinedwhen omitted.Evidence
Standalone red→green proof (replicates
truncateUtf16Safe+ the old vs. newaction logic):
The script asserts:
label.slice(0, 20)keeps a lone high surrogate (\uD83D)."1234567890123456789"(no lonesurrogate) for
label, and surrogate-safedata/displayText."Yes"→"Yes", 20-char ASCII unchanged, 25-char ASCIItruncated to 20, fully-fitting
"hi😀"preserved, anddisplayTextstaysundefinedwhen not passed.New unit tests in
extensions/line/src/message-cards.test.tscovermessageAction,uriAction,postbackAction(label, data, displayText), anddatetimePickerAction, asserting no/[\uD800-\uDBFF](?![\uDC00-\uDFFF])/lone surrogate survives truncation.
🤖 Generated with Claude Code