]> hydra-www.ietfng.org Git - gtetrinet/commitdiff
SECURITY FIXES: replace all uses of strcpy(), strcat(), strncpy() and strncat() with...
authorJordi Albornoz <jordi@src.gnome.org>
Sun, 27 Oct 2002 22:31:33 +0000 (22:31 +0000)
committerJordi Albornoz <jordi@src.gnome.org>
Sun, 27 Oct 2002 22:31:33 +0000 (22:31 +0000)
14 files changed:
ChangeLog
NEWS
src/client.c
src/commands.c
src/config.c
src/dialogs.c
src/fields.c
src/gtetrinet.c
src/misc.c
src/misc.h
src/partyline.c
src/sound.c
src/tetrinet.c
src/winlist.c

index d3276f9d7d84040fdaa3332da69ca7e48e56986d..6799bcab36938bdf8fcce323ba7996a9b636e33d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,29 @@
+2002-10-22  James Antill  <james@and.org>
+
+       * src/tetrinet.c (tetrinet_inmessage): Check all values from atoi()
+       for out of bounds.
+       (tetrinet_inmessage): Check all int values from sscanf() for out of
+       bounds.
+       (tetrinet_inmessage): Stop buffer overflows in sscanf() %s.
+       (tetrinet_inmessage): Protect playercount from overflow.
+       (speclist_add): Protect spectatorcount from overflow.
+
+2002-10-21  James Antill  <james@and.org>
+
+       * src/tetrinet.c: Convert hard coded color/attribute values into
+       constants and %c formats, when used in g_snprintf(). Readability.
+       
+       * src/*.c: Replace all uses of sprintf(), strcpy(), strcat(), 
+       strncpy() and strncat() with GTET_STRCPY() or GTET_STRCAT().
+
+       * src/config.c (config_getthemeinfo): Fixup buffer overflows on theme
+       info load.
+
+       * src/misc.h (GTET_STRCPY): Added safe strcpy() function.
+       (GTET_STRCAT): Added safe strcat() function.
+       (GTET_O_STRCPY): Added safe strcpy() function, with auto size.
+       (GTET_O_STRCAT): Added safe strcat() function, with auto size.
+
 2002-10-21  Jordi Mallach  <jordi@sindominio.net>
 
        * NEWS, configure.in: released gtetrinet 0.4.3.
diff --git a/NEWS b/NEWS
index fcac8cabd597da39d920898b8d63ffa6002362b3..acb6e2d57ca5ade4fc69def1c9a1651008cd8923 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,9 @@
+GTetrinet 0.4.4 - 2002-10-27
+- SECURITY FIX: multiple buffer overflows fixed all over the place.
+  This CAN be exploited REMOTELY, please upgrade ASAP.
+  Special thanks go to Steve Kemp for working on an exploit and its fix,
+  and James Antill for the patch which fixes the problems in this release.
+
 GTetrinet 0.4.3 - 2002-10-21
 - IPv6 support!
 - Add missing includes so i18n works correctly.
index 7ee9276126c152b219d7449fbe7e49cfa07cb71d..5fc404943d0e0ce1293ffd333bb44c2c7ac6d777 100644 (file)
@@ -175,8 +175,8 @@ void client_destroypipes (void)
 void client_init (char *s, char *n)
 {
     int i;
-    strcpy (server, s);
-    strcpy (nick, n);
+    GTET_O_STRCPY(server, s);
+    GTET_O_STRCPY(nick, n);
 
     /* wipe spaces off the nick */
     for (i = 0; nick[i]; i ++)
