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

Code before:
		}
		if info.Name() != "symlink" && info.Name() != "towalk" {
			t.Fatal("Walk unexpected file", info.Name())
		}
		return nil
	}); err != nil {
		t.Fatal(err)
	}
}

func createDirJunct(target string, name string) error {
	output, err := osexec.Command("cmd", "/c", "mklink", "/J", name, target).CombinedOutput()
	if err != nil {
		return fmt.Errorf("Failed to run mklink %v %v: %v %q", name, target, err, output)
	}
	return nil
}

func testWalkTraverseDirJunct(t *testing.T, fsType FilesystemType, uri string) {
	if runtime.GOOS != "windows" {
		t.Skip("Directory junctions are available and tested on windows only")
	}

	fs := NewFilesystem(fsType, uri)

	if err := fs.MkdirAll("target\\foo", 0); err != nil {
		t.Fatal(err)
	}
	if err := fs.Mkdir("towalk", 0); err != nil {
		t.Fatal(err)
	}
	if err := createDirJunct(uri+"\\target", uri+"\\towalk\\dirjunct"); err != nil {
		t.Fatal(err)
	}
	traversed := false
	if err := fs.Walk("towalk", func(path string, info FileInfo, err error) error {
		if err != nil {
			t.Fatal(err)
		}
		if info.Name() == "foo" {
			traversed = true
		}
		return nil
	}); err != nil {
		t.Fatal(err)
	}
	if !traversed {
		t.Fatal("Directory junction was not traversed")
	}
}


Review comment (security):
Please use `path/filepath` for handling paths (i.e. `filepath.Join` or `filepath.Clean`) to make them os-independent, as these tests could in principle also run on non-windows. And generally you can use backticks for quoting, then you don't need to escape backslashes.

Code after:
			t.Fatal(err)
		}
		if info.Name() != "symlink" && info.Name() != "towalk" {
			t.Fatal("Walk unexpected file", info.Name())
		}
		return nil
	}); err != nil {
		t.Fatal(err)
	}
}

func createDirJunct(target string, name string) error {
	output, err := osexec.Command("cmd", "/c", "mklink", "/J", name, target).CombinedOutput()
	if err != nil {
		return fmt.Errorf("Failed to run mklink %v %v: %v %q", name, target, err, output)
	}
	return nil
}

func testWalkTraverseDirJunct(t *testing.T, fsType FilesystemType, uri string) {
	if runtime.GOOS != "windows" {
		t.Skip("Directory junctions are available and tested on windows only")
	}

	fs := NewFilesystem(fsType, uri)

	if err := fs.MkdirAll("target/foo", 0); err != nil {
		t.Fatal(err)
	}
	if err := fs.Mkdir("towalk", 0); err != nil {
		t.Fatal(err)
	}
	if err := createDirJunct(filepath.Join(uri, "target"), filepath.Join(uri, "towalk/dirjunct")); err != nil {
		t.Fatal(err)
	}
	traversed := false
	if err := fs.Walk("towalk", func(path string, info FileInfo, err error) error {
		if err != nil {
			t.Fatal(err)
		}
		if info.Name() == "foo" {
			traversed = true
		}
		return nil
	}); err != nil {
		t.Fatal(err)
	}
	if !traversed {
		t.Fatal("Directory junction was not traversed")
	}
}
Repository: syncthing/syncthing
File: lib/fs/basicfs_fileinfo_unix.go (Go)

Code before:
// Copyright (C) 2017 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 https://mozilla.org/MPL/2.0/.

// +build !windows

package fs

import "syscall"

func (e basicFileInfo) Mode() FileMode {
	return FileMode(e.FileInfo.Mode())
}

func (e basicFileInfo) Owner() int {
	if st, ok := e.Sys().(*syscall.Stat_t); ok {
		return int(st.Uid)
	}
	return -1
}

func (e basicFileInfo) Group() int {
	if st, ok := e.Sys().(*syscall.Stat_t); ok {
		return int(st.Gid)
	}
	return -1
}


Review comment (suggestion):
```suggestion
// osFileInfo converts e to os.FileInfo that is suitable
```

Code after:
package fs

import (
	"os"
	"syscall"
)

func (e basicFileInfo) Mode() FileMode {
	return FileMode(e.FileInfo.Mode())
}

