Skip to content

Commit

Permalink
appease Go 1.22's stricter base64 sanity checks
Browse files Browse the repository at this point in the history
We were using an alphabet with a duplicate character on purpose.
Go 1.21 was perfectly fine with that, but 1.22 started noticing:

    panic: encoding alphabet includes duplicate symbols

I can't fault the new sanity check, because it makes sense in general.
What we are doing here is slightly bizarre, because we don't care
about decoding the name hashes at all.

Appease the sanity check by replacing dashes with duplicate characters
as a follow-up step. While here, use "a" rather than "z",
which is more common and less likely to be noticeable.
  • Loading branch information
mvdan committed Oct 8, 2023
1 parent 82834ac commit a09f837
Showing 1 changed file with 9 additions and 5 deletions.
14 changes: 9 additions & 5 deletions hash.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,12 +181,11 @@ func buildidOf(path string) (string, error) {
var (
// Hashed names are base64-encoded.
// Go names can only be letters, numbers, and underscores.
// This means we can use base64's URL encoding, minus '-'.
// Use the URL encoding, replacing '-' with a duplicate 'z'.
// This means we can use base64's URL encoding, minus '-',
// which is later replaced with a duplicate 'a'.
// Such a lossy encoding is fine, since we never decode hashes.
// We don't need padding either, as we take a short prefix anyway.
nameCharset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_z"
nameBase64 = base64.NewEncoding(nameCharset).WithPadding(base64.NoPadding)
nameBase64 = base64.URLEncoding.WithPadding(base64.NoPadding)

b64NameBuffer [12]byte // nameBase64.EncodedLen(neededSumBytes) = 12
)
Expand Down Expand Up @@ -330,10 +329,15 @@ func hashWithCustomSalt(salt []byte, name string) string {
// in the ASCII table.
b64Name[0] += 'A' - '0'
}
// Keep the result equally exported or not, if it was an identifier.
if !token.IsIdentifier(name) {
return string(b64Name)
}
// Identifiers should remain valid and stay exported or unexported.
for i, b := range b64Name {
if b == '-' { // URL encoding uses dashes, which aren't valid
b64Name[i] = 'a'
}
}
if token.IsExported(name) {
if b64Name[0] == '_' {
// Turn "_foo" into "Zfoo".
Expand Down

0 comments on commit a09f837

Please sign in to comment.