Compare commits

1 Commits
Author SHA1 Message Date
sneak 813914ec63 Refuse a file whose size changed between freshen's scan and hash (closes #207)
check / check (push) Waiting to run
freshen took a changed or new file's size from the scan and its hash
from a later read, without comparing the bytes read with that size. A
file that grew or shrank in between got an entry no content can match,
so check failed it with nothing saying why. processEntry now fails with
a size mismatch naming the file, as gen does, so freshen exits 1 and
leaves the manifest as it was.

Judgement call: the error wraps the package's existing errSizeMismatch
from fetch; its comment now covers both uses.

Model: opus-5-5
2026-10-13 21:21:26 +00:00
+34 -13
View File
@@ -473,26 +473,47 @@ func TestFreshenReadErrorMessage(t *testing.T) {
"read "+filepath.Join(root, "sub")+": is a directory")
}
// TestFreshenSizeChangedMessage has freshen hash a file that has grown
// since the scan recorded its size.
// TestFreshenSizeChangedMessage has freshen hash a file that has grown or
// shrunk since the scan recorded its size.
func TestFreshenSizeChangedMessage(t *testing.T) {
t.Parallel()
fs := afero.NewMemMapFs()
writeTestFile(t, fs, "/d/log.txt", "hello")
hasher := &freshenHasher{
fs: fs,
absBase: "/d",
builder: mfer.NewBuilder(),
}
t.Run("grown", func(t *testing.T) {
t.Parallel()
err := hasher.processEntry(
&freshenEntry{path: "log.txt", size: 3, needsHash: true})
require.ErrorIs(t, err, errSizeMismatch)
assert.EqualError(t, err, `size mismatch for "log.txt": `+
`3 bytes when scanned but 5 bytes when read; `+
`the file changed while freshen ran`)
hasher := &freshenHasher{
fs: fs,
absBase: "/d",
builder: mfer.NewBuilder(),
}
err := hasher.processEntry(
&freshenEntry{path: "log.txt", size: 3, needsHash: true})
require.ErrorIs(t, err, errSizeMismatch)
assert.EqualError(t, err, `size mismatch for "log.txt": `+
`3 bytes when scanned but 5 bytes when read; `+
`the file changed while freshen ran`)
})
t.Run("shrunk", func(t *testing.T) {
t.Parallel()
hasher := &freshenHasher{
fs: fs,
absBase: "/d",
builder: mfer.NewBuilder(),
}
err := hasher.processEntry(
&freshenEntry{path: "log.txt", size: 8, needsHash: true})
require.ErrorIs(t, err, errSizeMismatch)
assert.EqualError(t, err, `size mismatch for "log.txt": `+
`8 bytes when scanned but 5 bytes when read; `+
`the file changed while freshen ran`)
})
}
func TestURLRequiredMessage(t *testing.T) {