Skip to content

BugFix - Stop Re-Upload Same File Due To File Extension#15253

Open
alperozturk96 wants to merge 11 commits intomasterfrom
bugfix/stop-reupload-due-to-file-extension-lowercasing
Open

BugFix - Stop Re-Upload Same File Due To File Extension#15253
alperozturk96 wants to merge 11 commits intomasterfrom
bugfix/stop-reupload-due-to-file-extension-lowercasing

Conversation

@alperozturk96
Copy link
Collaborator

@alperozturk96 alperozturk96 commented Jul 25, 2025

  • Tests written, or not not needed

Issue

When uploading a file, the app changes the file extension to lowercase (e.g., .JPG becomes .jpg). This leads to duplicate uploads if the same file was previously uploaded with the original (uppercase) extension, since the system may treat .JPG and .jpg as different files.

This behavior has resulted in thousands of unintended duplicates.

How to reproduce?

  1. Have a file in folder, e.g. File.JPG
  2. Try to upload exact same file but with lowercased extension e.g. File.jpg
be.mov

Solution

If one of the remote path variant (File.JPG or File.jpg) exists in remote and file didn't change, skip the upload process.

@mpivchev Please check this for iOS as well. @tobiasKaminsky fyi.

After

pt.mp4

How to test?

  1. Files with the exact same name, content and only differing in upper- or lowercase extensions should not be re-uploaded.
  2. If a file has the same name but different content, a conflict resolution dialog must be shown.

@alperozturk96 alperozturk96 linked an issue Jul 25, 2025 that may be closed by this pull request
4 tasks
@alperozturk96
Copy link
Collaborator Author

/backport to stable-3.32

@alperozturk96 alperozturk96 requested a review from mpivchev July 28, 2025 12:41
@alperozturk96 alperozturk96 force-pushed the bugfix/stop-reupload-due-to-file-extension-lowercasing branch from 1936b91 to e2c219b Compare July 30, 2025 07:18
}

val remoteFile = getRemoteFile(path)
val remoteFile = fileOperationHelper.getRemoteFile(path, client)
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

OfflineOperationWorker was updated to use the logic in FileUtil to prevent code duplication and unify similar functionality.

getFileByDecryptedRemotePath(lc) ?: getFileByDecryptedRemotePath(uc)
}

if (upload.toFile()?.length() == remoteFile?.fileLength) {
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

@tobiasKaminsky @ZetaTom

I need to compare a local file intended for upload with an existing remote file to determine if they are exactly the same. While file size can be used as a basic check, I’m looking for a more reliable method.

Using eTags is not feasible in this case, as the file to be uploaded (OCUpload) does not have an eTag yet. Similarly, relying on the modification timestamp is unreliable, since it can change due to non-content-related operations such as permission updates or file copying.

At this point, I have a java.io.File object and an OCFile instance, and I need to determine whether they represent the same file content.

Any suggestions for a more robust comparison method beyond file size?

Signed-off-by: alperozturk <alper_ozturk@proton.me>
Signed-off-by: alperozturk <alper_ozturk@proton.me>
Signed-off-by: alperozturk <alper_ozturk@proton.me>
Signed-off-by: alperozturk <alper_ozturk@proton.me>
Signed-off-by: alperozturk <alper_ozturk@proton.me>
Signed-off-by: alperozturk <alper_ozturk@proton.me>
Signed-off-by: alperozturk <alper_ozturk@proton.me>
Signed-off-by: alperozturk <alper_ozturk@proton.me>
Signed-off-by: alperozturk <alper_ozturk@proton.me>
Signed-off-by: alperozturk <alper_ozturk@proton.me>
Signed-off-by: alperozturk <alper_ozturk@proton.me>
@alperozturk96 alperozturk96 force-pushed the bugfix/stop-reupload-due-to-file-extension-lowercasing branch from 6a85f12 to 3b6f42e Compare August 7, 2025 07:12
@github-actions
Copy link

github-actions bot commented Aug 7, 2025

test-Unit test failed, but no output was generated. Maybe a preliminary stage failed.

@github-actions
Copy link

github-actions bot commented Aug 7, 2025

Codacy

Lint

TypemasterPR
Warnings4848
Errors1111

SpotBugs

CategoryBaseNew
Bad practice6060
Correctness6363
Dodgy code296296
Experimental11
Internationalization77
Malicious code vulnerability22
Multithreaded correctness3535
Performance5050
Security1818
Total532532

@github-actions
Copy link

github-actions bot commented Aug 7, 2025

APK file: https://www.kaminsky.me/nc-dev/android-artifacts/15253.apk

qrcode

To test this change/fix you can simply download above APK file and install and test it in parallel to your existing Nextcloud app.

@fabolhak
Copy link

fabolhak commented Aug 12, 2025

Unfortunately, this change makes it worse for my use case 😢. I use to following workflow to upload my pictures (with ending .JPG):

  • open the inbuilt Files app
  • select all images I want to store on my nextcloud instance
  • move all files to the specific folder using the Nextcloud storage provider in files app

With the previous version two files were created:

  • empty .JPG file
  • actual .jpg file

For some reason the .JPG files were never deleted and I had to clean them up manually.

With the linked version above, I only get the following file:

  • empty .JPG file

And the file with actual content is lost :(

So please consider reworking the whole "changing of file extension to lowercase feature" as it can cause a lot of trouble.

logs.txt

@tobiasKaminsky
Copy link
Member

  • auto rename should only be working when "enforce windows compatible mode" is enabled, which is not clear by server right now (server justs adds some additional config to capabilities)
  • if auto-rename is enabled, then our app should check before upload, if a renamed file exists and if yes, it should show the conflict resolution screen

@fabolhak
Copy link

fabolhak commented Aug 31, 2025

I have "enforce windows compatible mode" disabled. Still the file extensions get renamed from upper case to lower case: JPG -> jpg or MP4 -> mp4

Uploading via the Nextcloud app works fine (still does the renaming), but uploading via the inbuilt File browser is broken.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

upload changes case of file extension to lowercase

3 participants