ronantakizawa/codereview-bench huggingface dataset:
Repository: syncthing/syncthing
File: lib/beacon/broadcast.go (Go)

Code before:
}

func writeBroadcasts(ctx context.Context, inbox <-chan []byte, port int) error {
	conn, err := net.ListenUDP("udp4", nil)
	if err != nil {
		l.Debugln(err)
		return err
	}
	doneCtx, cancel := context.WithCancel(ctx)
	defer cancel()
	go func() {
		<-doneCtx.Done()
		conn.Close()
	}()

	for {
		var bs []byte
		select {
		case bs = <-inbox:
		case <-doneCtx.Done():
			return doneCtx.Err()
		}

		intfs, err := net.Interfaces()
		if err != nil {
			l.Debugln("Failed to list interfaces", err)
			// net.Interfaces() is broken on Android. see https://github.com/golang/go/issues/40569
			// Use the general broadcast address 255.255.255.255 instead.
		}

		var dsts []net.IP
		for _, intf := range intfs {
			if intf.Flags&net.FlagRunning == 0 || intf.Flags&net.FlagBroadcast == 0 {
				continue
			}

			addrs, err := intf.Addrs()
			if err != nil {
				l.Debugln("Failed to list interface addresses", err)
				// Interface discovery might work while retrieving the addresses doesn't. So log the error and carry on.
				continue
			}

			for _, addr := range addrs {
				if iaddr, ok := addr.(*net.IPNet); ok && len(iaddr.IP) >= 4 && iaddr.IP.IsGlobalUnicast() && iaddr.IP.To4() != nil {
					baddr := bcast(iaddr)
					dsts = append(dsts, baddr.IP)
				}
			}
		}


Review comment (bug):
```suggestion
			l.Debugln("Failed to list interfaces:", err)
```

Code after:
}

func writeBroadcasts(ctx context.Context, inbox <-chan []byte, port int) error {
	conn, err := net.ListenUDP("udp4", nil)
	if err != nil {
		l.Debugln(err)
		return err
	}
	doneCtx, cancel := context.WithCancel(ctx)
	defer cancel()
	go func() {
		<-doneCtx.Done()
		conn.Close()
	}()

	for {
		var bs []byte
		select {
		case bs = <-inbox:
		case <-doneCtx.Done():
			return doneCtx.Err()
		}

		intfs, err := net.Interfaces()
		if err != nil {
			l.Debugln("Failed to list interfaces:", err)
			// net.Interfaces() is broken on Android. see https://github.com/golang/go/issues/40569
			// Use the general broadcast address 255.255.255.255 instead.
		}

		var dsts []net.IP
		for _, intf := range intfs {
			if intf.Flags&net.FlagRunning == 0 || intf.Flags&net.FlagBroadcast == 0 {
				continue
			}

			addrs, err := intf.Addrs()
			if err != nil {
				l.Debugln("Failed to list interface addresses:", err)
				// Interface discovery might work while retrieving the addresses doesn't. So log the error and carry on.
				continue
			}

			for _, addr := range addrs {
				if iaddr, ok := addr.(*net.IPNet); ok && len(iaddr.IP) >= 4 && iaddr.IP.IsGlobalUnicast() && iaddr.IP.To4() != nil {
					baddr := bcast(iaddr)
					dsts = append(dsts, baddr.IP)
				}
			}
		}
Repository: syncthing/syncthing
File: lib/beacon/broadcast.go (Go)

Code before:
	}()

	for {
		var bs []byte
		select {
		case bs = <-inbox:
		case <-doneCtx.Done():
			return doneCtx.Err()
		}

		intfs, err := net.Interfaces()
		if err != nil {
			l.Debugln("Failed to list interfaces", err)
			// net.Interfaces() is broken on Android. see https://github.com/golang/go/issues/40569
			// Use the general broadcast address 255.255.255.255 instead.
		}

		var dsts []net.IP
		for _, intf := range intfs {
			if intf.Flags&net.FlagRunning == 0 || intf.Flags&net.FlagBroadcast == 0 {
				continue
			}

			addrs, err := intf.Addrs()
			if err != nil {
				l.Debugln("Failed to list interface addresses", err)
				// Interface discovery might work while retrieving the addresses doesn't. So log the error and carry on.
				continue
			}

			for _, addr := range addrs {
				if iaddr, ok := addr.(*net.IPNet); ok && len(iaddr.IP) >= 4 && iaddr.IP.IsGlobalUnicast() && iaddr.IP.To4() != nil {
					baddr := bcast(iaddr)
					dsts = append(dsts, baddr.IP)
				}
			}
		}

		if len(dsts) == 0 {
			// Fall back to the general IPv4 broadcast address
			dsts = append(dsts, net.IP{0xff, 0xff, 0xff, 0xff})
		}

		l.Debugln("addresses:", dsts)

		success := 0
		for _, ip := range dsts {
			dst := &net.UDPAddr{IP: ip, Port: port}

			conn.SetWriteDeadline(time.Now().Add(time.Second))
			_, err = conn.WriteTo(bs, dst)

Review comment (bug):
```suggestion
				l.Debugln("Failed to list interface addresses:", err)
```

Code after:
	}()

	for {
		var bs []byte
		select {
		case bs = <-inbox:
		case <-doneCtx.Done():
			return doneCtx.Err()
		}

		intfs, err := net.Interfaces()
		if err != nil {
			l.Debugln("Failed to list interfaces:", err)
			// net.Interfaces() is broken on Android. see https://github.com/golang/go/issues/40569
			// Use the general broadcast address 255.255.255.255 instead.
		}

		var dsts []net.IP
		for _, intf := range intfs {
			if intf.Flags&net.FlagRunning == 0 || intf.Flags&net.FlagBroadcast == 0 {
				continue
			}

			addrs, err := intf.Addrs()
			if err != nil {
				l.Debugln("Failed to list interface addresses:", err)
				// Interface discovery might work while retrieving the addresses doesn't. So log the error and carry on.
				continue
			}

			for _, addr := range addrs {
				if iaddr, ok := addr.(*net.IPNet); ok && len(iaddr.IP) >= 4 && iaddr.IP.IsGlobalUnicast() && iaddr.IP.To4() != nil {
					baddr := bcast(iaddr)
					dsts = append(dsts, baddr.IP)
				}
			}
		}

		if len(dsts) == 0 {
			// Fall back to the general IPv4 broadcast address
			dsts = append(dsts, net.IP{0xff, 0xff, 0xff, 0xff})
		}

		l.Debugln("addresses:", dsts)

		success := 0
		for _, ip := range dsts {
			dst := &net.UDPAddr{IP: ip, Port: port}

			conn.SetWriteDeadline(time.Now().Add(time.Second))
			_, err = conn.WriteTo(bs, dst)
Repository: syncthing/syncthing
File: lib/discover/local.go (Go)

Code before:
		})
	}

	return isNewDevice
}

// filterUndialableLocal returns the list of addresses after removing any
// localhost, multicast, broadcast or port-zero addresses.
func filterUndialableLocal(addrs []string) []string {
	filtered := addrs[:0]
	for _, addr := range addrs {
		u, err := url.Parse(addr)
		if err != nil {
			continue
		}

		tcpAddr, err := net.ResolveTCPAddr("tcp", u.Host)
		if err != nil {
			continue
		}

		switch {
		case len(tcpAddr.IP) == 0:
		case tcpAddr.Port == 0:
		case !tcpAddr.IP.IsGlobalUnicast() && !tcpAddr.IP.IsLinkLocalUnicast() && !tcpAddr.IP.IsUnspecified():
		default:
			filtered = append(filtered, addr)
		}
	}
	return filtered
}

func sanitizeRelayAddresses(addrs []string) []string {
	filtered := addrs[:0]
	allowlist := []string{"id"}

	for _, addr := range addrs {
		u, err := url.Parse(addr)
		if err != nil {
			continue
		}

		if u.Scheme == "relay" {
			s := url.Values{}
			q := u.Query()

			for _, w := range allowlist {
				if q.Has(w) {
					s.Add(w, q.Get(w))
				}
			}

Review comment (suggestion):
```suggestion
		case tcpAddr.IP.IsGlobalUnicast(), tcpAddr.IP.IsLinkLocalUnicast(), tcpAddr.IP.IsUnspecified():
```

let's use a positive expression instead

Code after:
		})
	}

	return isNewDevice
}

