Repository navigation
Truncate RPC error fields by byte length, not code unit count - #1254
Open
xianshijing-lk wants to merge 2 commits into
Open
xianshijing-lk wants to merge 2 commits into
xianshijing-lk wants to merge 2 commits into
Conversation
_truncateForWire compared String.length against kRpcMaxPayloadBytes and sliced with substring. String.length counts UTF-16 code units, not bytes, so the cap did not bound the wire packet it exists to bound: a message of non-ASCII text could still encode to well over 15 KB. The same slice could also land between the halves of a surrogate pair, sending the pair's first half alone, which encodes as U+FFFD and reached the peer corrupted. Add truncateBytes, which binary searches for the longest prefix fitting the byte budget and steps back off a trailing high surrogate, and use it for both the message and the data field. Port of livekit/client-sdk-js#2126. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
xianshijing-lk
requested review from
changt,
cloudwebrtc and
hiroshihorie
as code owners
October 23, 2026 22:18
changt
approved these changes
Oct 23, 2026
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This branch has not been deployed
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.
Port of livekit/client-sdk-js#2126.
The bug
RpcServerManager._truncateForWirecaps the errormessageanddataatkRpcMaxPayloadBytes(15360) like this:String.lengthcounts UTF-16 code units, not bytes, which causes two distinct problems:substringcan split a surrogate pair, sending its first half alone. That is not representable in UTF-8, so it reaches the peer asU+FFFD.Repro
Added a case to
test/core/rpc_test.dartthat throws an oversize emoji message from an RPC handler and inspects what the caller receives. Against the unfixed code:The fix
Added
lib/src/rpc/rpc_utils.dartwithtruncateBytes, mirroring the JS SDK'sroom/rpc/utils.ts: binary search for the longest prefix whose UTF-8 encoding fits, then step back off a trailing high surrogate. Both the message and data fields now use it.This makes the cap byte-accurate as well as fixing the split, so the test asserts both properties.
Verification
flutter test— 467/467 pass (the new case fails before the change).flutter analyze lib/src/rpc/clean.Not needed elsewhere
Swift and Rust are safe by construction (grapheme
Characters andcharscalar values respectively). Android has the same class of bug, fixed in livekit/client-sdk-android#1044.🤖 Generated with Claude Code