Skip to content
1 change: 1 addition & 0 deletions .golangci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ linters:
- recvcheck
- tagliatelle
- tagalign
- testpackage
- wsl

settings:
Expand Down
11 changes: 8 additions & 3 deletions internal/io/write_fuzz_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ func FuzzSecureWriteFromReader(f *testing.F) {
f.Add("link.txt", []byte("data"), int64(10), true, true, false)
f.Add("abs.txt", []byte("data"), int64(10), true, false, true)

f.Fuzz(func(t *testing.T, name string, data []byte, maxSize int64, allowSymlinks bool, useSymlink bool, makeAbsolute bool) {
f.Fuzz(func(t *testing.T, name string, data []byte, maxSize int64, allowSymlinks, useSymlink, makeAbsolute bool) {
if len(data) > 2048 {
data = data[:2048]
}
Expand All @@ -36,13 +36,18 @@ func FuzzSecureWriteFromReader(f *testing.F) {

if useSymlink {
targetPath := filepath.Join(baseDir, "target-"+safeName)
if err := os.WriteFile(targetPath, []byte("target"), 0o600); err != nil {

err := os.WriteFile(targetPath, []byte("target"), 0o600)
if err != nil {
t.Skipf("failed to create symlink target: %v", err)
}

linkName := "link-" + safeName

linkPath := filepath.Join(baseDir, linkName)
if err := os.Symlink(targetPath, linkPath); err != nil {

err = os.Symlink(targetPath, linkPath)
if err != nil {
t.Skipf("symlink not supported: %v", err)
}

Expand Down
4 changes: 4 additions & 0 deletions pkg/auth/paseto_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ func TestPasetoLocalRoundTrip(t *testing.T) {
if err != nil {
t.Fatalf("expected parsed token, got error: %v", err)
}

if parsed == nil {
t.Fatalf("expected parsed token")
}
Expand Down Expand Up @@ -81,13 +82,15 @@ func TestPasetoPublicRoundTrip(t *testing.T) {
if err != nil {
t.Fatalf("expected parsed token, got error: %v", err)
}

if parsed == nil {
t.Fatalf("expected parsed token")
}
}

func TestPasetoMissingExpiration(t *testing.T) {
key := paseto.NewV4SymmetricKey()

local, err := NewPasetoLocal(WithPasetoLocalKey(key))
if err != nil {
t.Fatalf("expected local helper, got error: %v", err)
Expand All @@ -99,6 +102,7 @@ func TestPasetoMissingExpiration(t *testing.T) {
}

secret := paseto.NewV4AsymmetricSecretKey()

signer, err := NewPasetoPublicSigner(WithPasetoPublicSecretKey(secret))
if err != nil {
t.Fatalf("expected signer, got error: %v", err)
Expand Down
1 change: 1 addition & 0 deletions pkg/io/copy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,5 +58,6 @@ func TestSecureCopyFileVerifyChecksum(t *testing.T) {
require.NoError(t, err)

destPath := filepath.Join(os.TempDir(), destName)

t.Cleanup(func() { _ = os.Remove(destPath) })
}
6 changes: 4 additions & 2 deletions pkg/memory/secure_buffer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -220,11 +220,13 @@ func TestZeroBytes(t *testing.T) {
func TestSecureBufferLockUnlockEmpty(t *testing.T) {
buf := NewSecureBuffer([]byte{})

if err := buf.Lock(); err != nil {
err := buf.Lock()
if err != nil {
t.Fatalf("expected nil error on empty lock, got %v", err)
}

if err := buf.Unlock(); err != nil {
err = buf.Unlock()
if err != nil {
t.Fatalf("expected nil error on empty unlock, got %v", err)
}
}
4 changes: 4 additions & 0 deletions pkg/password/argon2id_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,11 @@ func TestArgon2idHashVerify(t *testing.T) {
if err != nil {
t.Fatalf("expected verify success, got error: %v", err)
}

if !ok {
t.Fatalf("expected password match")
}

if needsRehash {
t.Fatalf("expected no rehash with same params")
}
Expand All @@ -50,9 +52,11 @@ func TestArgon2idHashVerify(t *testing.T) {
if err != nil {
t.Fatalf("expected verify success, got error: %v", err)
}

if !ok {
t.Fatalf("expected password match")
}

if !needsRehash {
t.Fatalf("expected rehash for stronger params")
}
Expand Down
5 changes: 5 additions & 0 deletions pkg/password/bcrypt_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,11 @@ func TestBcryptHashVerify(t *testing.T) {
if err != nil {
t.Fatalf("expected verify success, got error: %v", err)
}

if !ok {
t.Fatalf("expected password match")
}

if needsRehash {
t.Fatalf("expected no rehash with same cost")
}
Expand All @@ -38,9 +40,11 @@ func TestBcryptHashVerify(t *testing.T) {
if err != nil {
t.Fatalf("expected verify success, got error: %v", err)
}

if !ok {
t.Fatalf("expected password match")
}

if !needsRehash {
t.Fatalf("expected rehash with higher cost")
}
Expand All @@ -53,6 +57,7 @@ func TestBcryptPasswordTooLong(t *testing.T) {
}

longPassword := make([]byte, bcryptMaxPasswordLength+1)

_, err = hasher.Hash(longPassword)
if !errors.Is(err, ErrPasswordTooLong) {
t.Fatalf("expected ErrPasswordTooLong, got %v", err)
Expand Down
1 change: 1 addition & 0 deletions pkg/password/compare_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ func TestConstantTimeCompare(t *testing.T) {
if !ConstantTimeCompare([]byte("abc"), []byte("abc")) {
t.Fatalf("expected equal slices")
}

if ConstantTimeCompare([]byte("abc"), []byte("abcd")) {
t.Fatalf("expected unequal slices")
}
Expand Down
9 changes: 6 additions & 3 deletions pkg/sanitize/filename_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package sanitize

import "testing"
import (
"errors"
"testing"
)

func TestFilenameSanitizeBasic(t *testing.T) {
sanitizer, err := NewFilenameSanitizer()
Expand Down Expand Up @@ -57,7 +60,7 @@ func TestFilenameSanitizeEmpty(t *testing.T) {
}

_, err = sanitizer.Sanitize(" ")
if err != ErrFilenameEmpty {
if !errors.Is(err, ErrFilenameEmpty) {
t.Fatalf("expected ErrFilenameEmpty, got %v", err)
}
}
Expand All @@ -69,7 +72,7 @@ func TestFilenameSanitizeMaxLength(t *testing.T) {
}

_, err = sanitizer.Sanitize("abcd")
if err != ErrFilenameTooLong {
if !errors.Is(err, ErrFilenameTooLong) {
t.Fatalf("expected ErrFilenameTooLong, got %v", err)
}
}
4 changes: 3 additions & 1 deletion pkg/sanitize/html_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package sanitize

import (
"errors"
"html"
"testing"
)
Expand All @@ -12,6 +13,7 @@ func TestHTMLSanitizeEscape(t *testing.T) {
}

input := `<script>alert("x")</script>`

output, err := sanitizer.Sanitize(input)
if err != nil {
t.Fatalf("expected sanitized html, got %v", err)
Expand Down Expand Up @@ -64,7 +66,7 @@ func TestHTMLSanitizeMaxLength(t *testing.T) {
}

_, err = sanitizer.Sanitize("ab")
if err != ErrHTMLTooLong {
if !errors.Is(err, ErrHTMLTooLong) {
t.Fatalf("expected ErrHTMLTooLong, got %v", err)
}
}
5 changes: 4 additions & 1 deletion pkg/sanitize/markdown_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package sanitize

import (
"errors"
"html"
"testing"
)
Expand All @@ -12,6 +13,7 @@ func TestMarkdownSanitizeEscape(t *testing.T) {
}

input := "<b>hello</b>"

output, err := sanitizer.Sanitize(input)
if err != nil {
t.Fatalf("expected sanitized markdown, got %v", err)
Expand All @@ -30,6 +32,7 @@ func TestMarkdownAllowRawHTML(t *testing.T) {
}

input := "<b>hello</b>"

output, err := sanitizer.Sanitize(input)
if err != nil {
t.Fatalf("expected sanitized markdown, got %v", err)
Expand All @@ -47,7 +50,7 @@ func TestMarkdownMaxLength(t *testing.T) {
}

_, err = sanitizer.Sanitize("ab")
if err != ErrMarkdownTooLong {
if !errors.Is(err, ErrMarkdownTooLong) {
t.Fatalf("expected ErrMarkdownTooLong, got %v", err)
}
}
23 changes: 19 additions & 4 deletions pkg/sanitize/nosql_detect_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package sanitize

import "testing"
import (
"errors"
"testing"
)

func TestNoSQLInjectionDetectorDefault(t *testing.T) {
detector, err := NewNoSQLInjectionDetector()
Expand All @@ -9,12 +12,12 @@ func TestNoSQLInjectionDetectorDefault(t *testing.T) {
}

err = detector.Detect(`{"username":{"$ne":null}}`)
if err != ErrNoSQLInjectionDetected {
if !errors.Is(err, ErrNoSQLInjectionDetected) {
t.Fatalf("expected ErrNoSQLInjectionDetected, got %v", err)
}

err = detector.Detect(`{"$where":"sleep(1)"}`)
if err != ErrNoSQLInjectionDetected {
if !errors.Is(err, ErrNoSQLInjectionDetected) {
t.Fatalf("expected ErrNoSQLInjectionDetected, got %v", err)
}

Expand All @@ -31,7 +34,19 @@ func TestNoSQLInjectionDetectorCustomOperators(t *testing.T) {
}

err = detector.Detect(`{"$custom":true}`)
if err != ErrNoSQLInjectionDetected {
if !errors.Is(err, ErrNoSQLInjectionDetected) {
t.Fatalf("expected ErrNoSQLInjectionDetected, got %v", err)
}
}

func TestNoSQLInjectionDetectorMaxLength(t *testing.T) {
detector, err := NewNoSQLInjectionDetector(WithNoSQLDetectMaxLength(1))
if err != nil {
t.Fatalf("expected detector, got %v", err)
}

err = detector.Detect("ab")
if !errors.Is(err, ErrNoSQLInputTooLong) {
t.Fatalf("expected ErrNoSQLInputTooLong, got %v", err)
}
}
Comment on lines 42 to 52
Copy link

Copilot AI Jan 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test should include a boundary case where the input length equals the maxLength to verify that inputs at the exact limit are accepted. Consider adding a test case like detector.Detect("a") which should return nil since the length is exactly 1 and the maxLength is 1. This would ensure the boundary condition (len(input) > d.opts.maxLength) works correctly.

Copilot uses AI. Check for mistakes.
13 changes: 8 additions & 5 deletions pkg/sanitize/sql_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package sanitize

import "testing"
import (
"errors"
"testing"
)

func TestSQLSanitizeIdentifier(t *testing.T) {
sanitizer, err := NewSQLSanitizer()
Expand All @@ -18,7 +21,7 @@ func TestSQLSanitizeIdentifier(t *testing.T) {
}

_, err = sanitizer.Sanitize("users;drop")
if err != ErrSQLIdentifierInvalid {
if !errors.Is(err, ErrSQLIdentifierInvalid) {
t.Fatalf("expected ErrSQLIdentifierInvalid, got %v", err)
}
}
Expand All @@ -39,7 +42,7 @@ func TestSQLSanitizeQualifiedIdentifier(t *testing.T) {
}

_, err = sanitizer.Sanitize("public..users")
if err != ErrSQLIdentifierInvalid {
if !errors.Is(err, ErrSQLIdentifierInvalid) {
t.Fatalf("expected ErrSQLIdentifierInvalid, got %v", err)
}
}
Expand All @@ -60,7 +63,7 @@ func TestSQLSanitizeLiteral(t *testing.T) {
}

_, err = sanitizer.Sanitize("bad\x00")
if err != ErrSQLLiteralInvalid {
if !errors.Is(err, ErrSQLLiteralInvalid) {
t.Fatalf("expected ErrSQLLiteralInvalid, got %v", err)
}
}
Expand Down Expand Up @@ -88,7 +91,7 @@ func TestSQLInjectionDetector(t *testing.T) {
}

err = detector.Detect("1 OR 1=1; --")
if err != ErrSQLInjectionDetected {
if !errors.Is(err, ErrSQLInjectionDetected) {
t.Fatalf("expected ErrSQLInjectionDetected, got %v", err)
}

Expand Down
Loading
Loading