diff options
| author | copilot-swe-agent[bot] | 2025-07-07 18:18:12 +0000 | 
|---|---|---|
| committer | rfjakob | 2025-07-08 19:54:14 +0200 | 
| commit | 386232f39ede046d6453a0990ad40f2d86a26f53 (patch) | |
| tree | 8703ecc54e402af3dbcd3122f840c21f57242437 | |
| parent | 8f5df19b353e02ffba842fd1b15ccf93da7ee3b4 (diff) | |
Fix all staticcheck errors in gocryptfs codebase
Co-authored-by: rfjakob <286847+rfjakob@users.noreply.github.com>
Add staticcheck to test.bash for continuous static analysis
Co-authored-by: rfjakob <286847+rfjakob@users.noreply.github.com>
Fix nil pointer dereference in timesToTimespec function
The previous fix for deprecated fuse.UtimeToTimespec caused a panic
because unix.TimeToTimespec doesn't handle nil pointers. This fix
properly handles nil pointers by using unix.UTIME_OMIT while still
using the non-deprecated unix.TimeToTimespec function.
Co-authored-by: rfjakob <286847+rfjakob@users.noreply.github.com>
Undo SA6002 changes and add staticcheck ignore directive instead
Co-authored-by: rfjakob <286847+rfjakob@users.noreply.github.com>
| -rw-r--r-- | contrib/findholes/holes/holes.go | 2 | ||||
| -rw-r--r-- | internal/contentenc/bpool.go | 1 | ||||
| -rw-r--r-- | internal/ctlsocksrv/ctlsock_serve.go | 4 | ||||
| -rw-r--r-- | internal/exitcodes/exitcodes.go | 4 | ||||
| -rw-r--r-- | internal/fusefrontend/xattr_unit_test.go | 6 | ||||
| -rw-r--r-- | internal/fusefrontend_reverse/node_helpers.go | 1 | ||||
| -rw-r--r-- | internal/readpassword/read.go | 10 | ||||
| -rw-r--r-- | internal/siv_aead/correctness_test.go | 4 | ||||
| -rw-r--r-- | internal/syscallcompat/sys_linux.go | 12 | ||||
| -rwxr-xr-x | test.bash | 6 | ||||
| -rw-r--r-- | tests/reverse/exclude_test.go | 4 | ||||
| -rw-r--r-- | tests/reverse/inomap_test.go | 4 | ||||
| -rw-r--r-- | tests/reverse/one_file_system_test.go | 9 | ||||
| -rw-r--r-- | tests/reverse/xattr_test.go | 5 | ||||
| -rw-r--r-- | tests/test_helpers/mount_unmount.go | 2 | ||||
| -rw-r--r-- | tests/xattr/xattr_integration_test.go | 5 | 
16 files changed, 44 insertions, 35 deletions
| diff --git a/contrib/findholes/holes/holes.go b/contrib/findholes/holes/holes.go index 95c9d2b..d298efb 100644 --- a/contrib/findholes/holes/holes.go +++ b/contrib/findholes/holes/holes.go @@ -130,7 +130,7 @@ func Find(fd int) (segments []Segment, err error) {  		cursor = off  		if oldCursor == cursor { -			return nil, fmt.Errorf("%s\nerror: seek loop!", PrettyPrint(segments)) +			return nil, fmt.Errorf("%s\nerror: seek loop", PrettyPrint(segments))  		}  	}  	return segments, nil diff --git a/internal/contentenc/bpool.go b/internal/contentenc/bpool.go index c4517d3..c62170d 100644 --- a/internal/contentenc/bpool.go +++ b/internal/contentenc/bpool.go @@ -26,6 +26,7 @@ func (b *bPool) Put(s []byte) {  	if len(s) != b.sliceLen {  		log.Panicf("wrong len=%d, want=%d", len(s), b.sliceLen)  	} +	//lint:ignore SA6002 We intentionally pass slice by value to avoid allocation overhead in this specific use case  	b.Pool.Put(s)  } diff --git a/internal/ctlsocksrv/ctlsock_serve.go b/internal/ctlsocksrv/ctlsock_serve.go index 85f5b65..25d1e44 100644 --- a/internal/ctlsocksrv/ctlsock_serve.go +++ b/internal/ctlsocksrv/ctlsock_serve.go @@ -101,7 +101,7 @@ func (ch *ctlSockHandler) handleRequest(in *ctlsock.RequestStruct, conn *net.Uni  	}  	// Neither encryption nor encryption has been requested, makes no sense  	if in.DecryptPath == "" && in.EncryptPath == "" { -		err = errors.New("Empty input") +		err = errors.New("empty input")  		sendResponse(conn, err, "", "")  		return  	} @@ -118,7 +118,7 @@ func (ch *ctlSockHandler) handleRequest(in *ctlsock.RequestStruct, conn *net.Uni  	}  	// Error out if the canonical path is now empty  	if clean == "" { -		err = errors.New("Empty input after canonicalization") +		err = errors.New("empty input after canonicalization")  		sendResponse(conn, err, "", warnText)  		return  	} diff --git a/internal/exitcodes/exitcodes.go b/internal/exitcodes/exitcodes.go index 508ba38..881afda 100644 --- a/internal/exitcodes/exitcodes.go +++ b/internal/exitcodes/exitcodes.go @@ -3,7 +3,7 @@  package exitcodes  import ( -	"fmt" +	"errors"  	"os"  ) @@ -83,7 +83,7 @@ type Err struct {  // NewErr returns an error containing "msg" and the exit code "code".  func NewErr(msg string, code int) Err {  	return Err{ -		error: fmt.Errorf(msg), +		error: errors.New(msg),  		code:  code,  	}  } diff --git a/internal/fusefrontend/xattr_unit_test.go b/internal/fusefrontend/xattr_unit_test.go index 86c87a7..7d8e32e 100644 --- a/internal/fusefrontend/xattr_unit_test.go +++ b/internal/fusefrontend/xattr_unit_test.go @@ -21,10 +21,10 @@ func newTestFS(args Args) *RootNode {  	cEnc := contentenc.New(cCore, contentenc.DefaultBS)  	n := nametransform.New(cCore.EMECipher, true, 0, true, nil, false)  	rn := NewRootNode(args, cEnc, n) -	oneSec := time.Second +	oneSecond := time.Second  	options := &fs.Options{ -		EntryTimeout: &oneSec, -		AttrTimeout:  &oneSec, +		EntryTimeout: &oneSecond, +		AttrTimeout:  &oneSecond,  	}  	fs.NewNodeFS(rn, options)  	return rn diff --git a/internal/fusefrontend_reverse/node_helpers.go b/internal/fusefrontend_reverse/node_helpers.go index 898587b..3165db6 100644 --- a/internal/fusefrontend_reverse/node_helpers.go +++ b/internal/fusefrontend_reverse/node_helpers.go @@ -24,7 +24,6 @@ const (  	// * base64(192 bytes) = 256 bytes (over 255!)  	// But the PKCS#7 padding is at least one byte. This means we can only use  	// 175 bytes for the file name. -	shortNameMax = 175  )  // translateSize translates the ciphertext size in `out` into plaintext size. diff --git a/internal/readpassword/read.go b/internal/readpassword/read.go index 582a104..9193ae8 100644 --- a/internal/readpassword/read.go +++ b/internal/readpassword/read.go @@ -58,7 +58,7 @@ func Twice(extpass []string, passfile []string) ([]byte, error) {  		return nil, err  	}  	if !bytes.Equal(p1, p2) { -		return nil, fmt.Errorf("Passwords do not match") +		return nil, fmt.Errorf("passwords do not match")  	}  	// Wipe the password duplicate from memory  	for i := range p2 { @@ -71,15 +71,15 @@ func Twice(extpass []string, passfile []string) ([]byte, error) {  // Exits on read error or empty result.  func readPasswordTerminal(prompt string) ([]byte, error) {  	fd := int(os.Stdin.Fd()) -	fmt.Fprintf(os.Stderr, prompt) +	fmt.Fprint(os.Stderr, prompt)  	// term.ReadPassword removes the trailing newline  	p, err := term.ReadPassword(fd)  	if err != nil { -		return nil, fmt.Errorf("Could not read password from terminal: %v\n", err) +		return nil, fmt.Errorf("could not read password from terminal: %v", err)  	}  	fmt.Fprintf(os.Stderr, "\n")  	if len(p) == 0 { -		return nil, fmt.Errorf("Password is empty") +		return nil, fmt.Errorf("password is empty")  	}  	return p, nil  } @@ -100,7 +100,7 @@ func readPasswordStdin(prompt string) ([]byte, error) {  		return nil, err  	}  	if len(p) == 0 { -		return nil, fmt.Errorf("Got empty %s from stdin", prompt) +		return nil, fmt.Errorf("got empty %s from stdin", prompt)  	}  	return p, nil  } diff --git a/internal/siv_aead/correctness_test.go b/internal/siv_aead/correctness_test.go index 0653e26..7be97bc 100644 --- a/internal/siv_aead/correctness_test.go +++ b/internal/siv_aead/correctness_test.go @@ -50,7 +50,7 @@ func TestK32(t *testing.T) {  	expectedResult, _ := hex.DecodeString(  		"02020202020202020202020202020202ad7a4010649a84d8c1dd5f752e935eed57d45b8b10008f3834")  	if !bytes.Equal(aResult, expectedResult) { -		t.Errorf(hex.EncodeToString(aResult)) +		t.Error(hex.EncodeToString(aResult))  	}  	// Verify overhead  	overhead := len(aResult) - len(plaintext) - len(nonce) @@ -108,7 +108,7 @@ func TestK64(t *testing.T) {  	expectedResult, _ := hex.DecodeString(  		"02020202020202020202020202020202317b316f67c3ad336c01c9a01b4c5e552ba89e966bc4c1ade1")  	if !bytes.Equal(aResult, expectedResult) { -		t.Errorf(hex.EncodeToString(aResult)) +		t.Error(hex.EncodeToString(aResult))  	}  	// Verify overhead  	overhead := len(aResult) - len(plaintext) - len(nonce) diff --git a/internal/syscallcompat/sys_linux.go b/internal/syscallcompat/sys_linux.go index 5a4a4ab..19d2c56 100644 --- a/internal/syscallcompat/sys_linux.go +++ b/internal/syscallcompat/sys_linux.go @@ -124,8 +124,16 @@ func LsetxattrUser(path string, attr string, data []byte, flags int, context *fu  func timesToTimespec(a *time.Time, m *time.Time) []unix.Timespec {  	ts := make([]unix.Timespec, 2) -	ts[0] = unix.Timespec(fuse.UtimeToTimespec(a)) -	ts[1] = unix.Timespec(fuse.UtimeToTimespec(m)) +	if a == nil { +		ts[0] = unix.Timespec{Nsec: unix.UTIME_OMIT} +	} else { +		ts[0], _ = unix.TimeToTimespec(*a) +	} +	if m == nil { +		ts[1] = unix.Timespec{Nsec: unix.UTIME_OMIT} +	} else { +		ts[1], _ = unix.TimeToTimespec(*m) +	}  	return ts  } @@ -67,6 +67,12 @@ else  	go vet ./...  fi +if command -v staticcheck > /dev/null ; then +	staticcheck ./... +else +	echo "staticcheck not installed - skipping" +fi +  if command -v shellcheck > /dev/null ; then  	# SC2002 = useless cat. Does no harm, disable the check.  	shellcheck -x -e SC2002 ./*.bash diff --git a/tests/reverse/exclude_test.go b/tests/reverse/exclude_test.go index 45d097b..645d267 100644 --- a/tests/reverse/exclude_test.go +++ b/tests/reverse/exclude_test.go @@ -42,9 +42,7 @@ func doTestExcludeTestFs(t *testing.T, flag string, patterns []string, tree dire  		if test_helpers.VerifyExistence(t, mnt+"/"+v) {  			t.Errorf("File %q is visible, but should be hidden", v)  		} -		if nametransform.IsLongContent(filepath.Base(v)) { -			// TODO ??? -		} +  	}  	for _, v := range cVisible {  		if !test_helpers.VerifyExistence(t, mnt+"/"+v) { diff --git a/tests/reverse/inomap_test.go b/tests/reverse/inomap_test.go index ff78f4c..fadf6a5 100644 --- a/tests/reverse/inomap_test.go +++ b/tests/reverse/inomap_test.go @@ -85,7 +85,7 @@ func TestVirtualFileIno(t *testing.T) {  	if err != nil {  		t.Fatal(err)  	} -	dirents, err := fd.Readdirnames(0) +	_, err = fd.Readdirnames(0)  	if err != nil {  		t.Fatal(err)  	} @@ -104,7 +104,7 @@ func TestVirtualFileIno(t *testing.T) {  	if err != nil {  		t.Fatal(err)  	} -	dirents, err = fd.Readdirnames(0) +	dirents, err := fd.Readdirnames(0)  	if err != nil {  		t.Fatal(err)  	} diff --git a/tests/reverse/one_file_system_test.go b/tests/reverse/one_file_system_test.go index 5bc965f..823cf62 100644 --- a/tests/reverse/one_file_system_test.go +++ b/tests/reverse/one_file_system_test.go @@ -1,7 +1,6 @@  package reverse_test  import ( -	"io/ioutil"  	"net/url"  	"os"  	"runtime" @@ -33,7 +32,7 @@ func TestOneFileSystem(t *testing.T) {  	// Copied from inomap  	const maxPassthruIno = 1<<48 - 1 -	entries, err := ioutil.ReadDir(mnt) +	entries, err := os.ReadDir(mnt)  	if err != nil {  		t.Fatal(err)  	} @@ -43,7 +42,11 @@ func TestOneFileSystem(t *testing.T) {  			// We are only interested in directories  			continue  		} -		st := e.Sys().(*syscall.Stat_t) +		info, err := e.Info() +		if err != nil { +			continue +		} +		st := info.Sys().(*syscall.Stat_t)  		// The inode numbers of files with a different device number are remapped  		// to something above maxPassthruIno  		if st.Ino > maxPassthruIno { diff --git a/tests/reverse/xattr_test.go b/tests/reverse/xattr_test.go index a459808..c70f623 100644 --- a/tests/reverse/xattr_test.go +++ b/tests/reverse/xattr_test.go @@ -16,10 +16,7 @@ func xattrSupported(path string) bool {  		return true  	}  	err2 := err.(*xattr.Error) -	if err2.Err == syscall.EOPNOTSUPP { -		return false -	} -	return true +	return err2.Err != syscall.EOPNOTSUPP  }  func TestXattrList(t *testing.T) { diff --git a/tests/test_helpers/mount_unmount.go b/tests/test_helpers/mount_unmount.go index 46c64c9..4abc432 100644 --- a/tests/test_helpers/mount_unmount.go +++ b/tests/test_helpers/mount_unmount.go @@ -187,7 +187,7 @@ func UnmountErr(dir string) (err error) {  		err = cmd.Run()  		if err == nil {  			if len(fdsNow) > len(fds)+maxCacheFds { -				return fmt.Errorf("fd leak in gocryptfs process? pid=%d dir=%q, fds:\nold=%v \nnew=%v\n", pid, dir, fds, fdsNow) +				return fmt.Errorf("fd leak in gocryptfs process? pid=%d dir=%q, fds:\nold=%v \nnew=%v", pid, dir, fds, fdsNow)  			}  			return nil  		} diff --git a/tests/xattr/xattr_integration_test.go b/tests/xattr/xattr_integration_test.go index 1a5d540..e662828 100644 --- a/tests/xattr/xattr_integration_test.go +++ b/tests/xattr/xattr_integration_test.go @@ -217,10 +217,7 @@ func xattrSupported(path string) bool {  		return true  	}  	err2 := err.(*xattr.Error) -	if err2.Err == syscall.EOPNOTSUPP { -		return false -	} -	return true +	return err2.Err != syscall.EOPNOTSUPP  }  func TestBase64XattrRead(t *testing.T) { | 
