Raise Go to the latest release, update dependencies, use the standard library uuid, add a vulnerability check (closes #102)
check / check (push) Failing after 3s

Go 1.27.1 in go.mod and in the Dockerfile's test and build images.
Every module go.mod requires is at its current release; protoc-gen-go
follows protobuf to v1.36.12 and mf.pb.go is regenerated. The standard
library uuid package replaces github.com/google/uuid; FromBytes could
only fail on a length validateUUID already checks, so that call and its
unreachable error are gone. make vulncheck runs govulncheck v1.8.0,
installed with go install at its release commit, in a vulncheck stage
of the Dockerfile; script/check does not run it. The newer go directive
switches on lint checks for strings.SplitSeq and t.Chdir, now used. A
new test pins the bytes of a seeded manifest written by an mfer built
before this change.

Model: opus-5-5
This commit was merged in pull request #164.
This commit is contained in:
2026-10-06 20:26:15 +02:00
parent 2a270b40c5
commit 2a174e3ba2
19 changed files with 152 additions and 523 deletions
+1 -1
View File
@@ -64,7 +64,7 @@ func ValidatePath(p string) error {
return fmt.Errorf("path %q %w", p, errPathAbsolute)
}
for _, seg := range strings.Split(p, "/") {
for seg := range strings.SplitSeq(p, "/") {
if seg == "" {
return fmt.Errorf("path %q %w", p, errPathEmptySegment)
}
+2 -8
View File
@@ -8,7 +8,6 @@ import (
"fmt"
"io"
"github.com/google/uuid"
"github.com/klauspost/compress/zstd"
"github.com/spf13/afero"
"google.golang.org/protobuf/encoding/protowire"
@@ -19,7 +18,6 @@ import (
var (
errInvalidUUIDLength = errors.New("invalid UUID length")
errInvalidUUIDFormat = errors.New("invalid UUID format")
errUnknownVersion = errors.New("unknown version")
errUnknownCompression = errors.New("unknown compression type")
errCompressedHashWrong = errors.New("compressed data hash mismatch")
@@ -32,16 +30,12 @@ var (
"manifest would take too much memory to decode")
)
// validateUUID checks that the byte slice is a valid UUID (16 bytes, parseable).
// validateUUID checks that the byte slice is the 16 bytes of a binary UUID.
// Any 16 bytes are one, so the length is all there is to check.
func validateUUID(data []byte) error {
if len(data) != uuidLength {
return errInvalidUUIDLength
}
// Try to parse as UUID to validate format
_, err := uuid.FromBytes(data)
if err != nil {
return errInvalidUUIDFormat
}
return nil
}
+4 -4
View File
@@ -10,8 +10,8 @@ import (
"strings"
"testing"
"time"
"uuid"
"github.com/google/uuid"
"github.com/klauspost/compress/zstd"
"github.com/multiformats/go-multihash"
"github.com/stretchr/testify/assert"
@@ -92,7 +92,7 @@ func TestDeserializeRejectsInvalidEntryPaths(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
id := uuid.New()
id := uuid.NewV4()
data := wrapInner(t, id, craftInnerBytes(id, tt.path))
_, err := NewManifestFromReader(bytes.NewReader(data))
@@ -150,7 +150,7 @@ func TestDeserializeRefusesEntriesThatDecodeTooLarge(t *testing.T) {
entry = protowire.AppendTag(entry, 303, protowire.BytesType) // MFFilePath.ctime
entry = protowire.AppendBytes(entry, nil)
id := uuid.New()
id := uuid.NewV4()
inner := protowire.AppendTag(nil, 102, protowire.BytesType) // MFFile.uuid
inner = protowire.AppendBytes(inner, id[:])
@@ -181,7 +181,7 @@ func TestDeserializeDropsUnknownFields(t *testing.T) {
entry = protowire.AppendString(entry, "a")
entry = append(entry, unknown...)
id := uuid.New()
id := uuid.NewV4()
inner := protowire.AppendTag(nil, 101, protowire.BytesType) // MFFile.files
inner = protowire.AppendBytes(inner, entry)
inner = protowire.AppendTag(inner, 102, protowire.BytesType) // MFFile.uuid
+1 -1
View File
@@ -125,7 +125,7 @@ func runGPG(
// parseFingerprint extracts the first fingerprint from gpg --with-colons
// output, or returns ok=false if none is present.
func parseFingerprint(colonOutput string) (string, bool) {
for _, line := range strings.Split(colonOutput, "\n") {
for line := range strings.SplitSeq(colonOutput, "\n") {
fields := strings.Split(line, ":")
if len(fields) >= gpgFingerprintMinFields &&
fields[0] == gpgFingerprintField {
+1 -1
View File
@@ -75,7 +75,7 @@ Expire-Date: 0
// Parse fingerprint from output
var keyID string
for _, line := range strings.Split(string(output), "\n") {
for line := range strings.SplitSeq(string(output), "\n") {
fields := strings.Split(line, ":")
if len(fields) >= gpgFingerprintMinFields &&
fields[0] == gpgFingerprintField {
+4 -4
View File
@@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.36.11
// protoc-gen-go v1.36.12
// protoc v6.33.4
// source: mf.proto
@@ -223,11 +223,11 @@ type MFFileOuter struct {
// uuid must match the uuid in the inner message
Uuid []byte `protobuf:"bytes,105,opt,name=uuid,proto3" json:"uuid,omitempty"`
InnerMessage []byte `protobuf:"bytes,199,opt,name=innerMessage,proto3" json:"innerMessage,omitempty"`
// detached signature, ascii or binary
//detached signature, ascii or binary
Signature []byte `protobuf:"bytes,201,opt,name=signature,proto3,oneof" json:"signature,omitempty"`
// full GPG key id
//full GPG key id
Signer []byte `protobuf:"bytes,202,opt,name=signer,proto3,oneof" json:"signer,omitempty"`
// full GPG signing public key, ascii or binary
//full GPG signing public key, ascii or binary
SigningPubKey []byte `protobuf:"bytes,203,opt,name=signingPubKey,proto3,oneof" json:"signingPubKey,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
+2 -2
View File
@@ -8,8 +8,8 @@ import (
"fmt"
"math"
"time"
"uuid"
"github.com/google/uuid"
"github.com/klauspost/compress/zstd"
"google.golang.org/protobuf/proto"
)
@@ -88,7 +88,7 @@ func (m *manifest) generateOuter(ctx context.Context) error {
if len(m.fixedUUID) == uuidLength {
copy(manifestUUID[:], m.fixedUUID)
} else {
manifestUUID = uuid.New()
manifestUUID = uuid.NewV4()
}
m.pbInner.Uuid = manifestUUID[:]