check / check (pull_request) Successful in 2m41s
The local index lists every backed-up path and chunk hash, but its file mode was left to the SQLite driver and the umask, so under a typical 022 umask a fresh index (and its -wal/-shm side files) landed world-readable. The snapshot export copied the index to snapshot.db with a permissive create as well. provideDatabase now calls ensureIndexFileMode before opening the driver: it creates the index 0600 if missing and chmods an existing one to 0600. Doing this before the driver opens the file matters because SQLite gives its -wal and -shm files the mode of the main database file. The export copy is now created 0600 instead of via the umask-dependent default. Tests under umask 022 cover a fresh index, an existing 0644 index in a 0755 directory, and the export copy, asserting each ends up 0600. Model: opus-4-8
50 lines
1.1 KiB
Go
50 lines
1.1 KiB
Go
//nolint:testpackage // exercises the unexported copyFile helper
|
|
package snapshot
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"syscall"
|
|
"testing"
|
|
|
|
"github.com/spf13/afero"
|
|
)
|
|
|
|
// TestCopyFileExportCopyMode verifies that the exported snapshot database
|
|
// copy is created owner-only (0600), even under a lenient 022 umask that
|
|
// would otherwise leave a fresh file world-readable.
|
|
//
|
|
//nolint:paralleltest // syscall.Umask is process-global; parallel tests would clash
|
|
func TestCopyFileExportCopyMode(t *testing.T) {
|
|
restore := syscall.Umask(0o022)
|
|
defer syscall.Umask(restore)
|
|
|
|
dir := t.TempDir()
|
|
|
|
src := filepath.Join(dir, "index.sqlite")
|
|
|
|
err := os.WriteFile(src, []byte("index data"), 0o600)
|
|
if err != nil {
|
|
t.Fatalf("creating source index: %v", err)
|
|
}
|
|
|
|
dst := filepath.Join(dir, "snapshot.db")
|
|
|
|
sm := &SnapshotManager{fs: afero.NewOsFs()}
|
|
|
|
err = sm.copyFile(src, dst)
|
|
if err != nil {
|
|
t.Fatalf("copyFile: %v", err)
|
|
}
|
|
|
|
info, err := os.Stat(dst)
|
|
if err != nil {
|
|
t.Fatalf("stat export copy: %v", err)
|
|
}
|
|
|
|
got := info.Mode().Perm()
|
|
if got != 0o600 {
|
|
t.Fatalf("export copy permissions = %#o, want %#o", got, 0o600)
|
|
}
|
|
}
|