// filterUndialableLocal returns the list of addresses after removing any
// localhost, multicast, broadcast or port-zero addresses.
func filterUndialableLocal(addrs []string) []string {
	filtered := addrs[:0]
	for _, addr := range addrs {
		u, err := url.Parse(addr)
		if err != nil {
			continue
		}

		tcpAddr, err := net.ResolveTCPAddr("tcp", u.Host)
		if err != nil {
			continue
		}

		switch {
		case len(tcpAddr.IP) == 0:
		case tcpAddr.Port == 0:
		case tcpAddr.IP.IsGlobalUnicast(), tcpAddr.IP.IsLinkLocalUnicast(), tcpAddr.IP.IsUnspecified():
			filtered = append(filtered, addr)
		}
	}
	return filtered
}

func sanitizeRelayAddresses(addrs []string) []string {
	filtered := addrs[:0]
	allowlist := []string{"id"}

	for _, addr := range addrs {
		u, err := url.Parse(addr)
		if err != nil {
			continue
		}

		if u.Scheme == "relay" {
			s := url.Values{}
			q := u.Query()

			for _, w := range allowlist {
				if q.Has(w) {
					s.Add(w, q.Get(w))
				}
			}
Repository: syncthing/syncthing
File: lib/connections/service.go (Go)

Code before:

	if ip.IsLoopback() {
		return true
	}

	if ip.IsLinkLocalUnicast() {
		return true
	}

	for _, lan := range s.cfg.Options().AlwaysLocalNets {
		_, ipnet, err := net.ParseCIDR(lan)
		if err != nil {
			l.Debugln("Network", lan, "is malformed:", err)
			continue
		}
		if ipnet.Contains(ip) {
			return true
		}
	}

	lans, err := osutil.GetLans()

	if err != nil {
		l.Debugln("Failed to retrieve interface IPs:", err)
		return ip.IsPrivate()
	}

	for _, lan := range lans {
		if lan.Contains(ip) {
			return true
		}
	}

	return false
}

func (s *service) createListener(factory listenerFactory, uri *url.URL) bool {
	// must be called with listenerMut held

	l.Debugln("Starting listener", uri)

	listener := factory.New(uri, s.cfg, s.tlsCfg, s.conns, s.natService, s.registry, s.lanChecker)
	listener.OnAddressesChanged(s.logListenAddressesChangedEvent)

	// Retrying a listener many times in rapid succession is unlikely to help,
	// thus back off quickly. A listener may soon be functional again, e.g. due
	// to a network interface coming back online - retry every minute.
	spec := svcutil.SpecWithInfoLogger(l)
	spec.FailureThreshold = 2
	spec.FailureBackoff = time.Minute
	sup := suture.New(fmt.Sprintf("listenerSupervisor@%v", listener), spec)

Review comment (bug):
```suggestion
	lans, err := osutil.GetLans()
	if err != nil {
		l.Debugln("Failed to retrieve interface IPs:", err)
		priv := ip.IsPrivate()
		l.Debugf("Assuming isLAN=%v for IP %v", priv, ip)
		return priv
	}
```

Code after:

	if ip.IsLoopback() {
		return true
	}

	if ip.IsLinkLocalUnicast() {
		return true
	}

	for _, lan := range s.cfg.Options().AlwaysLocalNets {
		_, ipnet, err := net.ParseCIDR(lan)
		if err != nil {
			l.Debugln("Network", lan, "is malformed:", err)
			continue
		}
		if ipnet.Contains(ip) {
			return true
		}
	}

	lans, err := osutil.GetLans()
	if err != nil {
		l.Debugln("Failed to retrieve interface IPs:", err)
		priv := ip.IsPrivate()
		l.Debugf("Assuming isLAN=%v for IP %v", priv, ip)
		return priv
	}

	for _, lan := range lans {
		if lan.Contains(ip) {
			return true
		}
	}

	return false
}

func (s *service) createListener(factory listenerFactory, uri *url.URL) bool {
	// must be called with listenerMut held

	l.Debugln("Starting listener", uri)

	listener := factory.New(uri, s.cfg, s.tlsCfg, s.conns, s.natService, s.registry, s.lanChecker)
	listener.OnAddressesChanged(s.logListenAddressesChangedEvent)

	// Retrying a listener many times in rapid succession is unlikely to help,
	// thus back off quickly. A listener may soon be functional again, e.g. due
	// to a network interface coming back online - retry every minute.
	spec := svcutil.SpecWithInfoLogger(l)
	spec.FailureThreshold = 2
	spec.FailureBackoff = time.Minute
Repository: syncthing/syncthing
File: lib/api/api_auth.go (Go)

Code before:
	"net/http"
	"strings"
	"time"

	ldap "github.com/go-ldap/ldap/v3"
	"github.com/syncthing/syncthing/lib/config"
	"github.com/syncthing/syncthing/lib/events"
	"github.com/syncthing/syncthing/lib/rand"
	"github.com/syncthing/syncthing/lib/sync"
	"golang.org/x/exp/slices"
)

var (
	sessions    = make(map[string]bool)
	sessionsMut = sync.NewMutex()
)

func emitLoginAttempt(success bool, username, address string, evLogger events.Logger) {
	evLogger.Log(events.LoginAttempt, map[string]interface{}{
		"success":       success,
		"username":      username,
		"remoteAddress": address,
	})
	if !success {
		l.Infof("Wrong credentials supplied during API authorization from %s", address)
		antiBruteForceSleep()
	}
}

func antiBruteForceSleep() {
	time.Sleep(time.Duration(rand.Intn(100)+100) * time.Millisecond)
}

func unauthorized(w http.ResponseWriter) {
	w.Header().Set("WWW-Authenticate", "Basic realm=\"Authorization Required\"")
	http.Error(w, "Not Authorized", http.StatusUnauthorized)
}

func forbidden(w http.ResponseWriter) {
	http.Error(w, "Forbidden", http.StatusForbidden)
}

func isNoAuthPath(path string) bool {
	// Local variable instead of module var to prevent accidental mutation
	noAuthPaths := []string{
		"/",
		"/index.html",
		"/modal.html",
		"/rest/svc/lang", // Required to load language settings on login page
	}


Review comment (suggestion):
This change is less obvious in the overall diff, but it's clearer in the https://github.com/syncthing/syncthing/pull/9159/commits/e15b862d3819278aebdbd6ddb530deb9825f7ed6 commit that every invocation of `emitLoginAttempt(false, ...)` was accompanied by an `antiBruteForceSleep()` call, and `antiBruteForceSleep()` was called nowhere else.

Code after:
	"net/http"
	"strings"
	"time"

	ldap "github.com/go-ldap/ldap/v3"
	"github.com/syncthing/syncthing/lib/config"
	"github.com/syncthing/syncthing/lib/events"
	"github.com/syncthing/syncthing/lib/rand"
	"github.com/syncthing/syncthing/lib/sync"
	"golang.org/x/exp/slices"
)

var (
	sessions    = make(map[string]bool)
	sessionsMut = sync.NewMutex()
)

func emitLoginAttempt(success bool, username, address string, evLogger events.Logger) {
	evLogger.Log(events.LoginAttempt, map[string]interface{}{
		"success":       success,
		"username":      username,
		"remoteAddress": address,
	})
	if !success {
		l.Infof("Wrong credentials supplied during API authorization from %s", address)
	}
}

func antiBruteForceSleep() {
	time.Sleep(time.Duration(rand.Intn(100)+100) * time.Millisecond)
}

func unauthorized(w http.ResponseWriter) {
	w.Header().Set("WWW-Authenticate", "Basic realm=\"Authorization Required\"")
	http.Error(w, "Not Authorized", http.StatusUnauthorized)
}

func forbidden(w http.ResponseWriter) {
	http.Error(w, "Forbidden", http.StatusForbidden)
}

func isNoAuthPath(path string) bool {
	// Local variable instead of module var to prevent accidental mutation
	noAuthPaths := []string{
		"/",
		"/index.html",
		"/modal.html",
		"/rest/svc/lang", // Required to load language settings on login page
	}

	// Local variable instead of module var to prevent accidental mutation
Repository: syncthing/syncthing
File: lib/fs/basicfs_xattr_unix.go (Go)

Code before:
		if err != nil {
			return nil, fmt.Errorf("Lgetxattr %s %q: %w", path, name, err)
		}
		if size > len(buf) {
			xattrBufPool.Put(buf)
			buf = make([]byte, size)
		}
		size, err = unix.Lgetxattr(path, name, buf)
	}
	if err != nil {
		return nil, fmt.Errorf("Lgetxattr %s %q: %w", path, name, err)
	}

	if size >= len(buf)/4*3 {
		// The buffer is adequately sized (at least three quarters of it is
		// used), return it as-is.
		val := buf
		buf = nil // Don't put it back in the pool.
		return val, nil
	}

	// The buffer is larger than required, copy the data to a new buffer of
	// the correct size. This avoids having lots of 1024-sized allocations
	// sticking around when 24 bytes or whatever would be enough.
	val := make([]byte, size)
	copy(val, buf)
	return val, nil
}

func (f *BasicFilesystem) SetXattr(path string, xattrs []protocol.Xattr, xattrFilter XattrFilter) error {
	// Index the new attribute set.
	xattrsIdx := make(map[string]int)
	for i, xa := range xattrs {
		xattrsIdx[xa.Name] = i
	}

	// Get and index the existing attribute set
	current, err := f.GetXattr(path, xattrFilter)
	if err != nil {
		return fmt.Errorf("set xattrs %s: GetXattr: %w", path, err)
	}
	currentIdx := make(map[string]int)
	for i, xa := range current {
		currentIdx[xa.Name] = i
	}

	path, err = f.rooted(path)
	if err != nil {
		return fmt.Errorf("set xattrs %s: %w", path, err)
	}


Review comment (suggestion):
This is the reason for the lower memory usage, right? And the pool is "just" an additional optimisation for allocations.

Code after:
		if err != nil {
			return nil, fmt.Errorf("Lgetxattr %s %q: %w", path, name, err)
		}
		if size > len(buf) {
			xattrBufPool.Put(buf)
			buf = make([]byte, size)
		}
		size, err = unix.Lgetxattr(path, name, buf)
	}
	if err != nil {
		return nil, fmt.Errorf("Lgetxattr %s %q: %w", path, name, err)
	}

	if size >= len(buf)/4*3 {
		// The buffer is adequately sized (at least three quarters of it is
		// used), return it as-is.
		val := buf[:size]
		buf = nil // Don't put it back in the pool.
		return val, nil
	}

	// The buffer is larger than required, copy the data to a new buffer of
	// the correct size. This avoids having lots of 1024-sized allocations
	// sticking around when 24 bytes or whatever would be enough.
	val := make([]byte, size)
	copy(val, buf)
	return val, nil
}

