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; | 
