diff --git a/src/croc/croc.go b/src/croc/croc.go index 9410339..7c2f193 100644 --- a/src/croc/croc.go +++ b/src/croc/croc.go @@ -1209,8 +1209,7 @@ func (c *Client) processMessageFileInfo(m message.Message) (done bool, err error if strings.Contains(c.FilesToTransfer[i].FolderRemote, ".ssh") { return true, fmt.Errorf("invalid path detected: '%s'", fi.FolderRemote) } - // Issue #595 - disallow filenames with anything but 0-9a-zA-Z.-_. and / characters - + // Issue #595 - disallow filenames with invisible characters if !utils.ValidFileName(path.Join(c.FilesToTransfer[i].FolderRemote, fi.Name)) { return true, fmt.Errorf("invalid filename detected: '%s'", fi.Name) } diff --git a/src/utils/utils.go b/src/utils/utils.go index 35b9c27..b97e99c 100644 --- a/src/utils/utils.go +++ b/src/utils/utils.go @@ -21,6 +21,7 @@ import ( "path/filepath" "strings" "time" + "unicode" "github.com/cespare/xxhash" "github.com/kalafut/imohash" @@ -485,16 +486,21 @@ func UnzipDirectory(destination string, source string) error { } // ValidFileName checks if a filename is valid -// and returns true only if it all of the characters are either -// 0-9, a-z, A-Z, ., _, -, space, or / +// by making sure it has no invisible characters func ValidFileName(fname string) bool { - for _, r := range fname { - if !((r >= '0' && r <= '9') || - (r >= 'a' && r <= 'z') || - (r >= 'A' && r <= 'Z') || - r == '.' || r == '_' || r == '-' || r == ' ' || r == '/') { - return false + clean1 := strings.Map(func(r rune) rune { + if unicode.IsGraphic(r) { + return r } - } - return true + return -1 + }, fname) + + clean2 := strings.Map(func(r rune) rune { + if unicode.IsPrint(r) { + return r + } + return -1 + }, fname) + + return (fname == clean1) && (fname == clean2) } diff --git a/src/utils/utils_test.go b/src/utils/utils_test.go index f671f1c..ac8b625 100644 --- a/src/utils/utils_test.go +++ b/src/utils/utils_test.go @@ -231,3 +231,10 @@ func TestFindOpenPorts(t *testing.T) { func TestIsLocalIP(t *testing.T) { assert.True(t, IsLocalIP("192.168.0.14:9009")) } + +func TestValidFileName(t *testing.T) { + // contains regular characters + assert.True(t, ValidFileName("中文.csl")) + // contains invisible character + assert.False(t, ValidFileName("D中文.cslouglas​")) +}