Bug#304713: [patch] gtetrinet segfaults on some servers replies
when channel list is enabled
Julien Plissonneau Duquene
Julien Plissonneau Duquene
<debbug2005@julien.plissonneau.duquene.net>, 304713@bugs.debian.org
Thu, 14 Apr 2005 23:43:50 +0200
--VS++wcV0S1rZb1Fb
Content-Type: text/plain; charset=iso-8859-1
Content-Disposition: inline
Content-Transfer-Encoding: 8bit
Package: gtetrinet
Version: 0.7.8-1
Hello,
There is a lack of error checking in the function decoding server
replies that looks like /list replies, causing gtetrinet to crash
(segfault) when receiving replies to some commands from some servers.
For example, typing /who when connected to tetridome.com with channel
list enabled will crash gtetrinet. Actually each line in response to
/who on this server starts with an opening parenthesis, and thus is fed
to partyline_add_channel() for parsing.
The attached patch fixes partyline_add_channel in partyline.c so it does
not crash anymore on parsing errors. It does not fix side effects of
/whatever response being mistaken for /list response, including the fact
that the expected response text may not appear at all in the UI.
Regards,
Julien Plissonneau Duqučne
--VS++wcV0S1rZb1Fb
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename=patch
--- gtetrinet-0.7.8.orig/src/partyline.c 2004-12-26 16:59:45.000000000 +0100
+++ gtetrinet-0.7.8/src/partyline.c 2005-04-14 22:58:18.000000000 +0200
@@ -467,7 +467,7 @@
scan->config->skip_comment_single = FALSE;
while ((g_scanner_get_next_token (scan) != G_TOKEN_INT) && !g_scanner_eof (scan));
- num = scan->value.v_int;
+ num = (scan->token==G_TOKEN_INT) ? scan->value.v_int : 0;
g_scanner_get_next_token (scan); /* dump the ')' */
@@ -476,13 +476,13 @@
scan->config->cpair_comment_single = "# ";
while ((g_scanner_get_next_token (scan) != G_TOKEN_INT) && !g_scanner_eof (scan));
- actual = scan->value.v_int;
+ actual = (scan->token==G_TOKEN_INT) ? scan->value.v_int : 0;
while ((g_scanner_get_next_token (scan) != G_TOKEN_INT) && !g_scanner_eof (scan));
- max = scan->value.v_int;
+ max = (scan->token==G_TOKEN_INT) ? scan->value.v_int : 0;
while ((g_scanner_get_next_token (scan) != G_TOKEN_COMMENT_SINGLE) && !g_scanner_eof (scan));
- utf8 = g_locale_to_utf8 (scan->value.v_comment, -1, NULL, NULL, NULL);
+ utf8 = g_locale_to_utf8 ((scan->token==G_TOKEN_COMMENT_SINGLE) ? scan->value.v_comment : "", -1, NULL, NULL, NULL);
name = g_strconcat ("#", utf8, NULL);
g_snprintf (final, 1024, "%d/%d", actual, max);
@@ -490,7 +490,7 @@
scan->config->cpair_comment_single = "{}";
while ((g_scanner_get_next_token (scan) != G_TOKEN_COMMENT_SINGLE) && !g_scanner_eof (scan));
if (!g_scanner_eof (scan))
- state = g_strdup (scan->value.v_comment);
+ state = g_strdup ((scan->token==G_TOKEN_COMMENT_SINGLE) ? scan->value.v_comment : "");
else
state = g_strdup ("IDLE");
@@ -500,21 +500,21 @@
else
{
while ((g_scanner_get_next_token (scan) != G_TOKEN_COMMENT_SINGLE) && !g_scanner_eof (scan));
- utf8 = g_locale_to_utf8 (scan->value.v_comment, -1, NULL, NULL, NULL);
+ utf8 = g_locale_to_utf8 ((scan->token==G_TOKEN_COMMENT_SINGLE) ? scan->value.v_comment : "", -1, NULL, NULL, NULL);
name = g_strconcat ("#", utf8, NULL);
while ((g_scanner_get_next_token (scan) != G_TOKEN_IDENTIFIER) && !g_scanner_eof (scan));
- players = g_strdup (scan->value.v_identifier);
+ players = g_strdup ((scan->token==G_TOKEN_IDENTIFIER) ? scan->value.v_identifier : "");
if (players != NULL)
{
if (strncmp (players, "FULL", 4))
{
while ((g_scanner_get_next_token (scan) != G_TOKEN_INT) && !g_scanner_eof (scan));
- actual = scan->value.v_int;
+ actual = (scan->token==G_TOKEN_INT) ? scan->value.v_int : 0;
while ((g_scanner_get_next_token (scan) != G_TOKEN_INT) && !g_scanner_eof (scan));
- max = scan->value.v_int;
+ max = (scan->token==G_TOKEN_INT) ? scan->value.v_int : 0;
g_snprintf (final, 1024, "%d/%d %s", actual, max, players);
}
@@ -529,13 +529,13 @@
if (g_scanner_get_next_token (scan) == G_TOKEN_LEFT_CURLY)
{
g_scanner_get_next_token (scan);
- state = g_strdup (scan->value.v_identifier);
+ state = g_strdup ((scan->token==G_TOKEN_IDENTIFIER) ? scan->value.v_identifier : "");
}
else
state = g_strdup ("IDLE");
while ((g_scanner_get_next_token (scan) != G_TOKEN_RIGHT_PAREN) && !g_scanner_eof (scan));
- if (line[scan->position] != 0)
+ if (!g_scanner_eof(scan) && (scan->position < strlen(line)))
desc = g_strstrip (g_locale_to_utf8 (&line[scan->position], -1, NULL, NULL, NULL));
else
desc = g_strdup ("");
--VS++wcV0S1rZb1Fb--