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:
parent
b8dbc70a9c
commit
b082e82b62
2
NEWS
2
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"
|
||||
|
||||
|
64
xC.c
64
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;
|
||||
|
Loading…
Reference in New Issue
Block a user