Skip to content

Commit

Permalink
Paths are joined with client side separators when targeting remotes (#…
Browse files Browse the repository at this point in the history
…547)

Currently, filepath.Join is used to join path fragments that are supposed
to be created on remote storage backends. This could theoretically cause
problems when the separators used by the client and the remotes do not match.
It's unlikely this causes problems right now, but it's definitely better to
rectify it before it causes further confusion.

This was raised in #541
  • Loading branch information
m90 authored Feb 27, 2025
1 parent d8ac5ae commit eb4099d
Show file tree
Hide file tree
Showing 5 changed files with 11 additions and 14 deletions.
5 changes: 3 additions & 2 deletions internal/storage/azure/azure.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"errors"
"fmt"
"os"
"path"
"path/filepath"
"strings"
"sync"
Expand Down Expand Up @@ -128,7 +129,7 @@ func (b *azureBlobStorage) Copy(file string) error {
_, err = b.client.UploadStream(
context.Background(),
b.containerName,
filepath.Join(b.DestinationPath, filepath.Base(file)),
path.Join(b.DestinationPath, filepath.Base(file)),
fileReader,
b.uploadStreamOptions,
)
Expand All @@ -141,7 +142,7 @@ func (b *azureBlobStorage) Copy(file string) error {
// Prune rotates away backups according to the configuration and provided
// deadline for the Azure Blob storage backend.
func (b *azureBlobStorage) Prune(deadline time.Time, pruningPrefix string) (*storage.PruneStats, error) {
lookupPrefix := filepath.Join(b.DestinationPath, pruningPrefix)
lookupPrefix := path.Join(b.DestinationPath, pruningPrefix)
pager := b.client.NewListBlobsFlatPager(b.containerName, &container.ListBlobsFlatOptions{
Prefix: &lookupPrefix,
})
Expand Down
5 changes: 2 additions & 3 deletions internal/storage/dropbox/dropbox.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"net/url"
"os"
"path"
"path/filepath"
"strings"
"sync"
"time"
Expand Down Expand Up @@ -195,7 +194,7 @@ loop:
_, err = b.client.UploadSessionFinish(
files.NewUploadSessionFinishArg(
files.NewUploadSessionCursor(sessionId, 0),
files.NewCommitInfo(filepath.Join(b.DestinationPath, name)),
files.NewCommitInfo(path.Join(b.DestinationPath, name)),
), nil)
if err != nil {
return errwrap.Wrap(err, "error finishing the upload session")
Expand Down Expand Up @@ -247,7 +246,7 @@ func (b *dropboxStorage) Prune(deadline time.Time, pruningPrefix string) (*stora

pruneErr := b.DoPrune(b.Name(), len(matches), lenCandidates, deadline, func() error {
for _, match := range matches {
if _, err := b.client.DeleteV2(files.NewDeleteArg(filepath.Join(b.DestinationPath, match.Name))); err != nil {
if _, err := b.client.DeleteV2(files.NewDeleteArg(path.Join(b.DestinationPath, match.Name))); err != nil {
return errwrap.Wrap(err, "error removing file from Dropbox storage")
}
}
Expand Down
5 changes: 2 additions & 3 deletions internal/storage/s3/s3.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (
"fmt"
"os"
"path"
"path/filepath"
"time"

"github.com/minio/minio-go/v7"
Expand Down Expand Up @@ -124,7 +123,7 @@ func (b *s3Storage) Copy(file string) error {
putObjectOptions.PartSize = uint64(partSize)
}

if _, err := b.client.FPutObject(context.Background(), b.bucket, filepath.Join(b.DestinationPath, name), file, putObjectOptions); err != nil {
if _, err := b.client.FPutObject(context.Background(), b.bucket, path.Join(b.DestinationPath, name), file, putObjectOptions); err != nil {
if errResp := minio.ToErrorResponse(err); errResp.Message != "" {
return errwrap.Wrap(
nil,
Expand All @@ -147,7 +146,7 @@ func (b *s3Storage) Copy(file string) error {
// Prune rotates away backups according to the configuration and provided deadline for the S3/Minio storage backend.
func (b *s3Storage) Prune(deadline time.Time, pruningPrefix string) (*storage.PruneStats, error) {
candidates := b.client.ListObjects(context.Background(), b.bucket, minio.ListObjectsOptions{
Prefix: filepath.Join(b.DestinationPath, pruningPrefix),
Prefix: path.Join(b.DestinationPath, pruningPrefix),
Recursive: true,
})

Expand Down
5 changes: 2 additions & 3 deletions internal/storage/ssh/ssh.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
"io"
"os"
"path"
"path/filepath"
"strings"
"time"

Expand Down Expand Up @@ -115,7 +114,7 @@ func (b *sshStorage) Copy(file string) error {
}
defer source.Close()

destination, err := b.sftpClient.Create(filepath.Join(b.DestinationPath, name))
destination, err := b.sftpClient.Create(path.Join(b.DestinationPath, name))
if err != nil {
return errwrap.Wrap(err, "error creating file")
}
Expand Down Expand Up @@ -180,7 +179,7 @@ func (b *sshStorage) Prune(deadline time.Time, pruningPrefix string) (*storage.P

pruneErr := b.DoPrune(b.Name(), len(matches), len(candidates), deadline, func() error {
for _, match := range matches {
if err := b.sftpClient.Remove(filepath.Join(b.DestinationPath, match)); err != nil {
if err := b.sftpClient.Remove(path.Join(b.DestinationPath, match)); err != nil {
return errwrap.Wrap(err, "error removing file")
}
}
Expand Down
5 changes: 2 additions & 3 deletions internal/storage/webdav/webdav.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (
"net/http"
"os"
"path"
"path/filepath"
"strings"
"time"

Expand Down Expand Up @@ -77,7 +76,7 @@ func (b *webDavStorage) Copy(file string) error {
return errwrap.Wrap(err, "error opening the file to be uploaded")
}

if err := b.client.WriteStream(filepath.Join(b.DestinationPath, name), r, 0644); err != nil {
if err := b.client.WriteStream(path.Join(b.DestinationPath, name), r, 0644); err != nil {
return errwrap.Wrap(err, "error uploading the file")
}
b.Log(storage.LogLevelInfo, b.Name(), "Uploaded a copy of backup '%s' to '%s' at path '%s'.", file, b.url, b.DestinationPath)
Expand Down Expand Up @@ -110,7 +109,7 @@ func (b *webDavStorage) Prune(deadline time.Time, pruningPrefix string) (*storag

pruneErr := b.DoPrune(b.Name(), len(matches), lenCandidates, deadline, func() error {
for _, match := range matches {
if err := b.client.Remove(filepath.Join(b.DestinationPath, match.Name())); err != nil {
if err := b.client.Remove(path.Join(b.DestinationPath, match.Name())); err != nil {
return errwrap.Wrap(err, "error removing file")
}
}
Expand Down

0 comments on commit eb4099d

Please sign in to comment.