mirror of
https://github.com/sysadminsmedia/homebox.git
synced 2025-12-21 13:23:14 +01:00
Fix Windows attachment path encoding issue by normalizing to forward slashes
Co-authored-by: tankerkiller125 <3457368+tankerkiller125@users.noreply.github.com>
This commit is contained in:
@@ -98,11 +98,32 @@ func ToItemAttachment(attachment *ent.Attachment) ItemAttachment {
|
||||
}
|
||||
|
||||
func (r *AttachmentRepo) path(gid uuid.UUID, hash string) string {
|
||||
return filepath.Join(gid.String(), "documents", hash)
|
||||
// Always use forward slashes for consistency across platforms
|
||||
// This ensures paths are stored in the database with forward slashes
|
||||
return fmt.Sprintf("%s/documents/%s", gid.String(), hash)
|
||||
}
|
||||
|
||||
func (r *AttachmentRepo) fullPath(relativePath string) string {
|
||||
return filepath.Join(r.storage.PrefixPath, relativePath)
|
||||
// Normalize path separators to forward slashes for blob storage
|
||||
// The blob library expects forward slashes in keys regardless of OS
|
||||
normalizedRelativePath := strings.ReplaceAll(relativePath, "\\", "/")
|
||||
|
||||
// Always use forward slashes when joining paths for blob storage
|
||||
if r.storage.PrefixPath == "" {
|
||||
return normalizedRelativePath
|
||||
}
|
||||
normalizedPrefix := strings.ReplaceAll(r.storage.PrefixPath, "\\", "/")
|
||||
|
||||
// Trim trailing slashes from prefix and leading slashes from relative path
|
||||
// to avoid double slashes when joining
|
||||
normalizedPrefix = strings.TrimSuffix(normalizedPrefix, "/")
|
||||
normalizedRelativePath = strings.TrimPrefix(normalizedRelativePath, "/")
|
||||
|
||||
if normalizedPrefix == "" {
|
||||
return normalizedRelativePath
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%s/%s", normalizedPrefix, normalizedRelativePath)
|
||||
}
|
||||
|
||||
func (r *AttachmentRepo) GetFullPath(relativePath string) string {
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/sysadminsmedia/homebox/backend/internal/data/ent"
|
||||
"github.com/sysadminsmedia/homebox/backend/internal/data/ent/attachment"
|
||||
"github.com/sysadminsmedia/homebox/backend/internal/sys/config"
|
||||
)
|
||||
|
||||
func TestAttachmentRepo_Create(t *testing.T) {
|
||||
@@ -281,3 +282,58 @@ func TestAttachmentRepo_SettingPhotoPrimaryStillWorks(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
assert.False(t, photo1.Primary, "Photo 1 should no longer be primary after setting Photo 2 as primary")
|
||||
}
|
||||
|
||||
func TestAttachmentRepo_PathNormalization(t *testing.T) {
|
||||
// Test that paths always use forward slashes
|
||||
repo := &AttachmentRepo{
|
||||
storage: config.Storage{
|
||||
PrefixPath: ".data",
|
||||
},
|
||||
}
|
||||
|
||||
testGUID := uuid.MustParse("eb6bf410-a1a8-478d-a803-ca3948368a0c")
|
||||
testHash := "f295eb01-18a9-4631-a797-70bd9623edd4.png"
|
||||
|
||||
// Test path() method - should always return forward slashes
|
||||
relativePath := repo.path(testGUID, testHash)
|
||||
assert.Equal(t, "eb6bf410-a1a8-478d-a803-ca3948368a0c/documents/f295eb01-18a9-4631-a797-70bd9623edd4.png", relativePath)
|
||||
assert.NotContains(t, relativePath, "\\", "path() should not contain backslashes")
|
||||
|
||||
// Test fullPath() with forward slash input (from database)
|
||||
fullPath := repo.fullPath("eb6bf410-a1a8-478d-a803-ca3948368a0c/documents/f295eb01-18a9-4631-a797-70bd9623edd4.png")
|
||||
assert.Equal(t, ".data/eb6bf410-a1a8-478d-a803-ca3948368a0c/documents/f295eb01-18a9-4631-a797-70bd9623edd4.png", fullPath)
|
||||
assert.NotContains(t, fullPath, "\\", "fullPath() should not contain backslashes")
|
||||
|
||||
// Test fullPath() with backslash input (legacy Windows paths from old database)
|
||||
fullPathWithBackslash := repo.fullPath("eb6bf410-a1a8-478d-a803-ca3948368a0c\\documents\\f295eb01-18a9-4631-a797-70bd9623edd4.png")
|
||||
assert.Equal(t, ".data/eb6bf410-a1a8-478d-a803-ca3948368a0c/documents/f295eb01-18a9-4631-a797-70bd9623edd4.png", fullPathWithBackslash)
|
||||
assert.NotContains(t, fullPathWithBackslash, "\\", "fullPath() should normalize backslashes to forward slashes")
|
||||
|
||||
// Test with Windows-style prefix path
|
||||
repoWindows := &AttachmentRepo{
|
||||
storage: config.Storage{
|
||||
PrefixPath: ".data",
|
||||
},
|
||||
}
|
||||
fullPathWindows := repoWindows.fullPath("eb6bf410-a1a8-478d-a803-ca3948368a0c/documents/f295eb01-18a9-4631-a797-70bd9623edd4.png")
|
||||
assert.NotContains(t, fullPathWindows, "\\", "fullPath() should normalize Windows paths")
|
||||
|
||||
// Test empty prefix
|
||||
repoNoPrefix := &AttachmentRepo{
|
||||
storage: config.Storage{
|
||||
PrefixPath: "",
|
||||
},
|
||||
}
|
||||
fullPathNoPrefix := repoNoPrefix.fullPath("eb6bf410-a1a8-478d-a803-ca3948368a0c/documents/f295eb01-18a9-4631-a797-70bd9623edd4.png")
|
||||
assert.Equal(t, "eb6bf410-a1a8-478d-a803-ca3948368a0c/documents/f295eb01-18a9-4631-a797-70bd9623edd4.png", fullPathNoPrefix)
|
||||
|
||||
// Test with single slash prefix (like in tests)
|
||||
repoSlashPrefix := &AttachmentRepo{
|
||||
storage: config.Storage{
|
||||
PrefixPath: "/",
|
||||
},
|
||||
}
|
||||
fullPathSlashPrefix := repoSlashPrefix.fullPath("eb6bf410-a1a8-478d-a803-ca3948368a0c/documents/f295eb01-18a9-4631-a797-70bd9623edd4.png")
|
||||
assert.Equal(t, "eb6bf410-a1a8-478d-a803-ca3948368a0c/documents/f295eb01-18a9-4631-a797-70bd9623edd4.png", fullPathSlashPrefix)
|
||||
assert.NotContains(t, fullPathSlashPrefix, "//", "fullPath() should not have double slashes")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user