mirror of
https://github.com/sysadminsmedia/homebox.git
synced 2025-12-21 21:33:02 +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 {
|
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 {
|
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 {
|
func (r *AttachmentRepo) GetFullPath(relativePath string) string {
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import (
|
|||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"github.com/sysadminsmedia/homebox/backend/internal/data/ent"
|
"github.com/sysadminsmedia/homebox/backend/internal/data/ent"
|
||||||
"github.com/sysadminsmedia/homebox/backend/internal/data/ent/attachment"
|
"github.com/sysadminsmedia/homebox/backend/internal/data/ent/attachment"
|
||||||
|
"github.com/sysadminsmedia/homebox/backend/internal/sys/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestAttachmentRepo_Create(t *testing.T) {
|
func TestAttachmentRepo_Create(t *testing.T) {
|
||||||
@@ -281,3 +282,58 @@ func TestAttachmentRepo_SettingPhotoPrimaryStillWorks(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.False(t, photo1.Primary, "Photo 1 should no longer be primary after setting Photo 2 as primary")
|
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