You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
room-share: the joined notice and the copied pane line are cut on UTF-16 units, and the pane line is unbounded #1933
Implementation: FlyBot (ours) — PR follows within 24h. Do not pick up without a pickup-ok comment on this issue.
Written-by: FlyBot Lead
Claimed-by: FlyBot Lead
Claim-Id: 287704d751b440548bfbd9049eaa67aa
Branch: dev/2-p285-room-share-unbounded
Base: 77c9bc6
At: 2026-10-31T12:31:47Z
Implementation: FlyBot (ours) — PR follows within 24h. Do not pick up without a pickup-ok comment.
Written-by: FlyBot Lead
Two bounds on text written by the other side of a share still count UTF-16 units instead of code points, so a cut can leave half a surrogate pair in the room. Both were found while reviewing #1929 and left out of it on purpose.
1. The joined notice — core/src/host/room-membership.js, noticeOf: data.notice.replace(…).trim().slice(0, 2000) cuts at 2,000 UTF-16 units. A friend's notice whose 2,000th unit lands inside an emoji or ZWJ sequence is stored and rendered half cut.
2. The copied pane line — same file, applyShareHistory: the line written to room.log goes through cut(String(entry.text), HISTORY_TEXT), but the same loop then calls showShareLine({ text: entry.text }) with the raw sender string, and showShareLine applies no bound at all. The pane line is therefore unbounded (it can carry the transport's full 4,000 units) and can also end inside a pair, so the pane and the log disagree about the same line.
Expected.
Both bounds cut on code point boundaries and keep their current values: the notice stays at the envelope's own notice bound (NOTICE_MAX, 2,000) and the copied pane line uses the same HISTORY_TEXT the adjacent cut already uses. No new number is introduced; the two sides must share one constant so they cannot drift apart.
The pane line equals the stored prefix: what showSharedLine receives is the same bounded text that went into room.log.
The line operation is untouched: its text legitimately rides the transport bound (4,000), so the bound belongs at the applyShareHistory call site, not inside showShareLine.
Acceptance (red first, one test per site).
A join whose notice is 'a'.repeat(1999) + '😀' + 'b'.repeat(400) parses and stores a notice that is well formed (no lone surrogate) and is the expected prefix.
A copied history entry whose stored line is already a 1,999-unit prefix must be shown as exactly that prefix — not the sender's raw 2,405 units, and not a half pair.
Mutation, one at a time: put .slice(0, 2000) back in noticeOf → only case 1 red; pass entry.text back to showShareLine → only case 2 red.
fitJoin's notice shrink loop is not touched by this change.
Scope.core/src/host/room-membership.js (two call sites) + core/test/remote-room.test.js (the two cases) + the mirrors under patches/ds-bot/files/.
Dedupe: checked open issues — #1932 covers fitJoin dropping the notice when the roster is full (a different site: envelope fitting, not code-unit cutting), #1930/#1928 are closed or unrelated. No open issue covers these two.
Activity
HugoXK commentedon Oct 31, 2026
Heartbeat
Written-by: FlyBot Lead
Still-working: 287704d751b440548bfbd9049eaa67aa
At: 2026-10-31T12:37:31Z