fix: handle Unicode attachment filenames - #7
Open
KateNedelina wants to merge 3 commits into
Open
Conversation
Author
|
CI note: GitHub has held the Test workflow for this fork-based PR in |
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.
Summary
Root cause
sanitize_filenamemeasured the sanitized filename withString::len()and then sliced it with a byte offset (clean[..50]). Rust strings are UTF-8, so a filename containing a multi-byte character could be sliced in the middle of that character. The resulting panic aborted the upload request and the browser surfaced only:Failed to upload attachment:This was reproduced with a filename containing Cyrillic text (
4636__исполнитель_подтвердился...).The same class of corruption was also present in streamed agent output. The backend decoded each
ReaderStreamchunk independently withfrom_utf8_lossy. When a multi-byte Cyrillic characterwas split between two chunks, both incomplete sequences were replaced with
�, producing textsuch as
де��ствийin persisted assistant summaries.Implementation
.chars().take(...)instead of byte offsets.crates/services/src/services/file.rs.Utf8ChunkDecodershared by local process streaming and Codex command-output normalization.Validation
Passing locally:
pnpm run formatcargo test -p services filename(3 passed)cargo test -p utils utf8_chunk_decoder(2 passed)cargo check -p local-deploymentcargo check -p executorspnpm run web-core:checkpnpm --filter @vibe/local-web run lintpnpm --filter @vibe/ui run lintgit diff --cached --checkThe local checkout cannot reproduce the full GitHub Actions environment: the host does not have the
glib-2.0development package required by the workspace/Tauri crates, and the local Node heap limit is insufficient for the full Vite production bundle at the final chunk-rendering stage. The latest upstreammainTest workflow was already failing before this branch (including frontend and backend jobs); the changed packages themselves pass the focused checks above.Review notes
The commit is intentionally limited to the attachment failure and does not include the unrelated pre-existing local changes in
package.jsonorpackages/local-web/vite.config.ts.