Skip to content

Commit

Permalink
fix: cp and mirror commands fail to be executed when the file length …
Browse files Browse the repository at this point in the history
…is 255 characters (#5114)
  • Loading branch information
dormanze authored Jan 21, 2025
1 parent cc8758c commit 0019b7b
Showing 1 changed file with 57 additions and 4 deletions.
61 changes: 57 additions & 4 deletions cmd/client-fs.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ import (
"syscall"
"time"

"github.com/google/uuid"

"github.com/pkg/xattr"
"github.com/rjeczalik/notify"

Expand Down Expand Up @@ -301,8 +303,12 @@ func (f *fsClient) put(_ context.Context, reader io.Reader, size int64, progress

objectPath := f.PathURL.Path

// Write to a temporary file "object.part.minio" before commit.
objectPartPath := objectPath + partSuffix
if err := checkPathLength(objectPath); err != nil {
return 0, err
}

// Write to a temporary file "objectpath/uuid" before commit.
objectPartPath := filepath.Join(filepath.Dir(objectPath), uuid.NewString())

// We cannot resume this operation, then we
// should remove any partial download if any.
Expand Down Expand Up @@ -393,6 +399,49 @@ func (f *fsClient) Put(ctx context.Context, reader io.Reader, size int64, progre
return f.put(ctx, reader, size, progress, opts)
}

// checkPathLength - returns error if given path name length more than 255
func checkPathLength(pathName string) *probe.Error {
// Apple OS X path length is limited to 1016
if runtime.GOOS == "darwin" && len(pathName) > 1016 {
return probe.NewError(errors.New("file name too long"))
}

// Disallow more than 32,767 characters on windows, there
// are no known name_max limits on Windows.
// Refer: https://learn.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation?tabs=registry
if runtime.GOOS == "windows" && len(pathName) > 32767 {
return probe.NewError(errors.New("file name too long"))
}

// On Unix we reject paths if they are just '.', '..' or '/'
if pathName == "." || pathName == ".." || pathName == "/" {
return probe.NewError(errors.New("file access denied"))
}

// Check each path segment length is > 255 on all Unix
// platforms, look for this value as NAME_MAX in
// /usr/include/linux/limits.h
var count int64
for _, p := range pathName {
switch p {
case '/':
count = 0 // Reset
case '\\':
if runtime.GOOS == "windows" {
count = 0
} else {
count++
}
default:
count++
}
if count > 255 {
return probe.NewError(errors.New("file name too long"))
}
} // Success.
return nil
}

func (f *fsClient) putN(_ context.Context, reader io.Reader, size int64, progress io.Reader, opts PutOptions) (int64, *probe.Error) {
// ContentType is not handled on purpose.
// For filesystem this is a redundant information.
Expand All @@ -415,8 +464,12 @@ func (f *fsClient) putN(_ context.Context, reader io.Reader, size int64, progres

objectPath := f.PathURL.Path

// Write to a temporary file "object.part.minio" before commit.
objectPartPath := objectPath + partSuffix
if err := checkPathLength(objectPath); err != nil {
return 0, err
}

// Write to a temporary file ""objectpath/uuid"" before commit.
objectPartPath := filepath.Join(filepath.Dir(objectPath), uuid.NewString())

// We cannot resume this operation, then we
// should remove any partial download if any.
Expand Down

0 comments on commit 0019b7b

Please sign in to comment.