fix: avoid error file name too long when writing a file (#4876)

This commit is contained in:
Konstantin Lebedev 2023-09-27 17:40:51 +05:00 committed by GitHub
parent 9d589b48e6
commit 44906f1f3b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 43 additions and 4 deletions

View file

@ -99,7 +99,7 @@ func runFilerReplicate(cmd *Command, args []string) bool {
if m.OldEntry != nil && m.NewEntry == nil {
glog.V(1).Infof("delete: %s", key)
} else if m.OldEntry == nil && m.NewEntry != nil {
glog.V(1).Infof(" add: %s", key)
glog.V(1).Infof("add: %s", key)
} else {
glog.V(1).Infof("modify: %s", key)
}

View file

@ -90,7 +90,7 @@ func (localsink *LocalSink) CreateEntry(key string, entry *filer_pb.Entry, signa
return os.Mkdir(key, os.FileMode(entry.Attributes.FileMode))
}
dstFile, err := os.OpenFile(key, os.O_RDWR|os.O_CREATE|os.O_TRUNC, os.FileMode(entry.Attributes.FileMode))
dstFile, err := os.OpenFile(util.ToShortFileName(key), os.O_RDWR|os.O_CREATE|os.O_TRUNC, os.FileMode(entry.Attributes.FileMode))
if err != nil {
return err
}

View file

@ -1,16 +1,20 @@
package util
import (
"bytes"
"crypto/sha256"
"errors"
"fmt"
"github.com/seaweedfs/seaweedfs/weed/glog"
"os"
"os/user"
"path/filepath"
"strings"
"time"
"github.com/seaweedfs/seaweedfs/weed/glog"
)
const maxFilenameLength = 255
func TestFolderWritable(folder string) (err error) {
fileInfo, err := os.Stat(folder)
if err != nil {
@ -106,6 +110,19 @@ func FileNameBase(filename string) string {
return filename[:lastDotIndex]
}
func ToShortFileName(path string) string {
fileName := filepath.Base(path)
if fileNameBytes := []byte(fileName); len(fileNameBytes) > maxFilenameLength {
shaStr := fmt.Sprintf("%x", sha256.Sum256(fileNameBytes))
fileNameBase := FileNameBase(fileName)
fileExt := fileName[len(fileNameBase):]
fileNameBaseBates := bytes.ToValidUTF8([]byte(fileNameBase)[:maxFilenameLength-len([]byte(fileExt))-8], []byte{})
shortFileName := string(fileNameBaseBates) + shaStr[len(shaStr)-8:]
return filepath.Join(filepath.Dir(path), shortFileName) + fileExt
}
return path
}
// Copied from os.WriteFile(), adding file sync.
// see https://github.com/golang/go/issues/20599
func WriteFile(name string, data []byte, perm os.FileMode) error {

View file

@ -0,0 +1,22 @@
package util
import (
"testing"
)
func TestToShortFileName(t *testing.T) {
tests := []struct {
in string
value string
}{
{"/data/a/b/c/d.txt", "/data/a/b/c/d.txt"},
{"/data/a/b/c/очень_длинное_имя_файла_c_подробным_указанием_наименования_и_содержания_стандартизованныхорм_за_анварь_-_июнь_2023_года(РОГА_И_КОПЫТА_ООО).txt", "/data/a/b/c/очень_длинное_имя_файла_c_подробным_указанием_наименования_и_содержания_стандартизованныхорм_за_анварь_-_июнь_2023_года(РОГА_И_КОПЫТ354fcaf4.txt"},
{"/data/a/b/c/очень_длинное_имя_файла_c_подробным_указанием_наименования_и_содержания_стандартизованныхорм_за_анварь_-_июнь_2023_года(РОГА_И_КОПЫТА_ООО)_without_extension", "/data/a/b/c/очень_длинное_имя_файла_c_подробным_указанием_наименования_и_содержания_стандартизованныхорм_за_анварь_-_июнь_2023_года(РОГА_И_КОПЫТА_О21a6e47a"},
}
for _, p := range tests {
got := ToShortFileName(p.in)
if got != p.value {
t.Errorf("failed to test: got %v, want %v", got, p.value)
}
}
}