func (f *BasicFilesystem) SetXattr(path string, xattrs []protocol.Xattr, xattrFilter XattrFilter) error {
	// Index the new attribute set.
	xattrsIdx := make(map[string]int)
	for i, xa := range xattrs {
		xattrsIdx[xa.Name] = i
	}

	// Get and index the existing attribute set
	current, err := f.GetXattr(path, xattrFilter)
	if err != nil {
		return fmt.Errorf("set xattrs %s: GetXattr: %w", path, err)
	}
	currentIdx := make(map[string]int)
	for i, xa := range current {
		currentIdx[xa.Name] = i
	}

	path, err = f.rooted(path)
	if err != nil {
		return fmt.Errorf("set xattrs %s: %w", path, err)
	}
Repository: syncthing/syncthing
File: lib/protocol/deviceid.go (Go)

Code before:
// Copyright (C) 2014 The Protocol Authors.

package protocol

import (
	"bytes"
	"encoding/base32"
	"encoding/binary"
	"errors"
	"fmt"
	"strings"

	"github.com/syncthing/syncthing/lib/sha256"
)

const (
	DeviceIDLength      = 32
	// keep consistent with shortIDStringLength in gui/default/syncthing/app.js
	ShortIDStringLength = 7
)

type (
	DeviceID [DeviceIDLength]byte
	ShortID  uint64
)

var (
	LocalDeviceID  = repeatedDeviceID(0xff)
	GlobalDeviceID = repeatedDeviceID(0xf8)
	EmptyDeviceID  = DeviceID{ /* all zeroes */ }
)

func repeatedDeviceID(v byte) (d DeviceID) {
	for i := range d {
		d[i] = v
	}
	return
}

// NewDeviceID generates a new device ID from the raw bytes of a certificate
func NewDeviceID(rawCert []byte) DeviceID {
	return DeviceID(sha256.Sum256(rawCert))
}


Review comment (bug):
This is the source of the CI failure: The added comment changes the alignment `gofmt -S` expects:

```
=== RUN   TestCheckGoFmt
    gofmt_test.go:39: File ../lib/protocol/deviceid.go is not formatted correctly:
        
        diff ../lib/protocol/deviceid.go.orig ../lib/protocol/deviceid.go
        --- ../lib/protocol/deviceid.go.orig
        +++ ../lib/protocol/deviceid.go
        @@ -14,7 +14,7 @@
         )
         
         const (
        -	DeviceIDLength      = 32
        +	DeviceIDLength = 32
         	// keep consistent with shortIDStringLength in gui/default/syncthing/app.js
         	ShortIDStringLength = 7
         )
--- FAIL: TestCheckGoFmt (1.20s)
```

https://github.com/syncthing/syncthing/actions/runs/7387700143/job/20096964099?pr=9314

Code after:
// Copyright (C) 2014 The Protocol Authors.

package protocol

import (
	"bytes"
	"encoding/base32"
	"encoding/binary"
	"errors"
	"fmt"
	"strings"

	"github.com/syncthing/syncthing/lib/sha256"
)

const (
	DeviceIDLength = 32
	// keep consistent with shortIDStringLength in gui/default/syncthing/app.js
	ShortIDStringLength = 7
)

type (
	DeviceID [DeviceIDLength]byte
	ShortID  uint64
)

var (
	LocalDeviceID  = repeatedDeviceID(0xff)
	GlobalDeviceID = repeatedDeviceID(0xf8)
	EmptyDeviceID  = DeviceID{ /* all zeroes */ }
)

func repeatedDeviceID(v byte) (d DeviceID) {
	for i := range d {
		d[i] = v
	}
	return
}

// NewDeviceID generates a new device ID from the raw bytes of a certificate
func NewDeviceID(rawCert []byte) DeviceID {
	return DeviceID(sha256.Sum256(rawCert))
}
Repository: syncthing/syncthing
File: lib/ignore/ignore.go (Go)

Code before:

	case file == ".":
		return ignoreresult.NotIgnored
	}

	m.mut.Lock()
	defer m.mut.Unlock()

	if len(m.patterns) == 0 {
		return ignoreresult.NotIgnored
	}

	if m.matches != nil {
		// Check the cache for a known result.
		res, ok := m.matches.get(file)
		if ok {
			return res
		}

		// Update the cache with the result at return time
		defer func() {
			m.matches.set(file, result)
		}()
	}

	// Check all the patterns for a match. Track wether the patterns so far
	// allow skipping matched directories or not. As soon as we hit an
	// exclude pattern (with some exceptions), we can't skip directories
	// anymore.
	file = filepath.ToSlash(file)
	var lowercaseFile string
	canSkipDir := true
	for _, pattern := range m.patterns {
		if canSkipDir && !pattern.allowsSkippingIgnoredDirs() {
			canSkipDir = false
		}

		res := pattern.result
		if canSkipDir {
			res = res.WithSkipDir()
		}
		if pattern.result.IsCaseFolded() {
			if lowercaseFile == "" {
				lowercaseFile = strings.ToLower(file)
			}
			if pattern.match.Match(lowercaseFile) {
				return res
			}
		} else if pattern.match.Match(file) {
			return res
		}

Review comment (suggestion):
```suggestion
	// Check all the patterns for a match. Track whether the patterns so far
```

Code after:

	case file == ".":
		return ignoreresult.NotIgnored
	}

	m.mut.Lock()
	defer m.mut.Unlock()

	if len(m.patterns) == 0 {
		return ignoreresult.NotIgnored
	}

	if m.matches != nil {
		// Check the cache for a known result.
		res, ok := m.matches.get(file)
		if ok {
			return res
		}

		// Update the cache with the result at return time
		defer func() {
			m.matches.set(file, result)
		}()
	}

	// Check all the patterns for a match. Track whether the patterns so far
	// allow skipping matched directories or not. As soon as we hit an
	// exclude pattern (with some exceptions), we can't skip directories
	// anymore.
	file = filepath.ToSlash(file)
	var lowercaseFile string
	canSkipDir := true
	for _, pattern := range m.patterns {
		if canSkipDir && !pattern.allowsSkippingIgnoredDirs() {
			canSkipDir = false
		}

		res := pattern.result
		if canSkipDir {
			res = res.WithSkipDir()
		}
		if pattern.result.IsCaseFolded() {
			if lowercaseFile == "" {
				lowercaseFile = strings.ToLower(file)
			}
			if pattern.match.Match(lowercaseFile) {
				return res
			}
		} else if pattern.match.Match(file) {
			return res
		}
Repository: syncthing/syncthing
File: lib/ignore/ignore.go (Go)

Code before:
func (m *Matcher) parseLocked(r io.Reader, file string) error {
	lines, patterns, err := parseIgnoreFile(m.fs, r, file, m.changeDetector, make(map[string]struct{}))
	// Error is saved and returned at the end. We process the patterns
	// (possibly blank) anyway.

	m.lines = lines

	newHash := hashPatterns(patterns)
	if newHash == m.curHash {
		// We've already loaded exactly these patterns.
		return err
	}

	m.curHash = newHash
	m.patterns = patterns
	if m.withCache {
		m.matches = newCache(patterns)
	}

	return err
}

// Match matches the patterns plus temporary and internal files.
func (m *Matcher) Match(file string) (result ignoreresult.R) {
	switch {
	case !utf8.ValidString(file):
		return ignoreresult.IgnoreAndSkip

	case fs.IsTemporary(file):
		return ignoreresult.IgnoreAndSkip

	case fs.IsInternal(file):
		return ignoreresult.IgnoreAndSkip

	case file == ".":
		return ignoreresult.NotIgnored
	}

	m.mut.Lock()
	defer m.mut.Unlock()

	if len(m.patterns) == 0 {
		return ignoreresult.NotIgnored
	}

	if m.matches != nil {
		// Check the cache for a known result.
		res, ok := m.matches.get(file)
		if ok {
			return res
		}

Review comment (suggestion):
Lets not do this here - except for `lib/fs` that you are also fixing, the input will always be valid utf-8.

Code after:
func (m *Matcher) parseLocked(r io.Reader, file string) error {
	lines, patterns, err := parseIgnoreFile(m.fs, r, file, m.changeDetector, make(map[string]struct{}))
	// Error is saved and returned at the end. We process the patterns
	// (possibly blank) anyway.

	m.lines = lines

	newHash := hashPatterns(patterns)
	if newHash == m.curHash {
		// We've already loaded exactly these patterns.
		return err
	}

	m.curHash = newHash
	m.patterns = patterns
	if m.withCache {
		m.matches = newCache(patterns)
	}

	return err
}

// Match matches the patterns plus temporary and internal files.
func (m *Matcher) Match(file string) (result ignoreresult.R) {
	switch {
	case fs.IsTemporary(file):
		return ignoreresult.IgnoreAndSkip

	case fs.IsInternal(file):
		return ignoreresult.IgnoreAndSkip

	case file == ".":
		return ignoreresult.NotIgnored
	}

	m.mut.Lock()
	defer m.mut.Unlock()

	if len(m.patterns) == 0 {
		return ignoreresult.NotIgnored
	}

	if m.matches != nil {
		// Check the cache for a known result.
		res, ok := m.matches.get(file)
		if ok {
			return res
		}

		// Update the cache with the result at return time
		defer func() {