func (e basicFileInfo) Owner() int {
	if st, ok := e.Sys().(*syscall.Stat_t); ok {
		return int(st.Uid)
	}
	return -1
}

func (e basicFileInfo) Group() int {
	if st, ok := e.Sys().(*syscall.Stat_t); ok {
		return int(st.Gid)
	}
	return -1
}

// fileStat converts e to os.FileInfo that is suitable
// to be passed to os.SameFile. Non-trivial on Windows.
func (e *basicFileInfo) osFileInfo() os.FileInfo {
	return e.FileInfo
}
Repository: syncthing/syncthing
File: lib/db/set.go (Go)

Code before:
// This will cause a full index transmission on the next connection.
func DropDeltaIndexIDs(db *Lowlevel) {
	dbi, err := db.NewPrefixIterator([]byte{KeyTypeIndexID})
	if backend.IsClosed(err) {
		return
	} else if err != nil {
		panic(err)
	}
	defer dbi.Release()
	for dbi.Next() {
		if err := db.Delete(dbi.Key()); err != nil && !backend.IsClosed(err) {
			panic(err)
		}
	}
	if err := dbi.Error(); err != nil && !backend.IsClosed(err) {
		panic(err)
	}
}

func normalizeFilenamesAndDropDuplicates(fs []protocol.FileInfo) []protocol.FileInfo {
	positions := make(map[string]int, len(fs))
	newFs := fs[:0]
	for _, f := range fs {
		norm := osutil.NormalizedFilename(f.Name)
		if i, ok := positions[norm]; ok {
			newFs = append(newFs[:i], newFs[i+1:]...)
		}
		positions[norm] = len(newFs)
		f.Name = norm
		newFs = append(newFs, f)
	}
	return newFs
}

func nativeFileIterator(fn Iterator) Iterator {
	return func(fi FileIntf) bool {
		switch f := fi.(type) {
		case protocol.FileInfo:
			f.Name = osutil.NativeFilename(f.Name)
			return fn(f)
		case FileInfoTruncated:
			f.Name = osutil.NativeFilename(f.Name)
			return fn(f)
		default:
			panic("unknown interface type")
		}
	}
}


Review comment (bug):
Problem: this changes the positions of everything after i, so the map is now wrong for those items. Maybe replace the item to be dropped with a sentinel value, and then filter these in a latter stage?

Code after:
// This will cause a full index transmission on the next connection.
func DropDeltaIndexIDs(db *Lowlevel) {
	dbi, err := db.NewPrefixIterator([]byte{KeyTypeIndexID})
	if backend.IsClosed(err) {
		return
	} else if err != nil {
		panic(err)
	}
	defer dbi.Release()
	for dbi.Next() {
		if err := db.Delete(dbi.Key()); err != nil && !backend.IsClosed(err) {
			panic(err)
		}
	}
	if err := dbi.Error(); err != nil && !backend.IsClosed(err) {
		panic(err)
	}
}

func normalizeFilenamesAndDropDuplicates(fs []protocol.FileInfo) []protocol.FileInfo {
	positions := make(map[string]int, len(fs))
	for i, f := range fs {
		norm := osutil.NormalizedFilename(f.Name)
		if pos, ok := positions[norm]; ok {
			fs[pos] = protocol.FileInfo{}
		}
		positions[norm] = i
		fs[i].Name = norm
	}
	for i := 0; i < len(fs); {
		if fs[i].Name == "" {
			fs = append(fs[:i], fs[i+1:]...)
			continue
		}
		i++
	}
	return fs
}

func nativeFileIterator(fn Iterator) Iterator {
	return func(fi FileIntf) bool {
		switch f := fi.(type) {
		case protocol.FileInfo:
			f.Name = osutil.NativeFilename(f.Name)
			return fn(f)
		case FileInfoTruncated:
			f.Name = osutil.NativeFilename(f.Name)
			return fn(f)
		default:
			panic("unknown interface type")
		}
Repository: syncthing/syncthing
File: lib/db/db_test.go (Go)

Code before:
		t.Fatal(err)
	}
	if vl.Versions[0].Deleted {
		t.Error("vl.Versions[0] deleted for c")
	}
	if !vl.Versions[1].Deleted {
		t.Error("vl.Versions[1] not deleted for c")
	}
}

