Skip to content

Commit 24d6ef3

Browse files
committed
fixup! feat(fingerprint): add canonical encoder, version-set tag parser, sha256 combiner
1 parent 326e3a4 commit 24d6ef3

2 files changed

Lines changed: 37 additions & 4 deletions

File tree

internal/fingerprint/canonical.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,12 @@ func scalarToJSON(rval reflect.Value) (any, error) {
185185

186186
return number, nil
187187
case reflect.Slice:
188+
if rval.Type().Elem().Kind() == reflect.Uint8 {
189+
return nil, fmt.Errorf(
190+
"%s is not encodable at v1: a byte slice ([]byte) must be represented as a string in the config schema",
191+
rval.Type())
192+
}
193+
188194
out := make([]any, 0, rval.Len())
189195
for i := range rval.Len() {
190196
elem, err := scalarToJSON(rval.Index(i))

internal/fingerprint/versiontag.go

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ const excludeTag = "-"
2121
// keyPrefix is the fingerprint-tag prefix for an explicit emit-key override.
2222
const keyPrefix = "key="
2323

24-
// versionRange is one half-open or closed membership range in a version set.
24+
// versionRange is one closed (inclusive) membership range in a version set.
2525
// A range covers [low, high]; high == versionOpen means open-ended ("*").
2626
type versionRange struct {
2727
low int
@@ -66,6 +66,12 @@ func parseVersionSet(tag string, currentVersion int) (versionSet, error) {
6666
return versionSet{}, fmt.Errorf("empty key= override in fingerprint tag %#q", tag)
6767
}
6868

69+
if !isValidEmitKey(emitKey) {
70+
return versionSet{}, fmt.Errorf(
71+
"invalid key= override %#q in fingerprint tag %#q: must be a bare identifier "+
72+
"(letters, digits, '-', '_', '.')", emitKey, tag)
73+
}
74+
6975
set.emitKey = emitKey
7076
members = members[1:]
7177
}
@@ -95,10 +101,31 @@ func parseVersionSet(tag string, currentVersion int) (versionSet, error) {
95101
return set, nil
96102
}
97103

104+
// isValidEmitKey reports whether s is a bare emit-key identifier - the character
105+
// set of a frozen TOML key (letters, digits, '-', '_', '.'). The grammar's key=
106+
// override takes an identifier, so a malformed value like "foo bar" is rejected
107+
// up front rather than silently freezing an odd emit-key.
108+
func isValidEmitKey(s string) bool {
109+
for _, r := range s {
110+
switch {
111+
case r >= 'a' && r <= 'z', r >= 'A' && r <= 'Z', r >= '0' && r <= '9',
112+
r == '-', r == '_', r == '.':
113+
default:
114+
return false
115+
}
116+
}
117+
118+
return s != ""
119+
}
120+
98121
// parseRange parses a single "[!]vLow[..(vHigh|*)]" member.
99122
func parseRange(member string, currentVersion int) (versionRange, error) {
100123
rng := versionRange{}
101124

125+
// rangeText keeps the original member (including any leading '!') for error
126+
// messages, so a malformed "!v3..v1" is reported as written, not as "v3..v1".
127+
rangeText := member
128+
102129
if strings.HasPrefix(member, "!") {
103130
rng.alwaysEmit = true
104131
member = strings.TrimPrefix(member, "!")
@@ -126,20 +153,20 @@ func parseRange(member string, currentVersion int) (versionRange, error) {
126153
}
127154

128155
if highVersion < lowVersion {
129-
return versionRange{}, fmt.Errorf("range %#q is inverted: high bound is below low bound", member)
156+
return versionRange{}, fmt.Errorf("range %#q is inverted: high bound is below low bound", rangeText)
130157
}
131158

132159
rng.high = highVersion
133160
}
134161

135162
if rng.low > currentVersion {
136163
return versionRange{}, fmt.Errorf(
137-
"range %#q references v%d, which is beyond the current version v%d", member, rng.low, currentVersion)
164+
"range %#q references v%d, which is beyond the current version v%d", rangeText, rng.low, currentVersion)
138165
}
139166

140167
if rng.high != versionOpen && rng.high > currentVersion {
141168
return versionRange{}, fmt.Errorf(
142-
"range %#q references v%d, which is beyond the current version v%d", member, rng.high, currentVersion)
169+
"range %#q references v%d, which is beyond the current version v%d", rangeText, rng.high, currentVersion)
143170
}
144171

145172
return rng, nil

0 commit comments

Comments
 (0)