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.
This commit is contained in:
Přemysl Eric Janouch 2021-08-28 17:51:58 +02:00
parent b8dbc70a9c
commit b082e82b62
Signed by: p
GPG Key ID: A0420B94F92B9493
2 changed files with 27 additions and 39 deletions

2
NEWS
View File

@ -2,6 +2,8 @@
* xC: made message autosplitting respect text formatting * xC: made message autosplitting respect text formatting
* xC: fixed displaying IRC colours above 16
1.3.0 (2021-08-07) "New World Order" 1.3.0 (2021-08-07) "New World Order"

64
xC.c
View File

@ -3191,7 +3191,7 @@ static const int g_mirc_to_terminal[] =
// https://modern.ircdocs.horse/formatting.html // https://modern.ircdocs.horse/formatting.html
// http://anti.teamidiot.de/static/nei/*/extended_mirc_color_proposal.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, 52, 94, 100, 58, 22, 29, 23, 24, 17, 54, 53, 89,
88, 130, 142, 64, 28, 35, 30, 25, 18, 91, 90, 125, 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 * 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)) if (!isdigit_ascii (*s))
{ {
FORMATTER_ADD_ITEM (self, FG_COLOR, .color = -1); *fg = *bg = 99;
FORMATTER_ADD_ITEM (self, BG_COLOR, .color = -1);
return s; return s;
} }
int fg = *s++ - '0'; *fg = *s++ - '0';
if (isdigit_ascii (*s)) if (isdigit_ascii (*s))
fg = fg * 10 + (*s++ - '0'); *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]));
if (*s != ',' || !isdigit_ascii (s[1])) if (*s != ',' || !isdigit_ascii (s[1]))
return s; return s;
s++; s++;
int bg = *s++ - '0'; *bg = *s++ - '0';
if (isdigit_ascii (*s)) 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) if (bg < 16)
FORMATTER_ADD_ITEM (self, BG_COLOR, .color = g_mirc_to_terminal[bg]); FORMATTER_ADD_ITEM (self, BG_COLOR, .color = g_mirc_to_terminal[bg]);
else else if (bg < 100)
FORMATTER_ADD_ITEM (self, BG_COLOR, 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; 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'); 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 // The text needs to be NUL-terminated
// TODO: try to deduplicate analogous code in formatter_parse_mirc() // TODO: try to deduplicate analogous code in formatter_parse_mirc()
static struct irc_char_attrs * 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 '\x16': next.attributes ^= TEXT_INVERSE; break;
case '\x03': case '\x03':
text = irc_analyze_mirc_color (text, &next.fg, &next.bg); text = irc_parse_mirc_color (text, &next.fg, &next.bg);
break; break;
case '\x0f': case '\x0f':
next = blank; next = blank;