fix(file-provider): Ensure path comparisons are done on equal normalization#10443
fix(file-provider): Ensure path comparisons are done on equal normalization#10443claucambra wants to merge 19 commits into
Conversation
Signed-off-by: Claudio Cambra <developer@claudiocambra.com>
Signed-off-by: Claudio Cambra <developer@claudiocambra.com>
Signed-off-by: Claudio Cambra <developer@claudiocambra.com>
Signed-off-by: Claudio Cambra <developer@claudiocambra.com>
… normalised strings Signed-off-by: Claudio Cambra <developer@claudiocambra.com>
Signed-off-by: Claudio Cambra <developer@claudiocambra.com>
Signed-off-by: Claudio Cambra <developer@claudiocambra.com>
Signed-off-by: Claudio Cambra <developer@claudiocambra.com>
Signed-off-by: Claudio Cambra <developer@claudiocambra.com>
Signed-off-by: Claudio Cambra <developer@claudiocambra.com>
Signed-off-by: Claudio Cambra <developer@claudiocambra.com>
|
/backport to stable-34.0 please |
i2h3
left a comment
There was a problem hiding this comment.
I vaguely remember the problem of different Unicode representations from many years ago. 😅 I had to deal with that in exactly this context as well.
In general, the account no longer is a discriminator and does not need to be considered in code. I intended to remove it over time from internal APIs. Every file provider domain, process and Realm has its own scope restricted to a single account.
|
I will let Claude review this as well and post the results once they arrived. |
There was a problem hiding this comment.
Pull request overview
This PR addresses Unicode normalization mismatches (NFC vs NFD) in the macOS File Provider extension by introducing canonicalized comparison keys for remote locations and updating Realm queries/comparisons to use canonical-equivalent matching, with added regression tests and documentation.
Changes:
- Add persisted canonical (NFC) location keys (
normalizedServerUrl,normalizedFileName) toRealmItemMetadata, including schema migration and centralized query helpers. - Update FilesDatabaseManager queries and location comparisons to use canonical-equivalent matching (via normalized keys and
ItemMetadata.hasSameLocation(as:)). - Add regression tests and DocC design notes covering canonical-equivalence behavior and deduplication semantics.
Reviewed changes
Copilot reviewed 18 out of 18 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| shell_integration/MacOSX/NextcloudFileProviderKit/Tests/NextcloudFileProviderKitTests/RemoteChangePropagationTests.swift | Updates test metadata setup to use updateLocation(...). |
| shell_integration/MacOSX/NextcloudFileProviderKit/Tests/NextcloudFileProviderKitTests/PathBoundaryPrefixTests.swift | Refactors test setup to use updateLocation(...) for consistent normalized fields. |
| shell_integration/MacOSX/NextcloudFileProviderKit/Tests/NextcloudFileProviderKitTests/MoveSafeDeletionTests.swift | Refactors test metadata setup to use updateLocation(...). |
| shell_integration/MacOSX/NextcloudFileProviderKit/Tests/NextcloudFileProviderKitTests/LockTokenInvalidationTests.swift | Refactors test metadata setup to use updateLocation(...). |
| shell_integration/MacOSX/NextcloudFileProviderKit/Tests/NextcloudFileProviderKitTests/KeepDownloadedRecursiveTests.swift | Refactors test metadata setup to use updateLocation(...). |
| shell_integration/MacOSX/NextcloudFileProviderKit/Tests/NextcloudFileProviderKitTests/ItemPropertyTests.swift | Refactors test metadata setup to use updateLocation(...). |
| shell_integration/MacOSX/NextcloudFileProviderKit/Tests/NextcloudFileProviderKitTests/ItemMetadataTests.swift | Adds canonical-equivalence comparison test for hasSameLocation(as:). |
| shell_integration/MacOSX/NextcloudFileProviderKit/Tests/NextcloudFileProviderKitTests/FilesDatabaseManagerTests.swift | Adds canonical-path lookup and deduplication behavior tests; refactors setup to use updateLocation(...). |
| shell_integration/MacOSX/NextcloudFileProviderKit/Sources/NextcloudFileProviderKit/Metadata/RealmItemMetadata.swift | Adds persisted normalized location keys and updateLocation(...); updates equality and init to use canonical location comparison. |
| shell_integration/MacOSX/NextcloudFileProviderKit/Sources/NextcloudFileProviderKit/Metadata/ItemMetadata.swift | Adds hasSameLocation(as:) helper for canonical-equivalent in-memory comparisons. |
| shell_integration/MacOSX/NextcloudFileProviderKit/Sources/NextcloudFileProviderKit/Documentation.docc/UnicodePathNormalization.md | Adds DocC design note documenting Unicode normalization model and usage boundaries. |
| shell_integration/MacOSX/NextcloudFileProviderKit/Sources/NextcloudFileProviderKit/Documentation.docc/Documentation.md | Links the new Unicode normalization design note from package docs. |
| shell_integration/MacOSX/NextcloudFileProviderKit/Sources/NextcloudFileProviderKit/Database/SchemaVersion.swift | Bumps Realm schema version for canonical location keys. |
| shell_integration/MacOSX/NextcloudFileProviderKit/Sources/NextcloudFileProviderKit/Database/RealmItemMetadata+Queries.swift | Introduces centralized Realm query helpers for canonical-equivalent location/serverUrl matching. |
| shell_integration/MacOSX/NextcloudFileProviderKit/Sources/NextcloudFileProviderKit/Database/FilesDatabaseManager+Trash.swift | Updates trash queries to use canonical-aware hasServerUrl(...). |
| shell_integration/MacOSX/NextcloudFileProviderKit/Sources/NextcloudFileProviderKit/Database/FilesDatabaseManager+Directories.swift | Updates directory/descendant queries and rename propagation to use canonical-aware helpers and keep normalized fields in sync. |
| shell_integration/MacOSX/NextcloudFileProviderKit/Sources/NextcloudFileProviderKit/Database/FilesDatabaseManager+Deduplication.swift | Updates logical-duplicate eviction and startup cleanup to use canonical-aware location keys. |
| shell_integration/MacOSX/NextcloudFileProviderKit/Sources/NextcloudFileProviderKit/Database/FilesDatabaseManager.swift | Updates schema version, performs migration backfill of normalized fields, and switches remote-path lookup/comparisons to canonical-aware logic. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
SummaryNicely scoped, well-documented fix. The approach is the right one: keep the raw Two things to flag up front:
What's good
🔴 Blocking1. swiftformat 🟠 Worth addressing2. Working-set scan still compares raw paths across a normalization boundary — medium let childHasMaterialisedDescendant = materialisedItems.contains {
$0.ocId != childDirectory.ocId
&& ($0.serverUrl == childPath || $0.serverUrl.hasPrefix(childPath + "/"))
}Here 3. The 202→203 backfill migration is untested — medium 🟡 Low / consider4. 5. Distinct NFC/NFD server files get collapsed locally on upgrade — low (document as known limitation) 6. Test coverage gaps beyond the migration one (#3) — low
7. Empty-normalized raw fallback in the query helpers — low 🔵 Nits
Checked and found safe (no action needed)To save re-review, these raw comparisons were examined and are not normalization gaps — both sides are machine-constructed or server/sentinel values with no user-supplied path component: |
no longer necessary Signed-off-by: Claudio Cambra <developer@claudiocambra.com>
…escendancy with normalisation Signed-off-by: Claudio Cambra <developer@claudiocambra.com>
…n working set scan Signed-off-by: Claudio Cambra <developer@claudiocambra.com>
Signed-off-by: Claudio Cambra <developer@claudiocambra.com>
Signed-off-by: Claudio Cambra <developer@claudiocambra.com>
|
I believe the points for Claude's comments are addressed |
i2h3
left a comment
There was a problem hiding this comment.
Have you run swiftformat . in shell_integration/MacOSX/NextcloudFileProviderKit? That should fix the failing lint action.
Signed-off-by: Claudio Cambra <developer@claudiocambra.com>
Signed-off-by: Claudio Cambra <developer@claudiocambra.com>
…n convenience methods Signed-off-by: Claudio Cambra <developer@claudiocambra.com>
thanks :) now done |
|
Artifact containing the AppImage: nextcloud-appimage-pr-10443.zip Digest: To test this change/fix you can download the above artifact file, unzip it, and run it. Please make sure to quit your existing Nextcloud app and backup your data. |
|



Resolves
#10087
(though the deletion issue is unrelated and I see no way in which it is related)
Summary
macOS generally uses NFD normalisation, whereas the server uses NFC normalisation. This causes issues when performing path comparisons involving special characters (e.g. acute accents) or in certain languages (e.g. Korean).
This PR ensures we normalise server URLs and filenames consistently
Checklist
AI (if applicable)