aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPřemysl Eric Janouch <p@janouch.name>2021-08-28 17:51:58 +0200
committerPřemysl Eric Janouch <p@janouch.name>2021-08-28 18:25:03 +0200
commitb082e82b625eca244ac0d1381c152f12b946d463 (patch)
treec8d38631f0934f55e43c8e9a9e97c672de5e450f
parentb8dbc70a9c1b9160c07e696b3a64655abc6b7d9d (diff)
downloadxK-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--NEWS2
-rw-r--r--xC.c64
2 files changed, 27 insertions, 39 deletions
diff --git a/NEWS b/NEWS
index 9edef71..2ce6791 100644
--- a/NEWS
+++ b/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"
diff --git a/xC.c b/xC.c
index 2b2bf73..e714c65 100644
--- a/xC.c
+++ b/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;