From b082e82b625eca244ac0d1381c152f12b946d463 Mon Sep 17 00:00:00 2001 From: Přemysl Eric Janouch Date: Sat, 28 Aug 2021 17:51:58 +0200 Subject: xC: fix displaying IRC colours above 16 First, we indexed the colour array without a required offset. Second, the data type was too small and overflowed negative. Detected during a refactor, which this is a part of. --- NEWS | 2 ++ xC.c | 64 +++++++++++++++++++++++++--------------------------------------- 2 files changed, 27 insertions(+), 39 deletions(-) diff --git a/NEWS b/NEWS index 9edef71..2ce6791 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,8 @@ * xC: made message autosplitting respect text formatting + * xC: fixed displaying IRC colours above 16 + 1.3.0 (2021-08-07) "New World Order" diff --git a/xC.c b/xC.c index 2b2bf73..e714c65 100644 --- a/xC.c +++ b/xC.c @@ -3191,7 +3191,7 @@ static const int g_mirc_to_terminal[] = // https://modern.ircdocs.horse/formatting.html // http://anti.teamidiot.de/static/nei/*/extended_mirc_color_proposal.html -static const char g_extra_to_256[100 - 16] = +static const int16_t g_extra_to_256[100 - 16] = { 52, 94, 100, 58, 22, 29, 23, 24, 17, 54, 53, 89, 88, 130, 142, 64, 28, 35, 30, 25, 18, 91, 90, 125, @@ -3203,36 +3203,45 @@ static const char g_extra_to_256[100 - 16] = }; static const char * -formatter_parse_mirc_color (struct formatter *self, const char *s) +irc_parse_mirc_color (const char *s, uint8_t *fg, uint8_t *bg) { if (!isdigit_ascii (*s)) { - FORMATTER_ADD_ITEM (self, FG_COLOR, .color = -1); - FORMATTER_ADD_ITEM (self, BG_COLOR, .color = -1); + *fg = *bg = 99; return s; } - int fg = *s++ - '0'; + *fg = *s++ - '0'; if (isdigit_ascii (*s)) - fg = fg * 10 + (*s++ - '0'); - if (fg < 16) - FORMATTER_ADD_ITEM (self, FG_COLOR, .color = g_mirc_to_terminal[fg]); - else - FORMATTER_ADD_ITEM (self, FG_COLOR, - .color = COLOR_256 (DEFAULT, g_extra_to_256[fg])); + *fg = *fg * 10 + (*s++ - '0'); if (*s != ',' || !isdigit_ascii (s[1])) return s; s++; - int bg = *s++ - '0'; + *bg = *s++ - '0'; if (isdigit_ascii (*s)) - bg = bg * 10 + (*s++ - '0'); + *bg = *bg * 10 + (*s++ - '0'); + return s; +} + +static const char * +formatter_parse_mirc_color (struct formatter *self, const char *s) +{ + uint8_t fg = 255, bg = 255; + s = irc_parse_mirc_color (s, &fg, &bg); + + if (fg < 16) + FORMATTER_ADD_ITEM (self, FG_COLOR, .color = g_mirc_to_terminal[fg]); + else if (fg < 100) + FORMATTER_ADD_ITEM (self, FG_COLOR, + .color = COLOR_256 (DEFAULT, g_extra_to_256[fg - 16])); + if (bg < 16) FORMATTER_ADD_ITEM (self, BG_COLOR, .color = g_mirc_to_terminal[bg]); - else + else if (bg < 100) FORMATTER_ADD_ITEM (self, BG_COLOR, - .color = COLOR_256 (DEFAULT, g_extra_to_256[bg])); + .color = COLOR_256 (DEFAULT, g_extra_to_256[bg - 16])); return s; } @@ -8257,29 +8266,6 @@ irc_serialize_char_attrs (const struct irc_char_attrs *attrs, struct str *out) if (attrs->attributes & TEXT_MONOSPACE) str_append_c (out, '\x11'); } -static const char * -irc_analyze_mirc_color (const char *s, uint8_t *fg, uint8_t *bg) -{ - if (!isdigit_ascii (*s)) - { - *fg = *bg = 99; - return s; - } - - *fg = *s++ - '0'; - if (isdigit_ascii (*s)) - *fg = *fg * 10 + (*s++ - '0'); - - if (*s != ',' || !isdigit_ascii (s[1])) - return s; - s++; - - *bg = *s++ - '0'; - if (isdigit_ascii (*s)) - *bg = *bg * 10 + (*s++ - '0'); - return s; -} - // The text needs to be NUL-terminated // TODO: try to deduplicate analogous code in formatter_parse_mirc() static struct irc_char_attrs * @@ -8303,7 +8289,7 @@ irc_analyze_text (const char *text, size_t len) case '\x16': next.attributes ^= TEXT_INVERSE; break; case '\x03': - text = irc_analyze_mirc_color (text, &next.fg, &next.bg); + text = irc_parse_mirc_color (text, &next.fg, &next.bg); break; case '\x0f': next = blank; -- cgit v1.2.3-70-g09d2