lib/model: Harden sanitizePath (#6533)

In particular, non-printable runes and non-UTF8 sequences are no longer
allowed. Linux systems will happily creates filenames containing these.
This commit is contained in:
greatroar
2020-04-14 20:26:26 +02:00
committed by GitHub
parent 82fbcb96f8
commit 81ff31b8fc
2 changed files with 49 additions and 5 deletions
+27
View File
@@ -24,6 +24,8 @@ import (
"sync/atomic"
"testing"
"time"
"unicode"
"unicode/utf8"
"github.com/syncthing/syncthing/lib/config"
"github.com/syncthing/syncthing/lib/db"
@@ -3306,6 +3308,9 @@ func TestSanitizePath(t *testing.T) {
{`Räk \/ smörgås`, "Räk smörgås"},
{"هذا هو *\x07?اسم الملف", "هذا هو اسم الملف"},
{`../foo.txt`, `.. foo.txt`},
{" \t \n filename in \t space\r", "filename in space"},
{"你\xff好", `你 好`},
{"\000 foo", "foo"},
}
for _, tc := range cases {
@@ -3316,6 +3321,28 @@ func TestSanitizePath(t *testing.T) {
}
}
// Fuzz test: sanitizePath must always return strings of printable UTF-8
// characters when fed random data.
//
// Note that space is considered printable, but other whitespace runes are not.
func TestSanitizePathFuzz(t *testing.T) {
buf := make([]byte, 128)
for i := 0; i < 100; i++ {
rand.Read(buf)
path := sanitizePath(string(buf))
if !utf8.ValidString(path) {
t.Errorf("sanitizePath(%q) => %q, not valid UTF-8", buf, path)
continue
}
for _, c := range path {
if !unicode.IsPrint(c) {
t.Errorf("non-printable rune %q in sanitized path", c)
}
}
}
}
// TestConnCloseOnRestart checks that there is no deadlock when calling Close
// on a protocol connection that has a blocking reader (blocking writer can't
// be done as the test requires clusterconfigs to go through).