Skip to content

Commit d2ef32a

Browse files
The127claude
andcommitted
feat: a download that does not match the pin is refused
The bytes would sit under their own digest, where a later pin on that digest would find them without ever asking for them. Co-Authored-By: Claude <noreply@anthropic.com> Signed-off-by: karo <karolin.kostial@gmail.com>
1 parent f3d04cd commit d2ef32a

2 files changed

Lines changed: 39 additions & 1 deletion

File tree

‎internal/download/pinned.go‎

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package download
22

33
import (
44
"context"
5+
"fmt"
56
"os"
67
)
78

@@ -13,9 +14,18 @@ func (s *Store) Pinned(ctx context.Context, url, digest string) (string, error)
1314
return path, nil
1415
}
1516

16-
if _, err := s.Get(ctx, url); err != nil {
17+
got, err := s.Get(ctx, url)
18+
if err != nil {
1719
return "", err
1820
}
1921

22+
if got != digest {
23+
// the bytes would sit under their own digest, where a pin on that
24+
// digest would later find them without ever asking for them
25+
_ = os.Remove(s.Path(got))
26+
27+
return "", fmt.Errorf("GET %s: pinned to %s, downloaded %s", url, digest, got)
28+
}
29+
2030
return path, nil
2131
}

‎internal/download/pinned_test.go‎

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,15 @@ func kept(t *testing.T, dir, content string) string {
2828
return "sha256:" + hash
2929
}
3030

31+
// arrived is the digest bytes would have when they arrive.
32+
func arrived(t *testing.T, content string) string {
33+
t.Helper()
34+
35+
sum := sha256.Sum256([]byte(content))
36+
37+
return "sha256:" + hex.EncodeToString(sum[:])
38+
}
39+
3140
func read(t *testing.T, path string) string {
3241
t.Helper()
3342

@@ -73,3 +82,22 @@ func TestAPinnedFileThatIsNotThereIsDownloadedAndKept(t *testing.T) {
7382
assert.Equal(t, "the kernel", read(t, path))
7483
assert.Equal(t, store.Path(digest), path)
7584
}
85+
86+
func TestADownloadThatDoesNotMatchThePinIsRefused(t *testing.T) {
87+
// arrange
88+
server := serving(t, map[string]string{"/kernel.deb": "another kernel"})
89+
dir := t.TempDir()
90+
store := download.Open(dir, server.Client())
91+
digest := arrived(t, "the kernel")
92+
93+
// act
94+
_, err := store.Pinned(context.Background(), server.URL+"/kernel.deb", digest)
95+
96+
// assert
97+
require.Error(t, err)
98+
assert.ErrorContains(t, err, server.URL+"/kernel.deb")
99+
assert.ErrorContains(t, err, digest)
100+
assert.ErrorContains(t, err, arrived(t, "another kernel"))
101+
kept, _ := filepath.Glob(filepath.Join(dir, "sha256", "*"))
102+
assert.Empty(t, kept)
103+
}

0 commit comments

Comments
 (0)