From caf059eba760a778e252f980532bd81b19683606 Mon Sep 17 00:00:00 2001 From: dualfroz Date: Fri, 4 Sep 2026 09:03:13 +0200 Subject: [PATCH] fix(convert): zero-pad each channel in RgbToHex RgbToHex emitted a single hex digit for channel values below 0x10 because strconv.FormatInt produces the minimal representation. This broke the fixed-width hex format, the round-trip with HexToRgb, and the hex2basicMap fast path in Rgb2basic. Format each channel with %02x, matching RgbTo256. --- convert.go | 4 +++- utils_test.go | 9 +++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/convert.go b/convert.go index 21344e7..81e3a3b 100644 --- a/convert.go +++ b/convert.go @@ -483,7 +483,9 @@ func RgbToHex(rgb []int) string { hexNodes := make([]string, 0, len(rgb)) for _, v := range rgb { - hexNodes = append(hexNodes, strconv.FormatInt(int64(v), 16)) + // Channels below 0x10 must keep two digits, or the fixed-width format and + // the round-trip with HexToRgb both break. + hexNodes = append(hexNodes, fmt.Sprintf("%02x", v)) } return strings.Join(hexNodes, "") } diff --git a/utils_test.go b/utils_test.go index b20c033..3b960d2 100644 --- a/utils_test.go +++ b/utils_test.go @@ -119,12 +119,21 @@ func TestRgbToHex(t *testing.T) { {"cccccc", []int{204, 204, 204}}, {"aabbcc", []int{170, 187, 204}}, {"aa99cd", []int{170, 153, 205}}, + // channels below 0x10 must be zero-padded to two hex digits + {"000000", []int{0, 0, 0}}, + {"010203", []int{1, 2, 3}}, + {"0a0b0c", []int{10, 11, 12}}, } for _, item := range tests { assert.Equal(t, RgbToHex(item.given), item.want) assert.Equal(t, Rgb2hex(item.given), item.want) } + + // RgbToHex must be the inverse of HexToRgb, including for small channels. + for _, hex := range []string{"010203", "000000", "0a0b0c", "aabbcc"} { + assert.Equal(t, RgbToHex(HexToRgb(hex)), hex) + } } func TestRgbToAnsi(t *testing.T) {