diff --git a/internal/model/tempname.go b/internal/model/tempname.go index 66ae88cf..54a5fd09 100644 --- a/internal/model/tempname.go +++ b/internal/model/tempname.go @@ -1,16 +1,16 @@ -// Copyright (C) 2014 The Syncthing Authors. +// Copyright (C) 2015 The Syncthing Authors. // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this file, // You can obtain one at http://mozilla.org/MPL/2.0/. -// +build !windows - package model import ( + "crypto/md5" "fmt" "path/filepath" + "runtime" "strings" ) @@ -18,7 +18,15 @@ type tempNamer struct { prefix string } -var defTempNamer = tempNamer{".syncthing"} +var defTempNamer tempNamer + +func init() { + if runtime.GOOS == "windows" { + defTempNamer = tempNamer{"~syncthing~"} + } else { + defTempNamer = tempNamer{".syncthing."} + } +} func (t tempNamer) IsTemporary(name string) bool { return strings.HasPrefix(filepath.Base(name), t.prefix) @@ -26,6 +34,12 @@ func (t tempNamer) IsTemporary(name string) bool { func (t tempNamer) TempName(name string) string { tdir := filepath.Dir(name) - tname := fmt.Sprintf("%s.%s", t.prefix, filepath.Base(name)) + tbase := filepath.Base(name) + if len(tbase) > 240 { + hash := md5.New() + hash.Write([]byte(name)) + tbase = fmt.Sprintf("%x", hash.Sum(nil)) + } + tname := fmt.Sprintf("%s%s.tmp", t.prefix, tbase) return filepath.Join(tdir, tname) } diff --git a/internal/model/tempname_test.go b/internal/model/tempname_test.go new file mode 100644 index 00000000..80639304 --- /dev/null +++ b/internal/model/tempname_test.go @@ -0,0 +1,26 @@ +// Copyright (C) 2015 The Syncthing Authors. +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this file, +// You can obtain one at http://mozilla.org/MPL/2.0/. + +package model + +import ( + "strings" + "testing" +) + +func TestLongTempFilename(t *testing.T) { + filename := "" + for i := 0; i < 300; i++ { + filename += "l" + } + tFile := defTempNamer.TempName(filename) + if len(tFile) < 10 || len(tFile) > 200 { + t.Fatal("Invalid long filename") + } + if !strings.HasSuffix(defTempNamer.TempName("short"), "short.tmp") { + t.Fatal("Invalid short filename", defTempNamer.TempName("short")) + } +} diff --git a/internal/model/tempname_windows.go b/internal/model/tempname_windows.go deleted file mode 100644 index b928acaf..00000000 --- a/internal/model/tempname_windows.go +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (C) 2014 The Syncthing Authors. -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this file, -// You can obtain one at http://mozilla.org/MPL/2.0/. - -// +build windows - -package model - -import ( - "fmt" - "path/filepath" - "strings" -) - -type tempNamer struct { - prefix string -} - -var defTempNamer = tempNamer{"~syncthing~"} - -func (t tempNamer) IsTemporary(name string) bool { - return strings.HasPrefix(filepath.Base(name), t.prefix) -} - -func (t tempNamer) TempName(name string) string { - tdir := filepath.Dir(name) - tname := fmt.Sprintf("%s.%s.tmp", t.prefix, filepath.Base(name)) - return filepath.Join(tdir, tname) -} diff --git a/internal/model/testdata/.syncthing.file b/internal/model/testdata/.syncthing.file.tmp similarity index 100% rename from internal/model/testdata/.syncthing.file rename to internal/model/testdata/.syncthing.file.tmp diff --git a/internal/model/testdata/~syncthing~.file.tmp b/internal/model/testdata/~syncthing~file.tmp similarity index 100% rename from internal/model/testdata/~syncthing~.file.tmp rename to internal/model/testdata/~syncthing~file.tmp