func TestDropDuplicates(t *testing.T) {
	names := []string{
		"foo",
		"bar",
		"dcxvoijnds",
		"3d/dsfase/4/ss2",
	}
	tcs := []struct{ in, out []int }{
		{[]int{0}, []int{0}},
		{[]int{0, 1}, []int{0, 1}},
		{[]int{0, 1, 0, 1}, []int{0, 1}},
		{[]int{0, 1, 1, 1, 1}, []int{0, 1}},
		{[]int{0, 0, 0, 1}, []int{0, 1}},
		{[]int{0, 1, 2, 3}, []int{0, 1, 2, 3}},
		{[]int{0, 1, 2, 3, 0, 1, 2, 3}, []int{0, 1, 2, 3}},
		{[]int{0, 1, 1, 3, 0, 1, 0, 1, 2, 3}, []int{0, 1, 3, 2}},
	}

	for _, tc := range tcs {
		inp := make([]protocol.FileInfo, len(tc.in))
		for i, j := range tc.in {
			inp[i] = protocol.FileInfo{Name: names[j]}
		}
		outp := normalizeFilenamesAndDropDuplicates(inp)
		if len(outp) != len(tc.out) {
			t.Errorf("Expected %v entries, got %v", len(tc.out), len(outp))
			continue
		}
		for i, f := range outp {
			if exp := names[tc.out[i]]; exp != f.Name {
				t.Errorf("Got file %v at pos %v, expected %v", f.Name, i, exp)
			}
		}
	}
}


Review comment (suggestion):
```suggestion
		{[]int{3, 2, 1, 0, 0, 1, 2, 3}, []int{0, 1, 2, 3}},
		{[]int{0, 1, 1, 3, 0, 1, 0, 1, 2, 3}, []int{0, 1, 2, 3}},
```

Code after:
		t.Fatal(err)
	}
	if vl.Versions[0].Deleted {
		t.Error("vl.Versions[0] deleted for c")
	}
	if !vl.Versions[1].Deleted {
		t.Error("vl.Versions[1] not deleted for c")
	}
}

func TestDropDuplicates(t *testing.T) {
	names := []string{
		"foo",
		"bar",
		"dcxvoijnds",
		"3d/dsfase/4/ss2",
	}
	tcs := []struct{ in, out []int }{
		{[]int{0}, []int{0}},
		{[]int{0, 1}, []int{0, 1}},
		{[]int{0, 1, 0, 1}, []int{0, 1}},
		{[]int{0, 1, 1, 1, 1}, []int{0, 1}},
		{[]int{0, 0, 0, 1}, []int{0, 1}},
		{[]int{0, 1, 2, 3}, []int{0, 1, 2, 3}},
		{[]int{3, 2, 1, 0, 0, 1, 2, 3}, []int{0, 1, 2, 3}},
		{[]int{0, 1, 1, 3, 0, 1, 0, 1, 2, 3}, []int{0, 1, 2, 3}},
	}

	for tci, tc := range tcs {
		inp := make([]protocol.FileInfo, len(tc.in))
		expSeq := make(map[string]int)
		for i, j := range tc.in {
			inp[i] = protocol.FileInfo{Name: names[j], Sequence: int64(i)}
			expSeq[names[j]] = i
		}
		outp := normalizeFilenamesAndDropDuplicates(inp)
		if len(outp) != len(tc.out) {
			t.Errorf("tc %v: Expected %v entries, got %v", tci, len(tc.out), len(outp))
			continue
		}
		for i, f := range outp {
			if exp := names[tc.out[i]]; exp != f.Name {
				t.Errorf("tc %v: Got file %v at pos %v, expected %v", tci, f.Name, i, exp)
			}
			if exp := int64(expSeq[outp[i].Name]); exp != f.Sequence {
				t.Errorf("tc %v: Got sequence %v at pos %v, expected %v", tci, f.Sequence, i, exp)
			}
		}
	}
}
Repository: syncthing/syncthing
File: lib/versioner/staggered_test.go (Go)

Code before:

	if diff, equal := messagediff.PrettyDiff(delete, rem); !equal {
		t.Errorf("Incorrect deleted files; got %v, expected %v\n%v", rem, delete, diff)
	}
}

