diff --git a/pkg/apk/apk/cache.go b/pkg/apk/apk/cache.go index 01b82e26d..ecbe4f624 100644 --- a/pkg/apk/apk/cache.go +++ b/pkg/apk/apk/cache.go @@ -16,6 +16,7 @@ package apk import ( "context" + "encoding/base32" "fmt" "io" "net/http" @@ -331,6 +332,11 @@ func etagFromResponse(resp *http.Response) (string, bool) { } // When we get etags, they appear to be quoted. etag := strings.Trim(remoteEtag[0], `"`) + + // To ensure these things are safe filenames, base32 encode them. + // (Avoiding base64 due to case sensitive filesystems.) + etag = base32.StdEncoding.EncodeToString([]byte(etag)) + return etag, etag != "" } diff --git a/pkg/apk/apk/repo_test.go b/pkg/apk/apk/repo_test.go index b8a57ab8c..90a098880 100644 --- a/pkg/apk/apk/repo_test.go +++ b/pkg/apk/apk/repo_test.go @@ -16,6 +16,7 @@ package apk import ( "context" + "encoding/base32" "fmt" "io/fs" "net/http" @@ -192,7 +193,7 @@ func TestGetRepositoryIndexes(t *testing.T) { require.NoErrorf(t, err, "unable to get indexes") require.Greater(t, len(indexes), 0, "no indexes found") // check that the contents are the same - index1, err := os.ReadFile(filepath.Join(repoDir, "APKINDEX", "an-etag.tar.gz")) + index1, err := os.ReadFile(filepath.Join(repoDir, "APKINDEX", base32.StdEncoding.EncodeToString([]byte("an-etag"))+".tar.gz")) require.NoError(t, err, "unable to read cache index file") index2, err := os.ReadFile(filepath.Join(testPrimaryPkgDir, indexFilename)) require.NoError(t, err, "unable to read previous index file")