In ignores, normalize the input when parsing it. When scanning, normalize earlier such that the path is already normalized when checking ignores. This requires splitting normalization of the string from normalization of the file, as we don't want to attempt the latter if the file is ignored. Closes #9598 --------- Co-authored-by: Jakob Borg <jakob@kastelo.net>
This commit is contained in:
@@ -18,7 +18,9 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/gobwas/glob"
|
||||
"golang.org/x/text/unicode/norm"
|
||||
|
||||
"github.com/syncthing/syncthing/lib/build"
|
||||
"github.com/syncthing/syncthing/lib/fs"
|
||||
"github.com/syncthing/syncthing/lib/ignore/ignoreresult"
|
||||
"github.com/syncthing/syncthing/lib/osutil"
|
||||
@@ -212,6 +214,11 @@ func (m *Matcher) parseLocked(r io.Reader, file string) error {
|
||||
}
|
||||
|
||||
// Match matches the patterns plus temporary and internal files.
|
||||
//
|
||||
// The "file" parameter must be in the OS' native unicode format (NFD on macos,
|
||||
// NFC everywhere else). This is always the case in real usage in syncthing, as
|
||||
// we ensure native unicode normalisation on all entry points (scanning and from
|
||||
// protocol) - so no need to normalize when calling this, except e.g. in tests.
|
||||
func (m *Matcher) Match(file string) (result ignoreresult.R) {
|
||||
switch {
|
||||
case fs.IsTemporary(file):
|
||||
@@ -387,6 +394,10 @@ func loadParseIncludeFile(filesystem fs.Filesystem, file string, cd ChangeDetect
|
||||
}
|
||||
|
||||
func parseLine(line string) ([]Pattern, error) {
|
||||
// We use native normalization internally, thus the patterns must match
|
||||
// that to avoid false negative matches.
|
||||
line = nativeUnicodeNorm(line)
|
||||
|
||||
pattern := Pattern{
|
||||
result: ignoreresult.Ignored,
|
||||
}
|
||||
@@ -464,6 +475,13 @@ func parseLine(line string) ([]Pattern, error) {
|
||||
return patterns, nil
|
||||
}
|
||||
|
||||
func nativeUnicodeNorm(s string) string {
|
||||
if build.IsDarwin || build.IsIOS {
|
||||
return norm.NFD.String(s)
|
||||
}
|
||||
return norm.NFC.String(s)
|
||||
}
|
||||
|
||||
func parseIgnoreFile(fs fs.Filesystem, fd io.Reader, currentFile string, cd ChangeDetector, linesSeen map[string]struct{}) ([]string, []Pattern, error) {
|
||||
var patterns []Pattern
|
||||
|
||||
|
||||
@@ -805,7 +805,10 @@ func TestIssue3174(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !pats.Match("åäö").IsIgnored() {
|
||||
// The pattern above is normalized when parsing, and in order for this
|
||||
// string to match the pattern, it needs to use the same normalization. And
|
||||
// Go always uses NFC regardless of OS, while we use NFD on macos.
|
||||
if !pats.Match(nativeUnicodeNorm("åäö")).IsIgnored() {
|
||||
t.Error("Should match")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user