func parseTime(in string) time.Time {
	t, err := time.ParseInLocation(TimeFormat, in, time.Local)
	if err != nil {
		panic(err.Error())
	}
	return t
}

func TestCreateVersionPath(t *testing.T) {
	file := "myfile"

	tmpDir, err := ioutil.TempDir("", "")
	if err != nil {
		t.Fatal(err)
	}

	folderFs := fs.NewFilesystem(fs.FilesystemTypeBasic, tmpDir)

	versioner := newStaggered(folderFs, map[string]string{
		"fsType": "",
		"fsPath": file,
	})

	if err := versioner.Archive(file); err != nil {
		t.Fatal(err)
	}
}

Review comment (suggestion):
You don't need to add the empty string to the map. If `"fsType"` is missing, that's the same as an empty string.

Code after:
		"test~20160301-140000", // 44 days ago

		"test~20160223-140000", // 51 days ago

		"test~20150423-140000", // 358 days ago (!!! 2016 was a leap year !!!)

		"test~20150417-140000", // 364 days ago
		"test~20150416-140000", // 365 days ago

		// exceeds maxAge
		"test~20150416-135959", // 365 days 1 second ago
		"test~20150416-135958", // 365 days 2 seconds ago
		"test~20150414-140000", // 367 days ago
	}

	delete := []string{
		"test~20160415-135959", // 1 second ago
		"test~20160415-135931", // 29 seconds ago
		"test~20160415-130059", // 59 minutes 01 seconds ago
		"test~20160415-130000", // 1 hour ago
		"test~20160414-155959", // 22 hours 1 second ago
		"test~20160414-150001", // 22 hours 59 seconds ago
		"test~20160414-140000", // 1 day ago
		"test~20160409-135959", // 6 days 1 second ago
		"test~20160408-140001", // 6 days 23:59:59 second ago
		"test~20160408-135959", // 7 days 1 second ago
		"test~20160407-140001", // 7 days 23:59:59 ago
		"test~20160317-135959", // 29 days 1 second ago
		"test~20160308-135959", // 37 days 1 second ago
		"test~20150417-140000", // 364 days ago
		"test~20150416-135959", // 365 days 1 second ago
		"test~20150416-135958", // 365 days 2 seconds ago
		"test~20150414-140000", // 367 days ago
	}
	sort.Strings(delete)

	cfg := config.FolderConfiguration{
		FilesystemType: fs.FilesystemTypeBasic,
		Path:           "testdata",
		Versioning: config.VersioningConfiguration{
			Params: map[string]string{
				"maxAge": strconv.Itoa(365 * 86400),
			},
		},
	}

	v := newStaggered(cfg).(*staggered)
	rem := v.toRemove(versionsWithMtime, now)
	sort.Strings(rem)

	if diff, equal := messagediff.PrettyDiff(delete, rem); !equal {
Repository: syncthing/syncthing
File: lib/pmp/pmp.go (Go)

Code before:
	var ip net.IP
	err := util.CallWithContext(ctx, func() error {
		var err error
		ip, err = gateway.DiscoverGateway()
		return err
	})
	if err != nil {
		l.Debugln("Failed to discover gateway", err)
		return nil
	}
	if ip == nil || ip.IsUnspecified() {
		return nil
	}

	l.Debugln("Discovered gateway at", ip)

	c := natpmp.NewClientWithTimeout(ip, timeout)
	// Try contacting the gateway, if it does not respond, assume it does not
	// speak NAT-PMP.
	_, err = c.GetExternalAddress()
	if err != nil && strings.Contains(err.Error(), "Timed out") {
		l.Debugln("Timeout trying to get external address, assume no NAT-PMP available")
		return nil
	}

	var localIP net.IP
	// Port comes from the natpmp package
	timeoutCtx, cancel := context.WithTimeout(ctx, timeout)
	defer cancel()
	conn, err := (&net.Dialer{}).DialContext(timeoutCtx, "udp", net.JoinHostPort(ip.String(), "5351"))
	if err == nil {
		conn.Close()
		localIPAddress, _, err := net.SplitHostPort(conn.LocalAddr().String())
		if err == nil {
			localIP = net.ParseIP(localIPAddress)
		} else {
			l.Debugln("Failed to lookup local IP", err)
		}
	}

	return []nat.Device{&wrapper{
		renewal:   renewal,
		localIP:   localIP,
		gatewayIP: ip,
		client:    c,
	}}
}

