From 285dcc30cfb8f8e7dd405c4e8b10d129a7e4a7eb Mon Sep 17 00:00:00 2001 From: Jakob Borg Date: Sat, 9 May 2015 21:37:09 +0200 Subject: [PATCH 1/3] Use md5 hash of filename for temporary file (fixes #1786) --- internal/model/tempname.go | 5 ++++- internal/model/tempname_windows.go | 5 ++++- ... => .syncthing.8c7dd922ad47494fc02c388e12c00eac} | Bin ...syncthing~.8c7dd922ad47494fc02c388e12c00eac.tmp} | Bin 4 files changed, 8 insertions(+), 2 deletions(-) rename internal/model/testdata/{.syncthing.file => .syncthing.8c7dd922ad47494fc02c388e12c00eac} (100%) rename internal/model/testdata/{~syncthing~.file.tmp => ~syncthing~.8c7dd922ad47494fc02c388e12c00eac.tmp} (100%) diff --git a/internal/model/tempname.go b/internal/model/tempname.go index 66ae88cf..26be95f3 100644 --- a/internal/model/tempname.go +++ b/internal/model/tempname.go @@ -9,6 +9,7 @@ package model import ( + "crypto/md5" "fmt" "path/filepath" "strings" @@ -25,7 +26,9 @@ func (t tempNamer) IsTemporary(name string) bool { } func (t tempNamer) TempName(name string) string { + hash := md5.New() + hash.Write([]byte(name)) tdir := filepath.Dir(name) - tname := fmt.Sprintf("%s.%s", t.prefix, filepath.Base(name)) + tname := fmt.Sprintf("%s.%x", t.prefix, hash.Sum(nil)) return filepath.Join(tdir, tname) } diff --git a/internal/model/tempname_windows.go b/internal/model/tempname_windows.go index b928acaf..02c9f9f0 100644 --- a/internal/model/tempname_windows.go +++ b/internal/model/tempname_windows.go @@ -9,6 +9,7 @@ package model import ( + "crypto/md5" "fmt" "path/filepath" "strings" @@ -25,7 +26,9 @@ func (t tempNamer) IsTemporary(name string) bool { } func (t tempNamer) TempName(name string) string { + hash := md5.New() + hash.Write([]byte(name)) tdir := filepath.Dir(name) - tname := fmt.Sprintf("%s.%s.tmp", t.prefix, filepath.Base(name)) + tname := fmt.Sprintf("%s.%x.tmp", t.prefix, hash.Sum(nil)) return filepath.Join(tdir, tname) } diff --git a/internal/model/testdata/.syncthing.file b/internal/model/testdata/.syncthing.8c7dd922ad47494fc02c388e12c00eac similarity index 100% rename from internal/model/testdata/.syncthing.file rename to internal/model/testdata/.syncthing.8c7dd922ad47494fc02c388e12c00eac diff --git a/internal/model/testdata/~syncthing~.file.tmp b/internal/model/testdata/~syncthing~.8c7dd922ad47494fc02c388e12c00eac.tmp similarity index 100% rename from internal/model/testdata/~syncthing~.file.tmp rename to internal/model/testdata/~syncthing~.8c7dd922ad47494fc02c388e12c00eac.tmp From a692348336eadd7960cb741e77402f5fc9f7e38e Mon Sep 17 00:00:00 2001 From: Lode Hoste Date: Sun, 10 May 2015 11:56:20 +0200 Subject: [PATCH 2/3] Retain meaningful names for temporary files --- internal/model/tempname.go | 25 +++++++++---- internal/model/tempname_windows.go | 34 ------------------ ...4fc02c388e12c00eac => .syncthing.file.tmp} | Bin ...2c388e12c00eac.tmp => ~syncthing~file.tmp} | Bin 4 files changed, 18 insertions(+), 41 deletions(-) delete mode 100644 internal/model/tempname_windows.go rename internal/model/testdata/{.syncthing.8c7dd922ad47494fc02c388e12c00eac => .syncthing.file.tmp} (100%) rename internal/model/testdata/{~syncthing~.8c7dd922ad47494fc02c388e12c00eac.tmp => ~syncthing~file.tmp} (100%) diff --git a/internal/model/tempname.go b/internal/model/tempname.go index 26be95f3..54a5fd09 100644 --- a/internal/model/tempname.go +++ b/internal/model/tempname.go @@ -1,17 +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" ) @@ -19,16 +18,28 @@ 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) } func (t tempNamer) TempName(name string) string { - hash := md5.New() - hash.Write([]byte(name)) tdir := filepath.Dir(name) - tname := fmt.Sprintf("%s.%x", t.prefix, hash.Sum(nil)) + 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_windows.go b/internal/model/tempname_windows.go deleted file mode 100644 index 02c9f9f0..00000000 --- a/internal/model/tempname_windows.go +++ /dev/null @@ -1,34 +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 ( - "crypto/md5" - "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 { - hash := md5.New() - hash.Write([]byte(name)) - tdir := filepath.Dir(name) - tname := fmt.Sprintf("%s.%x.tmp", t.prefix, hash.Sum(nil)) - return filepath.Join(tdir, tname) -} diff --git a/internal/model/testdata/.syncthing.8c7dd922ad47494fc02c388e12c00eac b/internal/model/testdata/.syncthing.file.tmp similarity index 100% rename from internal/model/testdata/.syncthing.8c7dd922ad47494fc02c388e12c00eac rename to internal/model/testdata/.syncthing.file.tmp diff --git a/internal/model/testdata/~syncthing~.8c7dd922ad47494fc02c388e12c00eac.tmp b/internal/model/testdata/~syncthing~file.tmp similarity index 100% rename from internal/model/testdata/~syncthing~.8c7dd922ad47494fc02c388e12c00eac.tmp rename to internal/model/testdata/~syncthing~file.tmp From a7482a3644796ec9aaa907f7ab582e2d359ee16c Mon Sep 17 00:00:00 2001 From: Lode Hoste Date: Sun, 10 May 2015 11:59:42 +0200 Subject: [PATCH 3/3] Added simple unit test for temporary filenames --- internal/model/tempname_test.go | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 internal/model/tempname_test.go 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")) + } +}