Fix segfault when IniFile_Load is called with invalid input (#5331)
authorKubistika <kmizrachi18@gmail.com>
Mon, 8 Apr 2019 07:26:46 +0000 (10:26 +0300)
committerakallabeth <akallabeth@users.noreply.github.com>
Mon, 8 Apr 2019 07:26:46 +0000 (09:26 +0200)
* Fix segfault when IniFile_Load is called with invalid input

* Fix leak in TestIni.c third testcase

* TestIni.c: Refactor in order to avoid some old compilers errors

winpr/libwinpr/utils/ini.c
winpr/libwinpr/utils/test/TestIni.c

index 5c0798f..6522527 100644 (file)
@@ -390,6 +390,10 @@ int IniFile_Load(wIniFile* ini)
                else
                {
                        separator = strchr(line, '=');
+
+                       if (separator == NULL)
+                               return -1;
+
                        end = separator;
 
                        while ((&end[-1] > line) && ((end[-1] == ' ') || (end[-1] == '\t')))
index a584c50..307f7fb 100644 (file)
@@ -1,31 +1,43 @@
 
 #include <winpr/crt.h>
-
 #include <winpr/ini.h>
 
 const char TEST_INI_01[] =
-       "; This is a sample .ini config file\n"
-       "\n"
-       "[first_section]\n"
-       "one = 1\n"
-       "five = 5\n"
-       "animal = BIRD\n"
-       "\n"
-       "[second_section]\n"
-       "path = \"/usr/local/bin\"\n"
-       "URL = \"http://www.example.com/~username\"\n"
-       "\n";
+    "; This is a sample .ini config file\n"
+    "\n"
+    "[first_section]\n"
+    "one = 1\n"
+    "five = 5\n"
+    "animal = BIRD\n"
+    "\n"
+    "[second_section]\n"
+    "path = \"/usr/local/bin\"\n"
+    "URL = \"http://www.example.com/~username\"\n"
+    "\n";
 
 const char TEST_INI_02[] =
-       "[FreeRDS]\n"
-       "prefix=\"/usr/local\"\n"
-       "bindir=\"bin\"\n"
-       "sbindir=\"sbin\"\n"
-       "libdir=\"lib\"\n"
-       "datarootdir=\"share\"\n"
-       "localstatedir=\"var\"\n"
-       "sysconfdir=\"etc\"\n"
-       "\n";
+    "[FreeRDS]\n"
+    "prefix=\"/usr/local\"\n"
+    "bindir=\"bin\"\n"
+    "sbindir=\"sbin\"\n"
+    "libdir=\"lib\"\n"
+    "datarootdir=\"share\"\n"
+    "localstatedir=\"var\"\n"
+    "sysconfdir=\"etc\"\n"
+    "\n";
+
+const char TEST_INI_03[] =
+    "[FreeRDS]\n"
+    "prefix=\"/usr/local\"\n"
+    "bindir=\"bin\"\n"
+    "# some illegal string\n"
+    "sbindir=\"sbin\"\n"
+    "libdir=\"lib\"\n"
+    "invalid key-value pair\n"
+    "datarootdir=\"share\"\n"
+    "localstatedir=\"var\"\n"
+    "sysconfdir=\"etc\"\n"
+    "\n";
 
 int TestIni(int argc, char* argv[])
 {
@@ -37,101 +49,98 @@ int TestIni(int argc, char* argv[])
        const char* sValue;
        char** keyNames;
        char** sectionNames;
-
        /* First Sample */
-       
        ini = IniFile_New();
-
        IniFile_ReadBuffer(ini, TEST_INI_01);
-       
        sectionNames = IniFile_GetSectionNames(ini, &nSections);
-       
+
        for (i = 0; i < nSections; i++)
        {
                keyNames = IniFile_GetSectionKeyNames(ini, sectionNames[i], &nKeys);
-               
                printf("[%s]\n", sectionNames[i]);
-               
+
                for (j = 0; j < nKeys; j++)
                {
                        sValue = IniFile_GetKeyValueString(ini, sectionNames[i], keyNames[j]);
                        printf("%s = %s\n", keyNames[j], sValue);
                }
-               
+
                free(keyNames);
        }
-       
-       free(sectionNames);
 
+       free(sectionNames);
        iValue = IniFile_GetKeyValueInt(ini, "first_section", "one");
-       
+
        if (iValue != 1)
        {
                printf("IniFile_GetKeyValueInt failure\n");
                return -1;
        }
-       
+
        iValue = IniFile_GetKeyValueInt(ini, "first_section", "five");
-       
+
        if (iValue != 5)
        {
                printf("IniFile_GetKeyValueInt failure\n");
                return -1;
        }
-       
+
        sValue = IniFile_GetKeyValueString(ini, "first_section", "animal");
-       
+
        if (strcmp(sValue, "BIRD") != 0)
        {
                printf("IniFile_GetKeyValueString failure\n");
-               return -1;      
+               return -1;
        }
-       
+
        sValue = IniFile_GetKeyValueString(ini, "second_section", "path");
-       
+
        if (strcmp(sValue, "/usr/local/bin") != 0)
        {
                printf("IniFile_GetKeyValueString failure\n");
-               return -1;      
+               return -1;
        }
-       
+
        sValue = IniFile_GetKeyValueString(ini, "second_section", "URL");
-       
+
        if (strcmp(sValue, "http://www.example.com/~username") != 0)
        {
                printf("IniFile_GetKeyValueString failure\n");
-               return -1;      
+               return -1;
        }
-       
+
        IniFile_Free(ini);
-       
        /* Second Sample */
-
        ini = IniFile_New();
-
        IniFile_ReadBuffer(ini, TEST_INI_02);
-       
        sectionNames = IniFile_GetSectionNames(ini, &nSections);
-       
+
        for (i = 0; i < nSections; i++)
        {
                keyNames = IniFile_GetSectionKeyNames(ini, sectionNames[i], &nKeys);
-               
                printf("[%s]\n", sectionNames[i]);
-               
+
                for (j = 0; j < nKeys; j++)
                {
                        sValue = IniFile_GetKeyValueString(ini, sectionNames[i], keyNames[j]);
                        printf("%s = %s\n", keyNames[j], sValue);
                }
-               
+
                free(keyNames);
        }
-       
+
        free(sectionNames);
-       
        IniFile_Free(ini);
-       
+       /* Third sample - invalid input */
+       ini = IniFile_New();
+
+       if (IniFile_ReadBuffer(ini, TEST_INI_03) != -1)
+       {
+               IniFile_Free(ini);
+               return -1;
+       }
+
+       IniFile_Free(ini);
        return 0;
 }