diff options
author | Přemysl Eric Janouch <p@janouch.name> | 2021-08-28 17:51:58 +0200 |
---|---|---|
committer | Přemysl Eric Janouch <p@janouch.name> | 2021-08-28 18:25:03 +0200 |
commit | b082e82b625eca244ac0d1381c152f12b946d463 (patch) | |
tree | c8d38631f0934f55e43c8e9a9e97c672de5e450f | |
parent | b8dbc70a9c1b9160c07e696b3a64655abc6b7d9d (diff) | |
download | xK-b082e82b625eca244ac0d1381c152f12b946d463.tar.gz xK-b082e82b625eca244ac0d1381c152f12b946d463.tar.xz xK-b082e82b625eca244ac0d1381c152f12b946d463.zip |
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.
-rw-r--r-- | NEWS | 2 | ||||
-rw-r--r-- | xC.c | 64 |
2 files changed, 27 insertions, 39 deletions
@@ -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" @@ -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; |