foxygit / doom Log in
commit a104b98d48c0d5cfa5dcc79175f0ffa853ec4528
Author:     Simon Howard <fraggle@soulsphere.org>
AuthorDate: Wed Sep 27 23:37:46 2017 -0400
Commit:     Simon Howard <fraggle@soulsphere.org>
CommitDate: Wed Sep 27 23:37:46 2017 -0400

    net: Get rid of NET_SafePuts().

    Instead what's almost always wanted is to read a "safe" string that
    cannot contain any control codes. So introduce NET_ReadSafeString()
    instead as a wrapper around NET_ReadString() that does this.
---
 src/net_client.c   |  8 +++-----
 src/net_common.c   |  5 ++---
 src/net_packet.c   | 32 ++++++++++++++++++++++++++++++++
 src/net_packet.h   |  1 +
 src/net_query.c    |  2 +-
 src/net_server.c   |  4 ++--
 src/net_structrw.c | 24 ++----------------------
 src/net_structrw.h |  2 --
 8 files changed, 43 insertions(+), 35 deletions(-)

diff --git a/src/net_client.c b/src/net_client.c
index 6f558604..11615c08 100644
--- a/src/net_client.c
+++ b/src/net_client.c
@@ -433,7 +433,7 @@ static void NET_CL_ParseSYN(net_packet_t *packet)
     net_protocol_t protocol;
     char *server_version;

-    server_version = NET_ReadString(packet);
+    server_version = NET_ReadSafeString(packet);
     if (server_version == NULL)
     {
         return;
@@ -830,16 +830,14 @@ static void NET_CL_ParseConsoleMessage(net_packet_t *packet)
 {
     char *msg;

-    msg = NET_ReadString(packet);
+    msg = NET_ReadSafeString(packet);

     if (msg == NULL)
     {
         return;
     }

-    printf("Message from server: ");
-
-    NET_SafePuts(msg);
+    printf("Message from server:\n%s\n", msg);
 }

 // parse a received packet
diff --git a/src/net_common.c b/src/net_common.c
index 78520c5f..ca194d80 100644
--- a/src/net_common.c
+++ b/src/net_common.c
@@ -132,7 +132,7 @@ static void NET_Conn_ParseReject(net_connection_t *conn, net_packet_t *packet)
 {
     char *msg;

-    msg = NET_ReadString(packet);
+    msg = NET_ReadSafeString(packet);

     if (msg == NULL)
     {
@@ -146,8 +146,7 @@ static void NET_Conn_ParseReject(net_connection_t *conn, net_packet_t *packet)
         conn->state = NET_CONN_STATE_DISCONNECTED;
         conn->disconnect_reason = NET_DISCONNECT_REMOTE;

-        printf("Rejected by server: ");
-        NET_SafePuts(msg);
+        printf("Rejected by server: %s\n", msg);
     }
 }

diff --git a/src/net_packet.c b/src/net_packet.c
index 82a20fe5..ae1be7cb 100644
--- a/src/net_packet.c
+++ b/src/net_packet.c
@@ -15,6 +15,7 @@
 //      Network packet manipulation (net_packet_t)
 //

+#include <ctype.h>
 #include <string.h>
 #include "m_misc.h"
 #include "net_packet.h"
@@ -202,6 +203,37 @@ char *NET_ReadString(net_packet_t *packet)
     return start;
 }

+// Read a string from the packet, but (potentially) modify it to strip
+// out any unprintable characters which could be malicious control codes.
+// Note that this may modify the original packet contents.
+char *NET_ReadSafeString(net_packet_t *packet)
+{
+    char *r, *w, *result;
+
+    result = NET_ReadString(packet);
+    if (result == NULL)
+    {
+        return NULL;
+    }
+
+    // w is always <= r, so we never produce a longer string than the original.
+    w = result;
+    for (r = result; *r != '\0'; ++r)
+    {
+        // TODO: This is a very naive way of producing a safe string; only
+        // ASCII characters are allowed. Probably this should really support
+        // UTF-8 characters as well.
+        if (isprint(*r) || *r == '\n')
+        {
+            *w = *r;
+            ++w;
+        }
+    }
+    *w = '\0';
+
+    return result;
+}
+
 // Dynamically increases the size of a packet

 static void NET_IncreasePacket(net_packet_t *packet)
diff --git a/src/net_packet.h b/src/net_packet.h
index ced4e435..011f1af9 100644
--- a/src/net_packet.h
+++ b/src/net_packet.h
@@ -33,6 +33,7 @@ boolean NET_ReadSInt16(net_packet_t *packet, signed int *data);
 boolean NET_ReadSInt32(net_packet_t *packet, signed int *data);

 char *NET_ReadString(net_packet_t *packet);
+char *NET_ReadSafeString(net_packet_t *packet);

 void NET_WriteInt8(net_packet_t *packet, unsigned int i);
 void NET_WriteInt16(net_packet_t *packet, unsigned int i);
diff --git a/src/net_query.c b/src/net_query.c
index eaa6f96d..94fdf03b 100644
--- a/src/net_query.c
+++ b/src/net_query.c
@@ -738,7 +738,7 @@ static void NET_QueryPrintCallback(net_addr_t *addr,
         printf("(game running) ");
     }

-    NET_SafePuts(data->description);
+    printf("%s\n", data->description);
 }

 void NET_LANQuery(void)
diff --git a/src/net_server.c b/src/net_server.c
index fa31cbcf..ab79b954 100644
--- a/src/net_server.c
+++ b/src/net_server.c
@@ -213,7 +213,7 @@ static void NET_SV_BroadcastMessage(char *s, ...)
     va_start(args, s);
     M_vsnprintf(buf, sizeof(buf), s, args);
     va_end(args);
-
+
     for (i=0; i<MAXNETNODES; ++i)
     {
         if (ClientConnected(&clients[i]))
@@ -222,7 +222,7 @@ static void NET_SV_BroadcastMessage(char *s, ...)
         }
     }

-    NET_SafePuts(buf);
+    printf("%s\n", buf);
 }


diff --git a/src/net_structrw.c b/src/net_structrw.c
index a820df5f..6d958cf9 100644
--- a/src/net_structrw.c
+++ b/src/net_structrw.c
@@ -17,7 +17,6 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <ctype.h>

 #include "doomtype.h"
 #include "m_misc.h"
@@ -122,7 +121,7 @@ boolean NET_ReadQueryData(net_packet_t *packet, net_querydata_t *query)
 {
     boolean result;

-    query->version = NET_ReadString(packet);
+    query->version = NET_ReadSafeString(packet);

     result = query->version != NULL
           && NET_ReadInt8(packet, (unsigned int *) &query->server_state)
@@ -133,7 +132,7 @@ boolean NET_ReadQueryData(net_packet_t *packet, net_querydata_t *query)

     if (result)
     {
-        query->description = NET_ReadString(packet);
+        query->description = NET_ReadSafeString(packet);

         return query->description != NULL;
     }
@@ -551,22 +550,3 @@ void NET_WritePRNGSeed(net_packet_t *packet, prng_seed_t seed)
     NET_WriteBlob(packet, seed, sizeof(prng_seed_t));
 }

-// "Safe" version of puts, for displaying messages received from the
-// network.
-
-void NET_SafePuts(char *s)
-{
-    char *p;
-
-    // Do not do a straight "puts" of the string, as this could be
-    // dangerous (sending control codes to terminals can do all
-    // kinds of things)
-
-    for (p=s; *p; ++p)
-    {
-        if (isprint(*p) || *p == '\n')
-            putchar(*p);
-    }
-
-    putchar('\n');
-}
diff --git a/src/net_structrw.h b/src/net_structrw.h
index f02f169a..e349127c 100644
--- a/src/net_structrw.h
+++ b/src/net_structrw.h
@@ -43,8 +43,6 @@ void NET_WriteSHA1Sum(net_packet_t *packet, sha1_digest_t digest);
 void NET_WriteWaitData(net_packet_t *packet, net_waitdata_t *data);
 boolean NET_ReadWaitData(net_packet_t *packet, net_waitdata_t *data);

-void NET_SafePuts(char *msg);
-
 boolean NET_ReadPRNGSeed(net_packet_t *packet, prng_seed_t seed);
 void NET_WritePRNGSeed(net_packet_t *packet, prng_seed_t seed);