Skip to content

[Bug]: Uploaded files are saved with garbled non-ASCII names and overwrite existing files with the same name #458

Open

Description

@mayank609

Bug Description

Files sent from the phone with Send File don't always end up on the host the way they were sent:

  1. Non-ASCII file names are garbled. résumé.pdf is saved as résumé.pdf, and 照片.jpg as ç§ç.jpg. Browsers send the multipart filename as raw UTF-8, but parseMultipart in src/server/signalling/handlers/fileShare.ts reads the part headers from body.toString("binary") (latin1), so every multi-byte character turns into mojibake.

  2. Uploading a file with an existing name silently overwrites the old one. handleFileUpload calls fs.promises.writeFile(path.join(uploadDir, safeName), data), which replaces whatever is already there. This is easy to hit from a phone: iOS Safari names every camera photo image.jpg, so sending two photos leaves only the second one in ReinShared, with no warning.

Steps to Reproduce

  1. Run Rein and open the trackpad page on a phone.
  2. Send a file named résumé.pdf via Send File → it appears in ~/Downloads/ReinShared as résumé.pdf.
  3. Send a photo from the iOS camera roll (image.jpg), then send a different one → only one image.jpg exists, containing the second photo.

I also reproduced both against handleFileUpload directly with a local HTTP server and Node's FormData (which encodes file names the same way browsers do):

on disk: [ 'image.jpg', 'résumé.pdf', 'ç§ç.jpg' ]
image.jpg contents: second photo

Expected Behavior

  • The file is saved with the exact name it was sent with.
  • If a file with that name already exists, the new one is saved next to it (e.g. image (1).jpg) instead of replacing it.

Desktop Operating System

All (the logic is in the platform-independent fileShare.ts)

Client OS and browser

All (any browser sends UTF-8 filenames; iOS Safari's image.jpg naming makes the overwrite very common)

Rein Version

main @ 4efa9a8

Proposed fix

  • Decode the part header bytes as UTF-8 (body.subarray(headerStart, headerEnd).toString("utf8")). The latin1 string is still fine for finding offsets, since its indices match byte positions.
  • Write with the wx flag and fall back to name (1).ext, name (2).ext, … on EEXIST, which also avoids two simultaneous uploads racing for the same name.
  • Add a test file for the upload handler covering both cases.

I'd like to work on this.

Activity

  1. Aryan-en commented on Nov 4, 2026

    @Aryan-en
    Contributor

    Hi @mayank609, thanks for the detailed reproduction and proposed fix!

    I was looking into this issue as well. I noticed you've mentioned wanting to work on it, so I don't want to duplicate your efforts.

    If you'd find it useful, I'd be happy to help with regression tests, review the implementation, or test the fix across macOS and iOS Safari.

    Let me know what would be most helpful!

  2. added a commit that references this issue on Nov 4, 2026
    f0b08ef
  3. mayank609 commented on Nov 4, 2026

    @mayank609
    Author

    Thanks @Aryan-en! I'm working on the fix now and should have a PR up soon. Testing on macOS and iOS Safari would really help, since non-ASCII names in multipart uploads are where Safari tends to behave differently. I'll tag you on the PR once it's open.

  4. Aryan-en commented on Nov 4, 2026

    @Aryan-en
    Contributor

    Thanks @mayank609!

    Just to clarify, I had already started working on this and opened PR #459 with the UTF-8 filename fix, collision-safe file saving, and regression tests.

    I realize we're working on overlapping implementations, and I definitely don't want to duplicate efforts.

    I'm happy to coordinate on the fix and help test it on macOS and iOS Safari. We can compare approaches and incorporate whichever implementation works best.

    Let me know what you think!

  5. gitcordapp commented on Nov 4, 2026

    @gitcordapp

    Link your account with Gitcord

    Thanks for opening this issue, @mayank609!

    To receive Discord notifications and contributor tracking for this organization:

    1. Join Discord: https://discord.gg/hjUhu33uAn
    2. In Discord, run /link mayank609
    3. Paste the verification code into your GitHub bio (or a public gist)
    4. Click Verify in Discord (or run /verify-link mayank609)

    Once linked, Gitcord can notify you about assignments, mentions, and more.

    — Posted by Gitcord

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions