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: fixed displaying IRC colours above 16
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
// 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;