From a09f837c1b9f78d8a4fc0db5498b43fb5f09e872 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Mart=C3=AD?= Date: Sun, 8 Oct 2023 22:55:35 +0100 Subject: [PATCH] appease Go 1.22's stricter base64 sanity checks 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. --- hash.go | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/hash.go b/hash.go index 3b300375..29dbb76f 100644 --- a/hash.go +++ b/hash.go @@ -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 ) @@ -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".