type wrapper struct {
	renewal   time.Duration
	localIP   net.IP

Review comment (refactor):
Does util specifically use `github.com/pkg/errors` for wrapping? If so I guess this is fine (but should be flagged for future refactor), otherwise `errors.Is` seems more appropriate here now

Code after:
func Discover(ctx context.Context, renewal, timeout time.Duration) []nat.Device {
	var ip net.IP
	err := util.CallWithContext(ctx, func() error {
		var err error
		ip, err = gateway.DiscoverGateway()
		return err
	})
	if err != nil {
		l.Debugln("Failed to discover gateway", err)
		return nil
	}
	if ip == nil || ip.IsUnspecified() {
		return nil
	}

	l.Debugln("Discovered gateway at", ip)

	c := natpmp.NewClientWithTimeout(ip, timeout)
	// Try contacting the gateway, if it does not respond, assume it does not
	// speak NAT-PMP.
	err = util.CallWithContext(ctx, func() error {
		_, ierr := c.GetExternalAddress()
		return ierr
	})
	if err != nil {
		if errors.Cause(err) == context.Canceled {
			return nil
		}
		if strings.Contains(err.Error(), "Timed out") {
			l.Debugln("Timeout trying to get external address, assume no NAT-PMP available")
			return nil
		}
	}

	var localIP net.IP
	// Port comes from the natpmp package
	timeoutCtx, cancel := context.WithTimeout(ctx, timeout)
	defer cancel()
	conn, err := (&net.Dialer{}).DialContext(timeoutCtx, "udp", net.JoinHostPort(ip.String(), "5351"))
	if err == nil {
		conn.Close()
		localIPAddress, _, err := net.SplitHostPort(conn.LocalAddr().String())
		if err == nil {
			localIP = net.ParseIP(localIPAddress)
		} else {
			l.Debugln("Failed to lookup local IP", err)
		}
	}

	return []nat.Device{&wrapper{
		renewal:   renewal,
Repository: syncthing/syncthing
File: lib/model/model.go (Go)

Code before:
	defer restartMut.Unlock()

	var infoMsg string
	var errMsg string
	switch {
	case to.Paused:
		infoMsg = "Paused"
		errMsg = "pausing"
	case from.Paused:
		infoMsg = "Unpaused"
		errMsg = "unpausing"
	default:
		infoMsg = "Restarted"
		errMsg = "restarting"
	}

	var fset *db.FileSet
	if !to.Paused {
		// Creating the fileset can take a long time (metadata calculation)
		// so we do it outside of the lock.
		fset = db.NewFileSet(to.ID, to.Filesystem(), m.db)
	}

	m.stopFolder(from, fmt.Errorf("%v folder %v", errMsg, to.Description()))
	// Need to send CC change to both from and to devices.
	m.stopFolder(to, fmt.Errorf("%v folder %v", errMsg, to.Description()))

	m.fmut.Lock()
	defer m.fmut.Unlock()

	m.cleanupFolderLocked(from)
	if !to.Paused {
		m.addAndStartFolderLocked(to, fset)
	}
	l.Infof("%v folder %v (%v)", infoMsg, to.Description(), to.Type)
}

func (m *model) newFolder(cfg config.FolderConfiguration) {
	// Creating the fileset can take a long time (metadata calculation) so
	// we do it outside of the lock.
	fset := db.NewFileSet(cfg.ID, cfg.Filesystem(), m.db)

	// Close connections to affected devices
	m.closeConns(cfg.DeviceIDs(), fmt.Errorf("started folder %v", cfg.Description()))

	m.fmut.Lock()
	defer m.fmut.Unlock()
	m.addAndStartFolderLocked(cfg, fset)
}

func (m *model) UsageReportingStats(version int, preview bool) map[string]interface{} {

Review comment (suggestion):
```suggestion
	err := fmt.Errorf("%v folder %v", errMsg, to.Description()))
	m.stopFolder(from, err)
	// Need to send CC change to both from and to devices.
	m.closeConns(to.DeviceIDs, err)
```

Code after:
	defer restartMut.Unlock()

	var infoMsg string
	var errMsg string
	switch {
	case to.Paused:
		infoMsg = "Paused"
		errMsg = "pausing"
	case from.Paused:
		infoMsg = "Unpaused"
		errMsg = "unpausing"
	default:
		infoMsg = "Restarted"
		errMsg = "restarting"
	}

	var fset *db.FileSet
	if !to.Paused {
		// Creating the fileset can take a long time (metadata calculation)
		// so we do it outside of the lock.
		fset = db.NewFileSet(to.ID, to.Filesystem(), m.db)
	}

	err := fmt.Errorf("%v folder %v", errMsg, to.Description())
	m.stopFolder(from, err)
	// Need to send CC change to both from and to devices.
	m.closeConns(to.DeviceIDs(), err)

	m.fmut.Lock()
	defer m.fmut.Unlock()

	m.cleanupFolderLocked(from)
	if !to.Paused {
		m.addAndStartFolderLocked(to, fset)
	}
	l.Infof("%v folder %v (%v)", infoMsg, to.Description(), to.Type)
}

func (m *model) newFolder(cfg config.FolderConfiguration) {
	// Creating the fileset can take a long time (metadata calculation) so
	// we do it outside of the lock.
	fset := db.NewFileSet(cfg.ID, cfg.Filesystem(), m.db)

	// Close connections to affected devices
	m.closeConns(cfg.DeviceIDs(), fmt.Errorf("started folder %v", cfg.Description()))

	m.fmut.Lock()
	defer m.fmut.Unlock()
	m.addAndStartFolderLocked(cfg, fset)
}
Repository: syncthing/syncthing
File: lib/api/api.go (Go)

Code before:
	if deviceStr != "" {
		var err error
		device, err = protocol.DeviceIDFromString(deviceStr)
		if err != nil {
			http.Error(w, err.Error(), http.StatusBadRequest)
			return
		}
	}

	// The user specifically asked for our own device ID. Internally that is
	// known as protocol.LocalDeviceID so translate.
	if device == s.id {
		device = protocol.LocalDeviceID
	}

	var comp model.FolderCompletion
	if folder != "" {
		// We want completion for a specific folder.
		comp = s.model.Completion(device, folder)
	} else {
		// We want completion for all folders as an aggregate.
		for _, fcfg := range s.cfg.FolderList() {
			if device == protocol.LocalDeviceID || fcfg.SharedWith(device) {
				comp.Add(s.model.Completion(device, fcfg.ID))
			}
		}
	}

	sendJSON(w, comp.Map())
}

func (s *service) getDBStatus(w http.ResponseWriter, r *http.Request) {
	qs := r.URL.Query()
	folder := qs.Get("folder")
	if sum, err := s.fss.Summary(folder); err != nil {
		http.Error(w, err.Error(), http.StatusNotFound)
	} else {
		sendJSON(w, sum)
	}
}

func (s *service) postDBOverride(w http.ResponseWriter, r *http.Request) {
	var qs = r.URL.Query()
	var folder = qs.Get("folder")
	go s.model.Override(folder)
}

func (s *service) postDBRevert(w http.ResponseWriter, r *http.Request) {
	var qs = r.URL.Query()
	var folder = qs.Get("folder")
	go s.model.Revert(folder)

Review comment (suggestion):
I'd probably have done the aggregation to model.go, thus not exposing `model.FolderCompletion` and keeping api code "dumb".

Code after:
	if deviceStr != "" {
		var err error
		device, err = protocol.DeviceIDFromString(deviceStr)
		if err != nil {
			http.Error(w, err.Error(), http.StatusBadRequest)
			return
		}
	}

	sendJSON(w, s.model.Completion(device, folder).Map())
}

func (s *service) getDBStatus(w http.ResponseWriter, r *http.Request) {
	qs := r.URL.Query()
	folder := qs.Get("folder")
	if sum, err := s.fss.Summary(folder); err != nil {
		http.Error(w, err.Error(), http.StatusNotFound)
	} else {
		sendJSON(w, sum)
	}
}

func (s *service) postDBOverride(w http.ResponseWriter, r *http.Request) {
	var qs = r.URL.Query()
	var folder = qs.Get("folder")
	go s.model.Override(folder)
}

func (s *service) postDBRevert(w http.ResponseWriter, r *http.Request) {
	var qs = r.URL.Query()
	var folder = qs.Get("folder")
	go s.model.Revert(folder)
}

func getPagingParams(qs url.Values) (int, int) {
	page, err := strconv.Atoi(qs.Get("page"))
	if err != nil || page < 1 {
		page = 1
	}
	perpage, err := strconv.Atoi(qs.Get("perpage"))
	if err != nil || perpage < 1 {
		perpage = 1 << 16
	}
	return page, perpage
}

func (s *service) getDBNeed(w http.ResponseWriter, r *http.Request) {
	qs := r.URL.Query()

	folder := qs.Get("folder")
Repository: syncthing/syncthing
File: lib/api/api.go (Go)

Code before:
		var err error
		leaf, err = x509.ParseCertificate(cert.Certificate[0])
		if err != nil {
			return err
		}
	}

	if leaf.Subject.String() != leaf.Issuer.String() || len(leaf.IPAddresses) != 0 {
		// The certificate is not self signed, or has IP attributes we don't
		// add, so we leave it alone.
		return nil
	}
	if len(leaf.DNSNames) > 1 {
		// The certificate has more DNS SANs attributes than we ever add, so
		// we leave it alone.
		return nil
	}
	if len(leaf.DNSNames) == 1 && leaf.DNSNames[0] != leaf.Issuer.CommonName {
		// The one SAN is different from the issuer, so it's not one of our
		// newer self signed certificates.
		return nil
	}

	if leaf.NotAfter.Before(time.Now()) {
		return errors.New("certificate has expired")
	}
	if leaf.NotAfter.Before(time.Now().Add(30 * 24 * time.Hour)) {
		return errors.New("certificate will soon expire")
	}

	// On macOS, check for certificates issued on or after July 1st, 2019,
	// with a longer validity time than 825 days.
	cutoff := time.Date(2019, 7, 1, 0, 0, 0, 0, time.UTC)
	if runtime.GOOS == "darwin" &&
		leaf.NotBefore.After(cutoff) &&
		leaf.NotAfter.Sub(leaf.NotBefore) > 825*24*time.Hour {
		return errors.New("certificate incompatible with macOS 10.15 (Catalina)")
	}

	return nil
}

func errorString(err error) *string {
	if err != nil {
		msg := err.Error()
		return &msg
	}
	return nil
}


Review comment (bug):
Seems weird that checkExpiry function doesn't check expiry in so many edge cases, and returns no error... Defo feels deceptive...

Code after:
		if len(cert.Certificate) < 1 {
			// can't happen
			return errors.New("no certificate in certificate")
		}
		var err error
		leaf, err = x509.ParseCertificate(cert.Certificate[0])
		if err != nil {
			return err
		}
	}

	if leaf.Subject.String() != leaf.Issuer.String() || len(leaf.IPAddresses) != 0 {
		// The certificate is not self signed, or has IP attributes we don't
		// add, so we leave it alone.
		return nil
	}
	if len(leaf.DNSNames) > 1 {
		// The certificate has more DNS SANs attributes than we ever add, so
		// we leave it alone.
		return nil
	}
	if len(leaf.DNSNames) == 1 && leaf.DNSNames[0] != leaf.Issuer.CommonName {
		// The one SAN is different from the issuer, so it's not one of our
		// newer self signed certificates.
		return nil
	}

	if leaf.NotAfter.Before(time.Now()) {
		return errors.New("certificate has expired")
	}
	if leaf.NotAfter.Before(time.Now().Add(30 * 24 * time.Hour)) {
		return errors.New("certificate will soon expire")
	}

	// On macOS, check for certificates issued on or after July 1st, 2019,
	// with a longer validity time than 825 days.
	cutoff := time.Date(2019, 7, 1, 0, 0, 0, 0, time.UTC)
	if runtime.GOOS == "darwin" &&
		leaf.NotBefore.After(cutoff) &&
		leaf.NotAfter.Sub(leaf.NotBefore) > 825*24*time.Hour {
		return errors.New("certificate incompatible with macOS 10.15 (Catalina)")
	}

	return nil
}

func errorString(err error) *string {
	if err != nil {
		msg := err.Error()
		return &msg
	}