Skip to content

fix(id): sanitize collaborative cursor names - #4052

Merged
dezren39 merged 4 commits into
mainfrom
queue/5053-1833-cursor-name-sanitize
Nov 2, 2026
Merged

dezren39 merged 4 commits into
mainfrom
queue/5053-1833-cursor-name-sanitize

Conversation

@dezren39

@dezren39 dezren39 commented Nov 1, 2026 •

Copy link
Copy Markdown
Member

Summary

  • Sanitize identity and cursor display names consistently: remove control and bidi override/isolate characters, cap at 48 Unicode scalar values, and preserve ZWJ/ZWNJ.
  • Sanitize cursor names before storing and broadcasting, including identity name updates.
  • Limit collaborative WebSocket messages to MAX_FRAME_BYTES (1 MiB).
  • Add sanitizer cases and a cursor-ingest storage/broadcast regression.

Verification

  • cargo fmt --manifest-path pkgs/id/Cargo.toml -- --check — passed.
  • git diff --check — passed.
  • cargo test --features web in pkgs/id — running locally; CI remains authoritative.

Closes #1833


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.

@dezren39
dezren39 requested a review from a team as a code owner November 1, 2026 22:55
@coderabbitai

coderabbitai Bot commented Nov 1, 2026 •

Copy link
Copy Markdown

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 36 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 3d1a3cdf-ec15-4b8b-92c4-8011efd93f22
Commits

Reviewing files that changed from the base of the PR and between f12f5b7 and 134364f.

Files selected for processing: 3
  • pkgs/id/src/web/collab.rs
  • pkgs/id/src/web/identity.rs
  • pkgs/id/web/src/collab.ts
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 1, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-02T12:39:53.773537Z 134364f Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: cbfb52a641

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread pkgs/id/src/web/collab.rs Outdated
State(state): State<super::AppState>,
) -> impl IntoResponse {
ws.on_upgrade(move |socket| {
ws.max_message_size(crate::world_session::MAX_FRAME_BYTES)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Handle oversized editor changes before enforcing the message cap

When a user pastes more than 1 MiB of text, this new limit rejects the entire edit and disconnects the socket. The browser's handleEditorChange in web/src/collab.ts sends all pending ProseMirror steps in one message without size validation or splitting, and the server's receive loop exits on the resulting WebSocket error. On reconnect, the client's MSG.INIT handler destroys the existing editor and rebuilds it from server state, losing the rejected paste and any other unconfirmed edits. Add compatible client-side handling, including splitting oversized individual steps or visibly rejecting the edit without discarding local state, before applying this cap to collaborative editing.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 72a3897 (queue task 5053): send() in pkgs/id/web/src/collab.ts now measures the packed MessagePack payload and never sends a message over the 1 MiB MAX_FRAME_BYTES cap. An oversized STEPS message (e.g. a >1 MiB paste) is dropped with a console error and the connection error status instead of being sent — the socket is never closed by the cap, no reconnect/INIT rebuild happens, and the local document with all unconfirmed edits is preserved; the edit simply cannot sync until it is made smaller (e.g. undo), which is the "visibly rejecting without discarding local state" outcome. Splitting oversized step batches so they actually sync (ACK-ordered chunking, plus the single-oversized-step case) is filed as #4324. Web checks on the branch: vitest run src/collab.test.ts 3/3 pass, bun run build:js succeeds.

The 1 MiB max_message_size added for #1833 closes the socket when exceeded, and the reconnect INIT rebuild discards every unconfirmed local edit — a >1 MiB paste would be lost. Guard send() in web/src/collab.ts: a packed message over MAX_FRAME_BYTES is dropped with an error status instead of sent, keeping the socket and the local document alive; the edit simply cannot sync until it is smaller. True chunked sending of oversized step batches is filed as #4324.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 72a3897018

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread pkgs/id/src/web/collab.rs Outdated

#[allow(clippy::unwrap_used, clippy::panic)]
#[tokio::test]
async fn cursor_ingest_sanitizes_before_storage_and_broadcast() {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Prefix the new regression test with test_

The naming guideline in pkgs/id/AGENTS.md explicitly requires tests to use the test_ prefix. Rename this function to test_cursor_ingest_sanitizes_before_storage_and_broadcast to comply with that repository convention.

AGENTS.md reference: pkgs/id/AGENTS.md:L140-L140

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in f1d8f90 (task 5053): the regression test is renamed to test_cursor_ingest_sanitizes_before_storage_and_broadcast per the pkgs/id/AGENTS.md test_ prefix convention. The same commit merges origin/main (conflict in collab.rs resolved by keeping main's crate::frames::MAX_FRAME_BYTES handler form plus this PR's store_and_broadcast_cursor helper).

@dezren39

dezren39 commented Nov 2, 2026

Copy link
Copy Markdown
Member Author

@codex review — head 134364f merges origin/main into this branch and renames the regression test per your P1 on 72a3897; please re-review the current head.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 👍

Reviewed commit: 134364f201

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@dezren39
dezren39 merged commit 5375358 into main Nov 2, 2026
1 check passed
@dezren39
dezren39 deleted the queue/5053-1833-cursor-name-sanitize branch November 2, 2026 12:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant