changeset 1839:0402237b734e

Add a test mode to fuzz/test resiliency of the map search spec parser.
author Matti Hamalainen <ccr@tnsp.org>
date Tue, 31 Oct 2017 19:43:44 +0200
parents 2d96e2d518d2
children 5f574f78eff6
files mapsearch.c
diffstat 1 files changed, 85 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/mapsearch.c	Tue Oct 31 19:42:28 2017 +0200
+++ b/mapsearch.c	Tue Oct 31 19:43:44 2017 +0200
@@ -82,6 +82,7 @@
 char    *optSSLCipherList = SET_DEF_CIPHERS;
 struct lws_context *setLWSContext = NULL;
 int     optWorldXC = 0, optWorldYC = 0;
+char    *optTest = NULL;
 
 
 /* Arguments
@@ -94,6 +95,7 @@
     { 3,   0, "ssl-ciphers",   "Specify list of SSL/TLS ciphers", OPT_ARGREQ },
     { 4,   0, "clean-chars",   "String of characters to 'clean up' from map blocks.", OPT_ARGREQ },
     { 5, 'w', "world-origin",  "Specify the world origin <x:y> which map offsets relate to.", OPT_ARGREQ },
+    { 6, 'T', "test",          "Test search with given file input", OPT_ARGREQ },
 };
 
 static const int optListN = sizeof(optList) / sizeof(optList[0]);
@@ -401,6 +403,10 @@
         }
         break;
 
+    case 6:
+        optTest = optArg;
+        break;
+
     default:
         THERR("Unknown option '%s'.\n", currArg);
         return FALSE;
@@ -952,6 +958,63 @@
 }
 
 
+#define BUF_SIZE_INITIAL (1024 * 4)
+#define BUF_SIZE_GROW    (512)
+
+int mapReadFile(const char *filename, uint8_t **pbuf, size_t *pbufSize)
+{
+    uint8_t *dataBuf = NULL;
+    size_t readSize, dataSize, dataRead, dataPos;
+    int res = 0;
+    FILE *fh = NULL;
+
+    if ((fh = fopen(filename, "rb")) == NULL)
+    {
+        res = -5;
+        goto out;
+    }
+
+    // Allocate initial data buffer
+    readSize = dataSize = BUF_SIZE_INITIAL;
+    if ((dataBuf = th_malloc(dataSize)) == NULL)
+    {
+        res = -1;
+        goto out;
+    }
+
+    dataPos = 0;
+    dataRead = 0;
+    while (!feof(fh) && !ferror(fh))
+    {
+        size_t read = fread(dataBuf + dataPos, 1, readSize, fh);
+        dataPos += read;
+        dataRead += read;
+
+        if (dataRead >= dataSize)
+        {
+            readSize = BUF_SIZE_GROW;
+            dataSize += BUF_SIZE_GROW;
+            if ((dataBuf = th_realloc(dataBuf, dataSize)) == NULL)
+            {
+                res = -2;
+                goto out;
+            }
+        }
+        else
+            break;
+    }
+
+    *pbufSize = dataRead;
+    *pbuf = dataBuf;
+
+out:
+    if (fh != NULL)
+        fclose(fh);
+
+    return res;
+}
+
+
 int main(int argc, char *argv[])
 {
     // Initialize
@@ -973,7 +1036,7 @@
         goto exit;
     }
 
-    if (optNListenTo == 0)
+    if (optNListenTo == 0 && optTest == NULL)
     {
         THERR("No listeners specified.\n");
         goto exit;
@@ -1016,6 +1079,27 @@
         fclose(fh);
     }
 
+    // Check for test mode
+    if (optTest != NULL)
+    {
+        THMSG(1, "Running in test mode, input '%s'.\n", optTest);
+        uint8_t *buf = NULL;
+        size_t bufSize;
+
+        if (mapReadFile(optTest, &buf, &bufSize) == 0)
+        {
+            char *verr = NULL;
+            mapPerformSearch(NULL, buf, bufSize, &verr);
+            if (verr != NULL)
+                THERR("%s\n", verr);
+        }
+        else
+            THERR("Could not read test file.\n");
+
+        th_free(buf);
+        goto exit;
+    }
+
     // Initialize libwebsockets and create context
     THMSG(1, "Creating libwebsockets context.\n");