@@ -236,10 +236,10 @@ static void client_inputfunc (gpointer data, gint source,
 void client_outmessage (enum outmsg_type msgtype, char *str)
 {
     char buf[1024];
-    strcpy (buf, outmsg_translate (msgtype));
+    GTET_O_STRCPY(buf, outmsg_translate (msgtype));
     if (str) {
-        strcat (buf, " ");
-        strcat (buf, str);
+        GTET_O_STRCAT(buf, " ");
+        GTET_O_STRCAT(buf, str);
     }
     write (fdout[1], buf, strlen(buf));
     write (fdout[1], "\n", 1);
@@ -259,10 +259,10 @@ void client_process (void)
     if (client_connect () == -1) {
         char errmsg[1024];
 
-        strcpy (errmsg, "noconnecting ");
+        GTET_O_STRCPY(errmsg, "noconnecting ");
 
-        if (errno) strcat (errmsg, strerror (errno));
-        else if (h_errno) strcat (errmsg, "Unknown host");
+        if (errno)        GTET_O_STRCAT(errmsg, strerror (errno));
+        else if (h_errno) GTET_O_STRCAT(errmsg, "Unknown host");
 
         client_inmessage (errmsg);
 
@@ -410,27 +410,43 @@ int client_connect (void)
 
     /* say hello to the server */
     {
-        char buf[200], buf2[200];
+        GString *s1 = g_string_sized_new(80);
+        GString *s2 = g_string_sized_new(80);
         unsigned char ip[4];
-        unsigned char iphashbuf[6];
+        GString *iphashbuf = g_string_sized_new(11);
         int i, l, len;
+        
         /* construct message */
         if (gamemode == TETRIFAST)
-            sprintf (buf, "tetrifaster %s 1.13", nick);
+          g_string_sprintf (s1, "tetrifaster %s 1.13", nick);
         else
-            sprintf (buf, "tetrisstart %s 1.13", nick);
+          g_string_sprintf (s1, "tetrisstart %s 1.13", nick);
+
         /* do that encoding thingy */
         server_ip (ip);
-        sprintf (iphashbuf, "%d", ip[0]*54 + ip[1]*41 + ip[2]*29 + ip[3]*17);
-        l = strlen (iphashbuf);
-        buf2[0] = 0;
-        for (i = 0; buf[i]; i ++)
-            buf2[i+1] = (((buf2[i]&0xFF)+(buf[i]&0xFF))%255) ^ iphashbuf[i%l];
+        g_string_sprintf (iphashbuf, "%d",
+                          ip[0]*54 + ip[1]*41 + ip[2]*29 + ip[3]*17);
+        l = iphashbuf->len;
+
+        g_string_append_c(s2, 0);
+        for (i = 0; s1->str[i]; i ++)
+          g_string_append_c(s2, ((((s2->str[i] & 0xFF) +
+                                   (s1->str[i] & 0xFF)) % 255) ^
+                                 iphashbuf->str[i % l]));
+        g_assert(s1->len == i);
+        g_assert(s2->len == (i + 1));
         len = i + 1;
+
+        g_string_truncate(s1, 0);
         for (i = 0; i < len; i ++)
-            sprintf (buf+i*2, "%02X", buf2[i] & 0xFF);
+          g_string_sprintfa(s1, "%02X", s2->str[i] & 0xFF);
+
         /* now send to server */
-        client_sendmsg (buf);
+        client_sendmsg (s1->str);
+
+        g_string_free(s1, TRUE);
+        g_string_free(s2, TRUE);
+        g_string_free(iphashbuf, TRUE);
     }
     return 0;
 }
index b519397bccca9a81c116b9e98bfeb738b0401077..c42fac9b1580dd209a4d1692838cd8029b996283 100644 (file)
@@ -119,22 +119,22 @@ void detach_command (GtkWidget *widget, gpointer data)
 
 void start_command (GtkWidget *widget, gpointer data)
 {
-    char buf[16];
-    sprintf (buf, "%i %i", 1, playernum);
+    char buf[22];
+    g_snprintf (buf, sizeof(buf), "%i %i", 1, playernum);
     client_outmessage (OUT_STARTGAME, buf);
 }
 
 void end_command (GtkWidget *widget, gpointer data)
 {
-    char buf[16];
-    sprintf (buf, "%i %i", 0, playernum);
+    char buf[22];
+    g_snprintf (buf, sizeof(buf), "%i %i", 0, playernum);
     client_outmessage (OUT_STARTGAME, buf);
 }
 
 void pause_command (GtkWidget *widget, gpointer data)
 {
-    char buf[16];
-    sprintf (buf, "%i %i", paused?0:1, playernum);
+    char buf[22];
+    g_snprintf (buf, sizeof(buf), "%i %i", paused?0:1, playernum);
     client_outmessage (OUT_PAUSE, buf);
 }
 
@@ -207,8 +207,8 @@ void commands_checkstate ()
     if (ingame) partyline_status (_("Game in progress"));
     else if (connected) {
         char buf[256];
-        strcpy (buf, _("Connected to\n"));
-        strcat (buf, server);
+        GTET_O_STRCPY(buf, _("Connected to\n"));
+        GTET_O_STRCAT(buf, server);
         partyline_status (buf);
     }
     else partyline_status (_("Not connected"));
index 248033fae9ea5fc9b71aee862ac38887d7623114..8b67e46a3b7bfdf6671a7420b0f122fd421ec33e 100644 (file)
@@ -32,6 +32,7 @@
 #include "client.h"
 #include "tetrinet.h"
 #include "sound.h"
+#include "misc.h"
 
 char blocksfile[1024];
 int bsize;
@@ -69,9 +70,9 @@ void config_loadtheme (char *themedir)
     char buf[1024], *p;
     int i;
 
-    strcpy (buf, "=");
-    strcat (buf, themedir);
-    strcat (buf, "theme.cfg=/");
+    GTET_O_STRCPY(buf, "=");
+    GTET_O_STRCAT(buf, themedir);
+    GTET_O_STRCAT(buf, "theme.cfg=/");
 
     gnome_config_push_prefix (buf);
 
@@ -85,15 +86,15 @@ void config_loadtheme (char *themedir)
     else g_free (p);
 
     p = gnome_config_get_string ("Graphics/Blocks=blocks.png");
-    strcpy (blocksfile, themedir);
-    strncat (blocksfile, p, 256);
+    GTET_O_STRCPY(blocksfile, themedir);
+    GTET_O_STRCAT(blocksfile, p);
     g_free (p);
     bsize = gnome_config_get_int ("Graphics/BlockSize=16");
 
     p = gnome_config_get_string ("Sounds/MidiFile");
     if (p) {
-        strcpy (midifile, themedir);
-        strncat (midifile, p, 256);
+        GTET_O_STRCPY(midifile, themedir);
+        GTET_O_STRCAT(midifile, p);
         g_free (p);
     }
     else
@@ -102,8 +103,8 @@ void config_loadtheme (char *themedir)
     for (i = 0; i < S_NUM; i ++) {
         p = gnome_config_get_string (soundkeys[i]);
         if (p) {
-            strcpy (soundfiles[i], themedir);
-            strncat (soundfiles[i], p, 256);
+            GTET_O_STRCPY(soundfiles[i], themedir);
+            GTET_O_STRCAT(soundfiles[i], p);
             g_free (p);
         }
         else
@@ -115,13 +116,14 @@ void config_loadtheme (char *themedir)
     gnome_config_pop_prefix ();
 }
 
+/* Arrggh... all these params are sizeof() == 1024 ... this needs a real fix */
 int config_getthemeinfo (char *themedir, char *name, char *author, char *desc)
 {
     char buf[1024], *p;
 
-    strcpy (buf, "=");
-    strcat (buf, themedir);
-    strcat (buf, "theme.cfg=/");
+    GTET_O_STRCPY (buf, "=");
+    GTET_O_STRCAT (buf, themedir);
+    GTET_O_STRCAT (buf, "theme.cfg=/");
 
     gnome_config_push_prefix (buf);
 
@@ -131,17 +133,17 @@ int config_getthemeinfo (char *themedir, char *name, char *author, char *desc)
         return -1;
     }
     else {
-        if (name) strcpy (name, p);
+        if (name) GTET_STRCPY(name, p, 1024);
         g_free (p);
     }
     if (author) {
         p = gnome_config_get_string ("Theme/Author=");
-        strcpy (author, p);
+        GTET_STRCPY(author, p, 1024);
         g_free (p);
     }
     if (desc) {
         p = gnome_config_get_string ("Theme/Description=");
-        strcpy (desc, p);
+        GTET_STRCPY(desc, p, 1024);
         g_free (p);
     }
 
@@ -158,17 +160,16 @@ void config_loadconfig (void)
     gnome_config_push_prefix ("/"APPID"/");
 
     p = gnome_config_get_string ("Themes/ThemeDir="DEFAULTTHEME);
-    strncpy (currenttheme, p, 1024);
+    GTET_O_STRCPY(currenttheme, p);
     g_free (p);
     /* add trailing slash if none exists */
     l = strlen(currenttheme);
     if (currenttheme[l-1] != '/') {
-        currenttheme[l] = '/';
-        currenttheme[l+1] = 0;
+      GTET_O_STRCAT(currenttheme, "/");
     }
 
     p = gnome_config_get_string ("Sound/MidiPlayer="DEFAULTMIDICMD);
-    strncpy (midicmd, p, 1024);
+    GTET_O_STRCPY(midicmd, p);
     g_free (p);
 
     soundenable = gnome_config_get_int ("Sound/EnableSound=1");
@@ -176,13 +177,13 @@ void config_loadconfig (void)
 
     p = gnome_config_get_string ("Player/Nickname");
     if (p) {
-        strncpy (nick, p, 128);
+        GTET_O_STRCPY(nick, p);
         g_free(p);
     }
 
     p = gnome_config_get_string ("Player/Team");
     if (p) {
-        strncpy (team, p, 128);
+        GTET_O_STRCPY(team, p);
         g_free(p);
     }
 
index 8ab21682dc9a59a64c00f30445ed62c17aad060e..f38690c98bc3e850ff786fc05790fe6c895f8de3 100644 (file)
@@ -163,8 +163,8 @@ void connectdialog_button (GnomeDialog *dialog, gint button, gpointer data)
     case 0:
         /* connect now */
         spectating = GTK_TOGGLE_BUTTON(spectatorcheck)->active ? TRUE : FALSE;
-        strcpy (specpassword, gtk_entry_get_text (GTK_ENTRY(passwordentry)));
-        strcpy (team, gtk_entry_get_text (GTK_ENTRY(gnome_entry_gtk_entry(GNOME_ENTRY(teamnameentry)))));
+        GTET_O_STRCPY (specpassword, gtk_entry_get_text (GTK_ENTRY(passwordentry)));
+        GTET_O_STRCPY (team, gtk_entry_get_text (GTK_ENTRY(gnome_entry_gtk_entry(GNOME_ENTRY(teamnameentry)))));
         client_init (gtk_entry_get_text(GTK_ENTRY(gnome_entry_gtk_entry(GNOME_ENTRY(serveraddressentry)))),
                      gtk_entry_get_text(GTK_ENTRY(gnome_entry_gtk_entry(GNOME_ENTRY(nicknameentry)))));
         break;
@@ -476,7 +476,8 @@ void prefdialog_changekey (GtkWidget *widget, gpointer data)
 
     if (pk_row == -1) return;
 
-    sprintf (buf, _("Press new key for \"%s\""), actions[pk_row]);
+    g_snprintf (buf, sizeof(buf), _("Press new key for \"%s\""),
+                actions[pk_row]);
     k = key_dialog (buf);
     if (k) {
         newkeys[actionid[pk_row]] = k;
@@ -579,11 +580,11 @@ void prefdialog_themelist ()
     int i;
     char *basedir[2];
 
-    strcpy (dir, getenv ("HOME"));
-    strcat (dir, "/.gtetrinet/themes");
+    GTET_O_STRCPY (dir, getenv ("HOME"));
+    GTET_O_STRCAT (dir, "/.gtetrinet/themes");
 
-    basedir[0] = GTETRINET_THEMES;
-    basedir[1] = dir;
+    basedir[0] = dir; /* load users themes first ... in case we run out */
+    basedir[1] = GTETRINET_THEMES;
 
     themecount = 0;
 
@@ -591,20 +592,26 @@ void prefdialog_themelist ()
         d = opendir (basedir[i]);
         if (d) {
             while ((de = readdir(d))) {
-                strcpy (buf, basedir[i]);
-                strcat (buf, "/");
-                strcat (buf, de->d_name);
-                strcat (buf, "/");
+                GTET_O_STRCPY (buf, basedir[i]);
+                GTET_O_STRCAT (buf, "/");
+                GTET_O_STRCAT (buf, de->d_name);
+                GTET_O_STRCAT (buf, "/");
 
                 if (config_getthemeinfo(buf, str, NULL, NULL) == 0) {
-                    strcpy (themes[themecount].dir, buf);
-                    strcpy (themes[themecount].name, str);
+                    GTET_O_STRCPY (themes[themecount].dir, buf);
+                    GTET_O_STRCPY (themes[themecount].name, str);
                     themecount ++;
+                    if (themecount == (sizeof(themes) / sizeof(themes[0])))
+                    { /* FIXME: should be dynamic */
+                      g_warning("Too many theme files.\n");
+                      goto too_many_themes;
+                    }
                 }
             }
             closedir (d);
         }
     }
+ too_many_themes:
     qsort (themes, themecount, sizeof(struct themelistentry), themelistcomp);
 
     theme_select = 0;
@@ -639,7 +646,7 @@ void prefdialog_apply (GnomePropertyBox *dialog, gint pagenum)
         }
 
         if (themechanged) {
-            strcpy (currenttheme, themes[theme_select].dir);
+            GTET_O_STRCPY (currenttheme, themes[theme_select].dir);
             config_loadtheme (currenttheme);
 
             fields_page_destroy_contents ();
@@ -651,7 +658,7 @@ void prefdialog_apply (GnomePropertyBox *dialog, gint pagenum)
 
         if (midichanged) {
             midi = gtk_entry_get_text (GTK_ENTRY(gnome_entry_gtk_entry(GNOME_ENTRY(midientry))));
-            strcpy (midicmd, midi);
+            GTET_O_STRCPY (midicmd, midi);
         }
 
         if ((themechanged || midichanged) && ingame) {
index b5ae5fd7f5af855a76f3d9458d823ec9afd8f5f3..5b38ae8ac16d76dbaaa9ad0890f9775d17781dad 100644 (file)
@@ -388,9 +388,9 @@ void fields_drawblock (int field, int x, int y, char block)
 
 void fields_setlabel (int field, char *name, char *team, int num)
 {
-    char buf[10];
+    char buf[11];
 
-    sprintf (buf, "%d", num);
+    g_snprintf (buf, sizeof(buf), "%d", num);
     
     if (name == NULL) {
         gtk_widget_hide (fieldlabels[field][0]);
@@ -509,7 +509,7 @@ void fields_setlines (int l)
 {
     char buf[16] = "";
     if (l >= 0)
-        sprintf (buf, "%d", l);
+        g_snprintf (buf, sizeof(buf), "%d", l);
     leftlabel_set (lineswidget, buf);
 }
 
@@ -517,7 +517,7 @@ void fields_setlevel (int l)
 {
     char buf[16] = "";
     if (l > 0)
-        sprintf (buf, "%d", l);
+        g_snprintf (buf, sizeof(buf), "%d", l);
     leftlabel_set (levelwidget, buf);
 }
 
@@ -529,7 +529,7 @@ void fields_setactivelevel (int l)
         gtk_widget_hide (activewidget);
     }
     else {
-        sprintf (buf, "%d", l);
+        g_snprintf (buf, sizeof(buf), "%d", l);
         leftlabel_set (activewidget, buf);
         gtk_widget_show (activelabel);
         gtk_widget_show (activewidget);
@@ -570,7 +570,7 @@ void fields_gmsginputactivate (int t)
     if (t)
         gtk_widget_grab_focus (gmsginput);
     else
-        /* do nothing */;
+        { /* do nothing */; }
 }
 
 void fields_gmsginputadd (char *c)
@@ -583,7 +583,7 @@ void fields_gmsginputadd (char *c)
 void fields_gmsginputback (void)
 {
     char buf[256];
-    strcpy (buf, gtk_entry_get_text(GTK_ENTRY(gmsginput)));
+    GTET_O_STRCPY (buf, gtk_entry_get_text(GTK_ENTRY(gmsginput)));
     if (strlen(buf) == 0) return;
     buf[strlen(buf)-1] = 0;
     gtk_entry_set_text (GTK_ENTRY(gmsginput), buf);
index 08ea9f4c4896dcd6791621bc63eb0f26f26393ff..1c42a46f0f1b0cd91429544e6a3145731e6803e8 100644 (file)
@@ -74,7 +74,61 @@ static const struct poptOption options[] = {
 int main (int argc, char *argv[])
 {
     GtkWidget *page, *label, *box;
+    char buf[1024];
 
+    GTET_STRCPY(buf, "", 4);
+    g_assert(strlen(buf) == 0);
+    g_assert(buf[0] == 0);
+    
+    GTET_STRCAT(buf, "", 4);
+    g_assert(strlen(buf) == 0);
+    g_assert(buf[0] == 0);
+    
+    GTET_STRCPY(buf, "a", 1);
+    g_assert(strlen(buf) == 0);
+    g_assert(buf[0] == 0);
+    
+    GTET_STRCAT(buf, "a", 1);
+    g_assert(strlen(buf) == 0);
+    g_assert(buf[0] == 0);
+    
+    GTET_STRCPY(buf, "abcd", 4);
+    g_assert(strlen(buf) == 3);
+    g_assert(buf[3] == 0);
+    g_assert(buf[2] == 'c');
+    g_assert(buf[1] == 'b');
+    g_assert(buf[0] == 'a');
+    
+    GTET_STRCAT(buf, "xyz", 4);    
+    g_assert(strlen(buf) == 3);
+    g_assert(buf[3] == 0);
+    g_assert(buf[2] == 'c');
+    g_assert(buf[1] == 'b');
+    g_assert(buf[0] == 'a');
+    
+    GTET_STRCAT(buf, "abcd", 7);    
+    g_assert(strlen(buf) == 6);
+    g_assert(buf[6] == 0);
+    g_assert(buf[5] == 'c');
+    g_assert(buf[4] == 'b');
+    g_assert(buf[3] == 'a');
+    g_assert(buf[2] == 'c');
+    g_assert(buf[1] == 'b');
+    g_assert(buf[0] == 'a');
+    
+    GTET_O_STRCPY(buf, "abcd");
+    GTET_O_STRCAT(buf, "abcd");
+    g_assert(strlen(buf) == 8);
+    g_assert(buf[8] == 0);
+    g_assert(buf[7] == 'd');
+    g_assert(buf[6] == 'c');
+    g_assert(buf[5] == 'b');
+    g_assert(buf[4] == 'a');
+    g_assert(buf[3] == 'd');
+    g_assert(buf[2] == 'c');
+    g_assert(buf[1] == 'b');
+    g_assert(buf[0] == 'a');
+    
     setlocale(LC_ALL, "");
     bindtextdomain(PACKAGE, LOCALEDIR);
     textdomain(PACKAGE);
@@ -176,9 +230,9 @@ int main (int argc, char *argv[])
             option_connect, option_nick, option_team,
             option_pass, option_spec);
 #endif
-    if (option_nick) strcpy (nick, option_nick);
-    if (option_team) strcpy (team, option_team);
-    if (option_pass) strcpy (specpassword, option_pass);
+    if (option_nick) GTET_O_STRCPY(nick, option_nick);
+    if (option_team) GTET_O_STRCPY(team, option_team);
+    if (option_pass) GTET_O_STRCPY(specpassword, option_pass);
     if (option_spec) spectating = TRUE;
     if (option_connect) {
         client_init (option_connect, nick);
index d61109650961ba57ae1197647f1e87d1fcb5107c..9e62fbf6fa4f5b9d25ad4cb822da4d905c90b391 100644 (file)
@@ -140,9 +140,9 @@ void textbox_addtext (GtkText *textbox, unsigned char *text)
        }
         else if (text[i] < 32) {
             switch (text[i]) {
-            case 0x02: attr = attr ^ 0x01; break; /* bold */
-            case 0x16: attr = attr ^ 0x02; break; /* italics */
-            case 0x1F: break; /* underline not available */
+            case TETRI_TB_BOLD: attr = attr ^ 0x01; break; /* bold */
+            case TETRI_TB_ITALIC: attr = attr ^ 0x02; break; /* italics */
+            case TETRI_TB_UNDERLINE: break; /* underline not available */
             default: /* it is a color... */
                 if (text[i] > 0x1A) goto next; /* bounds checking */
                 if (text[i] == last) {
index 7dae59c67326c6ebcc20d63581db3677fb63e12d..d9292902c1b4d0b9868de230e28d136fe98a460f 100644 (file)
@@ -10,9 +10,56 @@ extern void adjust_bottom (GtkAdjustment *adj);
 extern char *nocolor (char *str);
 extern GtkWidget *pixmap_label (GdkPixmap *pm, GdkBitmap *mask, char *str);
 
+/* Better versions of the std. string functions */
+#define GTET_STRCPY(x, y, sz) G_STMT_START { \
+  size_t gtet_strcpy_x_sz = (sz); \
+  size_t gtet_strcpy_y_len = strlen(y); \
+  \
+  g_assert(gtet_strcpy_x_sz); \
+  \
+  if (gtet_strcpy_y_len >= gtet_strcpy_x_sz) \
+    gtet_strcpy_y_len = gtet_strcpy_x_sz - 1; \
+  \
+  if (gtet_strcpy_y_len) \
+    memcpy((x), (y), gtet_strcpy_y_len); \
+  (x)[gtet_strcpy_y_len] = 0; \
+ } G_STMT_END
+
+#define GTET_STRCAT(x, y, sz) G_STMT_START { \
+  size_t gtet_strcat_x_sz = (sz); \
+  size_t gtet_strcat_x_len = strlen(x); \
+  size_t gtet_strcat_y_len = strlen(y); \
+  \
+  g_assert(gtet_strcat_x_sz); \
+  \
+  if (gtet_strcat_x_len >= (gtet_strcat_x_sz - 1)) \
+    gtet_strcat_y_len = 0; \
+  \
+  gtet_strcat_x_sz -= gtet_strcat_x_len;  \
+  if (gtet_strcat_y_len >= gtet_strcat_x_sz) \
+    gtet_strcat_y_len = gtet_strcat_x_sz - 1; \
+  \
+  if (gtet_strcat_y_len) \
+    memcpy((x) + gtet_strcat_x_len, (y), gtet_strcat_y_len); \
+  (x)[gtet_strcat_x_len + gtet_strcat_y_len] = 0; \
+ } G_STMT_END
+
+/* these assume you are passing an "object", Ie. sizeof() returns the true
+ * size */
+#define GTET_O_STRCPY(x, y) G_STMT_START { \
+  g_assert(sizeof(x) > 4); GTET_STRCPY(x, y, sizeof(x)); \
+ } G_STMT_END
+
+#define GTET_O_STRCAT(x, y) G_STMT_START { \
+  g_assert(sizeof(x) > 4); GTET_STRCAT(x, y, sizeof(x)); \
+ } G_STMT_END
+
 /* textbox codes ... */
+#define TETRI_TB_RESET 0xFF
+
 #define TETRI_TB_BOLD 0x2
-#define TETRI_TB_UNDERLINE 0x16
+#define TETRI_TB_ITALIC 0x16
+#define TETRI_TB_UNDERLINE 0x1F
 
 /* colors... see colors[] in misc.c */
 #define TETRI_TB_C_CYAN 3
index 6bed189dad896c14e7d6ba45c7506983337e4693..ddc493032788fc306cae751b672f7919be3f0caf 100644 (file)
@@ -175,22 +175,24 @@ void partyline_text (char *text)
 void partyline_playerlist (int *numbers, char **names, char **teams, int n, char **specs, int sn)
 {
     int i;
-    char buf0[16], buf1[128], buf2[128], *item[3] = {buf0, buf1, buf2};
+    char buf0[16], buf1[128], buf2[128];
+    char *item[3] = {buf0, buf1, buf2};
+    
     /* update the playerlist so that it contains only the given names */
     gtk_clist_freeze (GTK_CLIST(playerlist));
     gtk_clist_clear (GTK_CLIST(playerlist));
     for (i = 0; i < n; i ++) {
-        sprintf (item[0], "%d", numbers[i]);
-        strcpy (item[1], nocolor(names[i]));
-        strcpy (item[2], nocolor(teams[i]));
+        g_snprintf (buf0, sizeof(buf0), "%d", numbers[i]);
+        GTET_O_STRCPY (buf1, nocolor(names[i]));
+        GTET_O_STRCPY (buf2, nocolor(teams[i]));
         gtk_clist_append (GTK_CLIST(playerlist), item);
     }
     buf0[0] = buf1[0] = buf2[0] = 0;
     gtk_clist_append (GTK_CLIST(playerlist), item);
     for (i = 0; i < sn; i ++) {
-        strcpy (item[0], "S");
-        strcpy (item[1], nocolor(specs[i]));
-        strcpy (item[2], "");
+        GTET_O_STRCPY (buf0, "S");
+        GTET_O_STRCPY (buf1, nocolor(specs[i]));
+        GTET_O_STRCPY (buf2, "");
         gtk_clist_append (GTK_CLIST(playerlist), item);
     }
     gtk_clist_thaw (GTK_CLIST(playerlist));
@@ -214,7 +216,7 @@ void textentry (GtkWidget *widget, gpointer data)
     if (strlen(text) == 0) return;
 
     tetrinet_playerline (text);
-    strcpy (plhistory[plh_end], text);
+    GTET_O_STRCPY (plhistory[plh_end], text);
     gtk_entry_set_text (GTK_ENTRY(widget), "");
 
     plh_end ++;
@@ -233,7 +235,7 @@ static gint entrykey (GtkWidget *widget, GdkEventKey *key)
         if (plh_cur == plh_end) {
             char *text;
             text = gtk_entry_get_text (GTK_ENTRY(widget));
-            strcpy (plhistory[plh_end], text);
+            GTET_O_STRCPY (plhistory[plh_end], text);
         }
         switch (keyval) {
         case GDK_Up:
index 32aeb8c828bd99f9eb2268fccf3c4384b14fb2fd..ea327d5ac95d00c55df66c99301558e68ba75424 100644 (file)
@@ -63,7 +63,6 @@ void sound_playsound (int id)
 void sound_playmidi (char *file)
 {
 #ifdef HAVE_PUTENV
-    char sz[1024];
 #endif
        
     sound_stopmidi();
@@ -74,8 +73,11 @@ void sound_playmidi (char *file)
 #ifdef HAVE_SETENV
         setenv ("MIDIFILE", file, TRUE);
 #elif HAVE_PUTENV
-        sprintf(sz, "MIDIFILE=%s", file);
+      {
+        char sz[1024];
+        g_snprintf(sz, sizeof(sz), "MIDIFILE=%s", file);
         putenv(sz);
+      }
 #else
 #error Need either setenv() or putenv()
 #endif
index 6ab5fb8873030771a7f813fc93dc251cf5b9b410..4f730cb96edb1ff1a9f9de624704115953057acc 100644 (file)
@@ -53,10 +53,12 @@ int playernum = 0;
 int moderatornum = 0;
 char team[128], nick[128], specpassword[128];
 
-char playernames[7][128];
-char teamnames[7][128];
-int playerlevels[7];
-int playerplaying[7];
+#define MAX_PLAYERS 7
+
+char playernames[MAX_PLAYERS][128];
+char teamnames[MAX_PLAYERS][128];
+int playerlevels[MAX_PLAYERS];
+int playerplaying[MAX_PLAYERS];
 int playercount = 0;
 
 char spectatorlist[128][128];
@@ -78,8 +80,16 @@ int gmsgstate;
 int bigfieldnum;
 
 /* game options from the server */
-int initialstackheight, initiallevel, linesperlevel, levelinc,
-    speciallines, specialcount, specialcapacity, levelaverage, classicmode;
+int initialstackheight; /* height of random crap */
+int initiallevel; /* speed speed level */
+int linesperlevel; /* number of lines before you go up a level */
+int levelinc; /* amount you go level up, after every linesperlevel */
+int speciallines; /* ratio of lines needed for special blocks */
+int specialcount; /* multiplier for special blocks to add */
+int specialcapacity; /* max number of specials you can have */
+int levelaverage; /* flag: should we average the levels across all players */
+int classicmode; /* bitflag: does everyone get lines of blocks when you
+                  * 2x, 3x or tetris */
 
 /* these are actually cumulative frequency counts */
 int blockfreq[7];
@@ -152,6 +162,7 @@ static FIELD sentfield; /* the field that the server thinks we have */
  */
 void tetrinet_inmessage (enum inmsg_type msgtype, char *data)
 {
+    int tmp_pnum = 0;
     char buf[1024];
     if (msgtype != IN_PLAYERJOIN && msgtype != IN_PLAYERLEAVE && msgtype != IN_TEAM &&
         msgtype != IN_PLAYERNUM && msgtype != IN_CONNECT && msgtype != IN_F && msgtype != IN_WINLIST) {
@@ -194,20 +205,23 @@ void tetrinet_inmessage (enum inmsg_type msgtype, char *data)
         {
             GtkWidget *dialog;
             connectingdialog_destroy ();
-            strcpy (buf, _("Error connecting: "));
-            strcat (buf, data);
+            GTET_O_STRCPY (buf, _("Error connecting: "));
+            GTET_O_STRCAT (buf, data);
             dialog = gnome_message_box_new (buf, GNOME_MESSAGE_BOX_ERROR,
                                             GNOME_STOCK_BUTTON_OK, NULL);
             gtk_widget_show (dialog);
         }
         break;
     case IN_PLAYERNUM:
-        bigfieldnum = playernum = atoi (data);
+        tmp_pnum = atoi (data);
+        if (tmp_pnum >= MAX_PLAYERS)
+          break;
+        bigfieldnum = playernum = tmp_pnum;
         if (!connected)
         {
             /* we have successfully connected */
             if (spectating) {
-                sprintf (buf, "%d %s", playernum, specpassword);
+                g_snprintf (buf, sizeof(buf), "%d %s", playernum, specpassword);
                 client_outmessage (OUT_TEAM, buf);
                 client_outmessage (OUT_VERSION, APPNAME"-"APPVERSION);
                 partyline_namelabel (nick, NULL);
@@ -227,10 +241,10 @@ void tetrinet_inmessage (enum inmsg_type msgtype, char *data)
         }
         if (!spectating) {
             /* set own player/team info */
-            strcpy (playernames[playernum], nick);
-            strcpy (teamnames[playernum], team);
+            GTET_O_STRCPY (playernames[playernum], nick);
+            GTET_O_STRCPY (teamnames[playernum], team);
             /* send team info */
-            sprintf (buf, "%d %s", playernum, team);
+            g_snprintf (buf, sizeof(buf), "%d %s", playernum, team);
             client_outmessage (OUT_TEAM, buf);
             /* update display */
             playerlistupdate ();
@@ -251,10 +265,12 @@ void tetrinet_inmessage (enum inmsg_type msgtype, char *data)
             token = strtok (data, " ");
             if (token == NULL) break;
             pnum = atoi (token);
+            if (pnum >= MAX_PLAYERS)
+              break;
             token = strtok (NULL, "");
             if (token == NULL) break;
             if (playernames[pnum][0] == 0) playercount ++;
-            strcpy (playernames[pnum], token);
+            GTET_O_STRCPY (playernames[pnum], token);
             teamnames[pnum][0] = 0;
             playerlistupdate ();
             /* update fields display */
@@ -275,6 +291,10 @@ void tetrinet_inmessage (enum inmsg_type msgtype, char *data)
             token = strtok (data, " ");
             if (token == NULL) break;
             pnum = atoi (token);
+            if (pnum >= MAX_PLAYERS)
+              break;
+            if (!playercount)
+              break;
             playercount --;
             if (playernames[pnum][0]) {
                 /* display */
@@ -299,10 +319,18 @@ void tetrinet_inmessage (enum inmsg_type msgtype, char *data)
             token = strtok (data, " ");
             if (token == NULL) break;
             pnum = atoi (token);
+            if (pnum >= MAX_PLAYERS)
+              break;
             if ((pnum == playernum) && !spectating)
-                sprintf (buf, "\014\02*** You have been kicked from the game");
+                g_snprintf (buf, sizeof(buf),
+                            "%c%c*** You have been kicked from the game",
+                            TETRI_TB_C_DARK_GREEN, TETRI_TB_BOLD);
             else
-                sprintf (buf, "\014*** \02%s\377\014 has been kicked from the game", playernames[pnum]);
+                g_snprintf (buf, sizeof(buf),
+                            "%c*** %c%s%c%c has been kicked from the game",
+                            TETRI_TB_C_DARK_GREEN, TETRI_TB_BOLD,
+                            playernames[pnum],
+                            TETRI_TB_RESET, TETRI_TB_C_DARK_GREEN);
             partyline_text (buf);
             /*
              mark it so that leave message is not displayed when playerleave
@@ -319,9 +347,11 @@ void tetrinet_inmessage (enum inmsg_type msgtype, char *data)
             token = strtok (data, " ");
             if (token == NULL) break;
             pnum = atoi (token);
+            if (pnum >= MAX_PLAYERS)
+              break;
             token = strtok (NULL, "");
             if (token == NULL) token = "";
-            strcpy (teamnames[pnum], token);
+            GTET_O_STRCPY (teamnames[pnum], token);
             playerlistupdate ();
             /* update fields display */
             fieldslabelupdate ();
@@ -336,6 +366,8 @@ void tetrinet_inmessage (enum inmsg_type msgtype, char *data)
             token = strtok (data, " ");
             if (token == NULL) break;
             pnum = atoi (token);
+            if (pnum >= MAX_PLAYERS)
+              break;
             token = strtok (NULL, "");
             if (token == NULL) token = "";
             if (pnum == 0) {
@@ -344,7 +376,7 @@ void tetrinet_inmessage (enum inmsg_type msgtype, char *data)
                     tetrix = TRUE;
                 }
                 else if (tetrix) {
-                    sprintf (buf, "*** %s", token);
+                    g_snprintf (buf, sizeof(buf), "*** %s", token);
                     partyline_text (buf);
                     break;
                 }
@@ -360,6 +392,8 @@ void tetrinet_inmessage (enum inmsg_type msgtype, char *data)
             token = strtok (data, " ");
             if (token == NULL) break;
             pnum = atoi (token);
+            if (pnum >= MAX_PLAYERS)
+              break;
             token = strtok (NULL, "");
             if (token == NULL) token = "";
             /* display it */
@@ -370,6 +404,8 @@ void tetrinet_inmessage (enum inmsg_type msgtype, char *data)
         {
             int pnum;
             pnum = atoi (data);
+            if (pnum >= MAX_PLAYERS)
+              break;
             /* player is out */
             playerplaying[pnum] = 0;
         }
@@ -378,12 +414,20 @@ void tetrinet_inmessage (enum inmsg_type msgtype, char *data)
         {
             int pnum;
             pnum = atoi (data);
+            if (pnum >= MAX_PLAYERS)
+              break;
             if (teamnames[pnum][0])
-                sprintf (buf, "\020*** Team \02%s\377\020 has won the game",
-                         teamnames[pnum]);
+                g_snprintf (buf, sizeof(buf),
+                            "%c*** Team %c%s%c%c has won the game",
+                            TETRI_TB_C_DARK_RED, TETRI_TB_BOLD,
+                            teamnames[pnum],
+                            TETRI_TB_RESET, TETRI_TB_C_DARK_RED);
             else
-                sprintf (buf, "\020*** \02%s\377\020 has won the game",
-                         playernames[pnum]);
+                g_snprintf (buf, sizeof(buf),
+                            "%c*** %c%s%c%c has won the game",
+                            TETRI_TB_C_DARK_RED, TETRI_TB_BOLD,
+                            playernames[pnum],
+                            TETRI_TB_RESET, TETRI_TB_C_DARK_RED);
             partyline_text (buf);
         }
         break;
@@ -391,11 +435,31 @@ void tetrinet_inmessage (enum inmsg_type msgtype, char *data)
         {
             int i, j;
             char bfreq[128], sfreq[128];
-            sscanf (data, "%d %d %d %d %d %d %d %s %s %d %d",
+            sscanf (data, "%d %d %d %d %d %d %d %128s %128s %d %d",
                     &initialstackheight, &initiallevel,
                     &linesperlevel, &levelinc, &speciallines,
                     &specialcount, &specialcapacity,
                     bfreq, sfreq, &levelaverage, &classicmode);
+
+            bfreq[127] = 0;
+            sfreq[127] = 0;
+            
+            /* initialstackheight == seems ok */
+            /* initiallevel == seems ok */
+            /* linesperlevel == seems ok */
+            /* levelinc == seems ok */
+            
+            if (!speciallines) /* does divide by this number */
+              speciallines = 1;
+            
+            /* specialcount == seems ok */
+            
+            if ((unsigned int)specialcapacity > sizeof(specialblocks))
+              specialcapacity = sizeof(specialblocks);
+            
+            /* levelaverage == seems ok */
+            /* classicmode == seems ok */
+            
             /*
              decoding the 11233345666677777 block frequecy thingies:
              */
@@ -475,6 +539,8 @@ void tetrinet_inmessage (enum inmsg_type msgtype, char *data)
             s = strtok (data, " ");
             if (s == NULL) break;
             pnum = atoi (s);
+            if (pnum >= MAX_PLAYERS)
+              break;
             s = strtok (NULL, "");
             if (s == NULL) break;
             if (*s >= '0') {
@@ -488,7 +554,7 @@ void tetrinet_inmessage (enum inmsg_type msgtype, char *data)
                 int block = 0, x, y;
                 for(; *s; s++) {
                     if (*s < '0' && *s >= '!') block = *s - '!';
-                    else {
+                    else { /* welcome to ASCII hell, x and y tested though */
                         x = *s - '3';
                         y = *(++s) - '3';
                         if (x >= 0 && x < FIELDWIDTH && y >= 0 && y < FIELDHEIGHT)
@@ -507,11 +573,15 @@ void tetrinet_inmessage (enum inmsg_type msgtype, char *data)
             token = strtok (data, " ");
             if (token == NULL) break;
             to = atoi (token);
+            if (to >= MAX_PLAYERS)
+              break;
             sbid = strtok (NULL, " ");
             if (sbid == NULL) break;
             token = strtok (NULL, "");
             if (token == NULL) break;
             from = atoi(token);
+            if (from >= MAX_PLAYERS)
+              break;
             for (sbnum = 0; sbinfo[sbnum].id; sbnum ++)
                 if (strcmp (sbid, sbinfo[sbnum].id) == 0) break;
             if (!sbinfo[sbnum].id) break;
@@ -525,6 +595,8 @@ void tetrinet_inmessage (enum inmsg_type msgtype, char *data)
             token = strtok (data, " ");
             if (token == NULL) break;
             pnum = atoi (token);
+            if (pnum >= MAX_PLAYERS)
+              break;
             token = strtok (NULL, "");
             if (token == NULL) break;
             playerlevels[pnum] = atoi (token);
@@ -564,7 +636,9 @@ void tetrinet_inmessage (enum inmsg_type msgtype, char *data)
             speclist_clear ();
             token = strtok (data, " ");
             if (token == NULL) break;
-            sprintf (buf, "\021*** You have joined \02%s", token);
+            g_snprintf (buf, sizeof(buf),
+                        "%c*** You have joined %c%s",
+                        TETRI_TB_C_DARK_BLUE, TETRI_TB_BOLD, token);
             partyline_text (buf);
             while ((token = strtok (NULL, " ")) != NULL) speclist_add (token);
             playerlistupdate ();
@@ -578,7 +652,15 @@ void tetrinet_inmessage (enum inmsg_type msgtype, char *data)
             speclist_add (name);
             info = strtok (NULL, "");
             if (info == NULL) info = "";
-            sprintf (buf, "\021*** \02%s\377\021 has joined the spectators \06\02(\02%s\337\06\02)", name, info);
+            g_snprintf (buf, sizeof(buf),
+                        "%c*** %c%s%c%c has joined the spectators"
+                        " %c%c(%c%s%c%c%c)",
+                        TETRI_TB_C_DARK_BLUE, TETRI_TB_BOLD,
+                        name,
+                        TETRI_TB_RESET, TETRI_TB_C_DARK_BLUE,
+                        TETRI_TB_C_GREY, TETRI_TB_BOLD,  TETRI_TB_BOLD,
+                        info,
+                        TETRI_TB_RESET, TETRI_TB_C_GREY, TETRI_TB_BOLD);
             partyline_text (buf);
             playerlistupdate ();
         }
@@ -591,7 +673,15 @@ void tetrinet_inmessage (enum inmsg_type msgtype, char *data)
             speclist_remove (name);
             info = strtok (NULL, "");
             if (info == NULL) info = "";
-            sprintf (buf, "\021*** \02%s\377\021 has left the spectators \06\02(\02%s\337\06\02)", name, info);
+            g_snprintf (buf, sizeof(buf),
+                        "%c*** %c%s%c%c has left the spectators"
+                        " %c%c(%c%s%c%c%c)",
+                        TETRI_TB_C_DARK_BLUE, TETRI_TB_BOLD,
+                        name,
+                        TETRI_TB_RESET, TETRI_TB_C_DARK_BLUE,
+                        TETRI_TB_C_GREY, TETRI_TB_BOLD,  TETRI_TB_BOLD,
+                        info,
+                        TETRI_TB_RESET, TETRI_TB_C_GREY, TETRI_TB_BOLD);
             partyline_text (buf);
             playerlistupdate ();
         }
@@ -630,7 +720,7 @@ void tetrinet_playerline (char *text)
         if (strncasecmp (p, "me ", 3) == 0) {
             p += 3;
             while (*p && isspace(*p)) p++;
-            sprintf (buf, "%d %s", playernum, p);
+            g_snprintf (buf, sizeof(buf), "%d %s", playernum, p);
             client_outmessage (OUT_PLINEACT, buf);
             if (spectating)
                 plinesact (nick, p);
@@ -639,12 +729,12 @@ void tetrinet_playerline (char *text)
             return;
         }
         if (tetrix) {
-            sprintf (buf, "%d %s", playernum, text);
+            g_snprintf (buf, sizeof(buf), "%d %s", playernum, text);
             client_outmessage (OUT_PLINE, buf);
             return;
         }
     }
-    sprintf (buf, "%d %s", playernum, text);
+    g_snprintf (buf, sizeof(buf), "%d %s", playernum, text);
     client_outmessage (OUT_PLINE, buf);
     if (spectating)
         plinesmsg (nick, text);
@@ -656,10 +746,10 @@ void tetrinet_changeteam (char *newteam)
 {
     char buf[128];
 
-    strcpy (team, newteam);
+    GTET_O_STRCPY (team, newteam);
 
     if (connected) {
-        sprintf (buf, "%d %s", playernum, team);
+        g_snprintf (buf, sizeof(buf), "%d %s", playernum, team);
         client_outmessage (OUT_TEAM, buf);
         tetrinet_inmessage (IN_TEAM, buf);
         partyline_namelabel (nick, team);
@@ -673,7 +763,7 @@ void tetrinet_sendfield (int reset)
 
     if (reset) goto sendwholefield;
 
-    sprintf (buf, "%d ", playernum);
+    g_snprintf (buf, sizeof(buf), "%d ", playernum);
     /* find differences between the fields */
     for (i = 0; i < 15; i ++) {
         p = buf2 + 1;
@@ -688,7 +778,7 @@ void tetrinet_sendfield (int reset)
                 }
         if (p > buf2+1) {
             *p = 0;
-            strcat (buf, buf2);
+            GTET_O_STRCAT (buf, buf2);
             d = TRUE;
         }
     }
@@ -701,7 +791,7 @@ void tetrinet_sendfield (int reset)
             for (x = 0; x < FIELDWIDTH; x ++)
                 *p++ = blocks[(int)fields[playernum][y][x]];
         *p = 0;
-        sprintf (buf, "%d %s", playernum, buf2);
+        g_snprintf (buf, sizeof(buf), "%d %s", playernum, buf2);
     }
     /* send it */
     client_outmessage (OUT_F, buf);
@@ -723,7 +813,7 @@ void tetrinet_resendfield (void)
         for (x = 0; x < FIELDWIDTH; x ++)
             *p++ = blocks[(int)sentfield[y][x]];
     *p = 0;
-    sprintf (buf, "%d %s", playernum, buf2);
+    g_snprintf (buf, sizeof(buf), "%d %s", playernum, buf2);
     client_outmessage (OUT_F, buf);
 }
 
@@ -834,19 +924,19 @@ void tetrinet_dospecial (int from, int to, int type)
       case S_ADDALL4: /* bad for everyone ... */
         g_assert(!to);
         if (from == playernum)
-          sprintf (buf, "%c%c%s%c%c",
-                   TETRI_TB_BOLD,
-                   TETRI_TB_C_BLACK,
-                   sbinfo[type].info,
-                   TETRI_TB_C_BLACK,
-                   TETRI_TB_BOLD);
+          g_snprintf (buf, sizeof(buf), "%c%c%s%c%c",
+                      TETRI_TB_BOLD,
+                      TETRI_TB_C_BLACK,
+                      sbinfo[type].info,
+                      TETRI_TB_C_BLACK,
+                      TETRI_TB_BOLD);
         else
-          sprintf (buf, "%c%c%s%c%c",
-                   TETRI_TB_BOLD,
-                   TETRI_TB_C_BRIGHT_RED,
-                   sbinfo[type].info,
-                   TETRI_TB_C_BRIGHT_RED,
-                   TETRI_TB_BOLD);
+          g_snprintf (buf, sizeof(buf), "%c%c%s%c%c",
+                      TETRI_TB_BOLD,
+                      TETRI_TB_C_BRIGHT_RED,
+                      sbinfo[type].info,
+                      TETRI_TB_C_BRIGHT_RED,
+                      TETRI_TB_BOLD);
         break;
         
       case S_ADDLINE:
@@ -855,26 +945,26 @@ void tetrinet_dospecial (int from, int to, int type)
       case S_BLOCKQUAKE:
       case S_BLOCKBOMB: /* badish stuff for someone */
         if (to == playernum)
-          sprintf (buf, "%c%c%s%c%c",
-                   TETRI_TB_BOLD,
-                   TETRI_TB_C_BRIGHT_RED,
-                   sbinfo[type].info,
-                   TETRI_TB_C_BRIGHT_RED,
-                   TETRI_TB_BOLD);
+          g_snprintf (buf, sizeof(buf), "%c%c%s%c%c",
+                      TETRI_TB_BOLD,
+                      TETRI_TB_C_BRIGHT_RED,
+                      sbinfo[type].info,
+                      TETRI_TB_C_BRIGHT_RED,
+                      TETRI_TB_BOLD);
         else if (from == playernum)
-          sprintf (buf, "%c%c%s%c%c",
-                   TETRI_TB_BOLD,
-                   TETRI_TB_C_BLACK,
-                   sbinfo[type].info,
-                   TETRI_TB_C_BLACK,
-                   TETRI_TB_BOLD);
+          g_snprintf (buf, sizeof(buf), "%c%c%s%c%c",
+                      TETRI_TB_BOLD,
+                      TETRI_TB_C_BLACK,
+                      sbinfo[type].info,
+                      TETRI_TB_C_BLACK,
+                      TETRI_TB_BOLD);
         else
-          sprintf (buf, "%c%c%s%c%c",
-                   TETRI_TB_BOLD,
-                   TETRI_TB_C_DARK_RED,
-                   sbinfo[type].info,
-                   TETRI_TB_C_DARK_RED,
-                   TETRI_TB_BOLD);
+          g_snprintf (buf, sizeof(buf), "%c%c%s%c%c",
+                      TETRI_TB_BOLD,
+                      TETRI_TB_C_DARK_RED,
+                      sbinfo[type].info,
+                      TETRI_TB_C_DARK_RED,
+                      TETRI_TB_BOLD);
         break;
 
       case S_CLEARLINE:
@@ -882,19 +972,19 @@ void tetrinet_dospecial (int from, int to, int type)
       case S_SWITCH:
       case S_GRAVITY: /* goodish stuff for someone */
         if (to == playernum)
-          sprintf (buf, "%c%c%s%c%c",
-                   TETRI_TB_BOLD,
-                   TETRI_TB_C_BRIGHT_GREEN,
-                   sbinfo[type].info,
-                   TETRI_TB_C_BRIGHT_GREEN,
-                   TETRI_TB_BOLD);
+          g_snprintf (buf, sizeof(buf), "%c%c%s%c%c",
+                      TETRI_TB_BOLD,
+                      TETRI_TB_C_BRIGHT_GREEN,
+                      sbinfo[type].info,
+                      TETRI_TB_C_BRIGHT_GREEN,
+                      TETRI_TB_BOLD);
         else
-          sprintf (buf, "%c%c%s%c%c",
-                   TETRI_TB_BOLD,
-                   TETRI_TB_C_DARK_GREEN,
-                   sbinfo[type].info,
-                   TETRI_TB_C_DARK_GREEN,
-                   TETRI_TB_BOLD);
+          g_snprintf (buf, sizeof(buf), "%c%c%s%c%c",
+                      TETRI_TB_BOLD,
+                      TETRI_TB_C_DARK_GREEN,
+                      sbinfo[type].info,
+                      TETRI_TB_C_DARK_GREEN,
+                      TETRI_TB_BOLD);
         break;
         
       default:
@@ -903,43 +993,43 @@ void tetrinet_dospecial (int from, int to, int type)
       
     if (to) {
       if (to == playernum)
-        sprintf (buf2, " on %c%c%s%c%c",
-                 TETRI_TB_BOLD,
-                 TETRI_TB_C_BRIGHT_BLUE,
-                 playernames[to],
-                 TETRI_TB_C_BRIGHT_BLUE,
-                 TETRI_TB_BOLD);
+        g_snprintf (buf2, sizeof(buf2), " on %c%c%s%c%c",
+                    TETRI_TB_BOLD,
+                    TETRI_TB_C_BRIGHT_BLUE,
+                    playernames[to],
+                    TETRI_TB_C_BRIGHT_BLUE,
+                    TETRI_TB_BOLD);
       else
-        sprintf (buf2, " on %c%c%s%c%c",
-                 TETRI_TB_BOLD,
-                 TETRI_TB_C_DARK_BLUE,
-                 playernames[to],
-                 TETRI_TB_C_DARK_BLUE,
-                 TETRI_TB_BOLD);
-        strcat (buf, buf2);
+        g_snprintf (buf2, sizeof(buf2), " on %c%c%s%c%c",
+                    TETRI_TB_BOLD,
+                    TETRI_TB_C_DARK_BLUE,
+                    playernames[to],
+                    TETRI_TB_C_DARK_BLUE,
+                    TETRI_TB_BOLD);
+        GTET_O_STRCAT (buf, buf2);
     }
     else
     {
-      sprintf (buf2, " to All");
-      strcat (buf, buf2);
+      g_snprintf (buf2, sizeof(buf2), " to All");
+      GTET_O_STRCAT (buf, buf2);
     }
     
     if (from) {
       if (from == playernum)
-        sprintf (buf2, " by %c%c%s%c%c",
-                 TETRI_TB_BOLD,
-                 TETRI_TB_C_BRIGHT_BLUE,
-                 playernames[from],
-                 TETRI_TB_C_BRIGHT_BLUE,
-                 TETRI_TB_BOLD);
+        g_snprintf (buf2, sizeof(buf2), " by %c%c%s%c%c",
+                    TETRI_TB_BOLD,
+                    TETRI_TB_C_BRIGHT_BLUE,
+                    playernames[from],
+                    TETRI_TB_C_BRIGHT_BLUE,
+                    TETRI_TB_BOLD);
       else
-        sprintf (buf2, " by %c%c%s%c%c",
-                 TETRI_TB_BOLD,
-                 TETRI_TB_C_DARK_BLUE,
-                 playernames[from],
-                 TETRI_TB_C_DARK_BLUE,
-                 TETRI_TB_BOLD);
-        strcat (buf, buf2);
+        g_snprintf (buf2, sizeof(buf2), " by %c%c%s%c%c",
+                    TETRI_TB_BOLD,
+                    TETRI_TB_C_DARK_BLUE,
+                    playernames[from],
+                    TETRI_TB_C_DARK_BLUE,
+                    TETRI_TB_BOLD);
+        GTET_O_STRCAT (buf, buf2);
     }
     fields_attdefmsg (buf);
 
@@ -1170,7 +1260,7 @@ void tetrinet_resumegame (void)
 void tetrinet_playerlost (void)
 {
     int x, y;
-    char buf[10];
+    char buf[11];
     FIELD field;
     playing = FALSE;
     /* fix up the display */
@@ -1183,7 +1273,7 @@ void tetrinet_playerlost (void)
     /* send field */
     tetrinet_sendfield (1);
     /* post message */
-    sprintf (buf, "%d", playernum);
+    g_snprintf (buf, sizeof(buf), "%d", playernum);
     client_outmessage (OUT_PLAYERLOST, buf);
     /* make a sound */
     sound_playsound (S_YOULOSE);
@@ -1348,7 +1438,8 @@ int tetrinet_removelines ()
                 llines -= linesperlevel;
             }
             /* tell everybody else */
-            sprintf (buf, "%d %d", playernum, playerlevels[playernum]);
+            g_snprintf (buf, sizeof(buf), "%d %d",
+                        playernum, playerlevels[playernum]);
             client_outmessage (OUT_LVL, buf);
             tetrinet_updatelevels ();
         }
@@ -1361,7 +1452,8 @@ int tetrinet_removelines ()
             case 4: sbnum = S_ADDALL4; break;
             default: goto endremovelines;
             }
-            sprintf (buf, "%i %s %i", 0, sbinfo[sbnum].id, playernum);
+            g_snprintf (buf, sizeof(buf), "%i %s %i",
+                        0, sbinfo[sbnum].id, playernum);
             client_outmessage (OUT_SB, buf);
             tetrinet_dospecial (playernum, 0, sbnum);
         }
@@ -1411,12 +1503,12 @@ notfieldkey:
                 if (strlen(s) > 0) {
                     if (strncmp("/me ", s, 4) == 0) {
                         /* post /me thingy */
-                        sprintf (buf, "* %s %s", nick, s+4);
+                        g_snprintf (buf, sizeof(buf), "* %s %s", nick, s+4);
                         client_outmessage (OUT_GMSG, buf);
                     }
                     else {
                         /* post message */
-                        sprintf (buf, "<%s> %s", nick, s);
+                        g_snprintf (buf, sizeof(buf), "<%s> %s", nick, s);
                         client_outmessage (OUT_GMSG, buf);
                     }
                 }
@@ -1536,7 +1628,7 @@ void tetrinet_specialkey (int pnum)
     if (pnum == -1) return;
 
     /* send it out */
-    sprintf (buf, "%i %s %i", pnum, sbinfo[sbnum].id, playernum);
+    g_snprintf (buf, sizeof(buf), "%i %s %i", pnum, sbinfo[sbnum].id, playernum);
     client_outmessage (OUT_SB, buf);
 
     tetrinet_dospecial (playernum, pnum, sbnum);
@@ -1556,7 +1648,11 @@ int moderatorupdate_timeout (void)
 {
     if (moderatornum) {
         char buf[256];
-        sprintf (buf, "\024*** \02%s\377\024 is the moderator", playernames[moderatornum]);
+        g_snprintf (buf, sizeof(buf),
+                    "%c*** %c%s%c%c is the moderator",
+                    TETRI_TB_C_BRIGHT_RED, TETRI_TB_BOLD,
+                    playernames[moderatornum],
+                    TETRI_TB_RESET, TETRI_TB_C_BRIGHT_RED);
         partyline_text (buf);
     }
     mutimeout = 0;
@@ -1594,46 +1690,56 @@ int partylineupdate_timeout (void)
     int f[16];
 
     if (plcount) {
-        strcpy (buf, "\014*** ");
+        g_snprintf(buf, sizeof(buf), "%c*** ", TETRI_TB_C_DARK_GREEN);
         for (i = 0; i < plcount; i++) {
-            sprintf (buf2, "\02%s\377\014, ", pleaves[i]);
-            strcat (buf, buf2);
+            g_snprintf (buf2, sizeof(buf2), "%c%s%c%c, ",
+                        TETRI_TB_BOLD, pleaves[i],
+                        TETRI_TB_RESET, TETRI_TB_C_DARK_GREEN);
+            GTET_O_STRCAT (buf, buf2);
         }
-        buf[strlen(buf)-2] = 0;
-        if (plcount == 1) strcat (buf, _(" has left the game"));
-        else strcat (buf, _(" have left the game"));
+        buf[strlen(buf)-2] = 0; /* remove ", " from end of string */
+        if (plcount == 1) GTET_O_STRCAT (buf, _(" has left the game"));
+        else GTET_O_STRCAT (buf, _(" have left the game"));
         plcount = 0;
         partyline_text (buf);
     }
     if (pcount) {
-        strcpy (buf, "\014*** ");
+        g_snprintf(buf, sizeof(buf), "%c*** ", TETRI_TB_C_DARK_GREEN);
         for (i = 0; i < pcount; i++) {
-            sprintf (buf2, "\02%s\377\014, ", pjoins[i]);
-            strcat (buf, buf2);
+            g_snprintf (buf2, sizeof(buf2), "%c%s%c%c, ",
+                        TETRI_TB_BOLD, pjoins[i],
+                        TETRI_TB_RESET, TETRI_TB_C_DARK_GREEN);
+            GTET_O_STRCAT (buf, buf2);
         }
         buf[strlen(buf)-2] = 0;
-        if (pcount == 1) strcat (buf, _(" has joined the game"));
-        else strcat (buf, _(" have joined the game"));
+        if (pcount == 1) GTET_O_STRCAT (buf, _(" has joined the game"));
+        else GTET_O_STRCAT (buf, _(" have joined the game"));
         partyline_text (buf);
 
         for (i = 0; i < pcount; i ++) f[i] = 1;
         for (i = 0; i < pcount; i ++) if (f[i]) {
-            strcpy (team, pteams[i]);
-            sprintf (buf, "\020*** \02%s\377\020", pjoins[i]);
+            GTET_O_STRCPY (team, pteams[i]);
+            g_snprintf (buf, sizeof(buf), "%c*** %c%s%c%c",
+                        TETRI_TB_C_DARK_RED, TETRI_TB_BOLD,
+                        pjoins[i],
+                        TETRI_TB_RESET, TETRI_TB_C_DARK_RED);
             c = 1;
             for (j = i+1; j < pcount; j ++) {
                 if (strcmp (team, pteams[j]) == 0) {
-                    sprintf (buf2, ", \02%s\377\020", pjoins[j]);
-                    strcat (buf, buf2);
+                    g_snprintf (buf2, sizeof(buf2), ", %c%s%c%c",
+                                TETRI_TB_BOLD, pjoins[j],
+                                TETRI_TB_RESET, TETRI_TB_C_DARK_RED);
+                    GTET_O_STRCAT (buf, buf2);
                     f[j] = 0;
                     c ++;
                 }
             }
-            if (c == 1) strcat (buf, " is ");
-            else strcat (buf, " are ");
-            if (team[0]) sprintf (buf2, "on team \02%s", team);
-            else sprintf (buf2, "alone");
-            strcat (buf, buf2);
+            if (c == 1) GTET_O_STRCAT (buf, " is ");
+            else GTET_O_STRCAT (buf, " are ");
+            if (team[0]) g_snprintf (buf2, sizeof(buf2), "on team %c%s",
+                                     TETRI_TB_BOLD, team);
+            else g_snprintf (buf2, sizeof(buf2), "alone");
+            GTET_O_STRCAT (buf, buf2);
             partyline_text (buf);
         }
         pcount = 0;
@@ -1658,7 +1764,7 @@ void partylineupdate_join (char *name)
     int i;
     if (!connected) return;
     for (i = 0; i < pcount; i ++) if (strcmp(pjoins[i], name) == 0) return;
-    strcpy (pjoins[pcount], name);
+    GTET_O_STRCPY (pjoins[pcount], name);
     pteams[pcount][0] = 0;
     pcount ++;
     partylineupdate (0);
@@ -1674,21 +1780,28 @@ void partylineupdate_team (char *name, char *team)
         char buf[1024];
         /* player did not just join - display normally */
         if (team[0])
-            sprintf (buf, "\020*** \02%s\377\020 is now on team \02%s",
-                     name, team);
+            g_snprintf (buf, sizeof(buf),
+                        "%c*** %c%s%c%c is now on team %c%s",
+                        TETRI_TB_C_DARK_RED, TETRI_TB_BOLD,
+                        name,
+                        TETRI_TB_RESET, TETRI_TB_C_DARK_RED,
+                        TETRI_TB_BOLD, team);
         else
-            sprintf (buf, "\020*** \02%s\377\020 is now alone",
-                     name);
+            g_snprintf (buf, sizeof(buf),
+                        "%c*** %c%s%c%c is now alone",
+                        TETRI_TB_C_DARK_RED, TETRI_TB_BOLD,
+                        name,
+                        TETRI_TB_RESET, TETRI_TB_C_DARK_RED);
         partyline_text (buf);
     }
-    strcpy (pteams[i], team);
+    GTET_O_STRCPY (pteams[i], team);
     partylineupdate (0);
 }
 
 void partylineupdate_leave (char *name)
 {
     if (!connected) return;
-    strcpy (pleaves[plcount], name);
+    GTET_O_STRCPY (pleaves[plcount], name);
     plcount ++;
     partylineupdate (0);
 }
@@ -1740,28 +1853,39 @@ void checkmoderatorstatus (void)
 void plinemsg (char *name, char *text)
 {
     char buf[1024];
-    sprintf (buf, "\02<%s\377\02>\02 %s", name, text);
+    g_snprintf (buf, sizeof(buf), "%c<%s%c%c>%c %s",
+                TETRI_TB_BOLD, name,
+                TETRI_TB_RESET, TETRI_TB_BOLD, TETRI_TB_BOLD, text);
     partyline_text (buf);
 }
 
 void plinesmsg (char *name, char *text)
 {
     char buf[1024];
-    sprintf (buf, "\05\02<%s\377\05\02>\02 %s", name, text);
+    g_snprintf (buf, sizeof(buf), "%c%c<%s%c%c%c>%c %s",
+                TETRI_TB_C_BRIGHT_BLUE, TETRI_TB_BOLD,
+                name,
+                TETRI_TB_RESET,
+                TETRI_TB_C_BRIGHT_BLUE, TETRI_TB_BOLD, TETRI_TB_BOLD, text);
     partyline_text (buf);
 }
 
 void plineact (char *name, char *text)
 {
     char buf[1024];
-    sprintf (buf, "\023* \02%s\377\023 %s", name, text);
+    g_snprintf (buf, sizeof(buf), "%c* %c%s%c%c %s",
+                TETRI_TB_C_PURPLE, TETRI_TB_BOLD, name,
+                TETRI_TB_RESET, TETRI_TB_C_PURPLE, text);
     partyline_text (buf);
 }
 
 void plinesact (char *name, char *text)
 {
     char buf[1024];
-    sprintf (buf, "\05* \02%s\377\05 %s", name, text);
+    g_snprintf (buf, sizeof(buf), "%c* %c%s%c%c %s",
+                TETRI_TB_C_BRIGHT_BLUE, TETRI_TB_BOLD,
+                name,
+                TETRI_TB_RESET, TETRI_TB_C_BRIGHT_BLUE, text);
     partyline_text (buf);
 }
 
@@ -1796,11 +1920,15 @@ void speclist_clear (void)
 void speclist_add (char *name)
 {
     int p, i;
+    
+    if (spectatorcount == (sizeof(spectatorlist) / sizeof(spectatorlist[0])))
+      return;
+    
     for (p = 0; p < spectatorcount; p++)
         if (strcasecmp(name, spectatorlist[p]) < 0) break;
     for (i = spectatorcount; i > p; i--)
-        strcpy (spectatorlist[i], spectatorlist[i-1]);
-    strcpy (spectatorlist[p], name);
+        GTET_O_STRCPY (spectatorlist[i], spectatorlist[i-1]);
+    GTET_O_STRCPY (spectatorlist[p], name);
     spectatorcount ++;
 }
 
@@ -1810,7 +1938,7 @@ void speclist_remove (char *name)
     for (i = 0; i < spectatorcount; i ++) {
         if (strcmp(name, spectatorlist[i]) == 0) {
             for (; i < spectatorcount-1; i++)
-                strcpy (spectatorlist[i], spectatorlist[i+1]);
+                GTET_O_STRCPY (spectatorlist[i], spectatorlist[i+1]);
             spectatorcount --;
             return;
         }
index 16e8c16761a604fd3201b4067c2205fffa8ebfd4..708918c467c4a61ad1aed599af1d4f1ad9fdaa4b 100644 (file)
@@ -69,7 +69,7 @@ void winlist_additem (int team, char *name, int score)
     if (team) item[0] = "T";
     else item[0] = "";
     item[1] = nocolor (name);
-    sprintf (buf, "%d", score);
+    g_snprintf (buf, sizeof(buf), "%d", score);
     item[2] = buf;
 
     gtk_clist_append (GTK_CLIST(winlist), item);