shithub: choc

Download patch

ref: 602ea481c556ca7d7bd26f07b8be55b3ce92281c
parent: 65ae592ca6f78ebbaa567b4922acc9668d7420ab
author: Simon Howard <fraggle@soulsphere.org>
date: Sat Nov 3 09:34:17 EDT 2018

glob: Fix build failure.

Correctly handle failed mallocs.

--- a/src/i_glob.c
+++ b/src/i_glob.c
@@ -84,6 +84,16 @@
     int next_index;
 };
 
+static void FreeStringList(char **globs, int num_globs)
+{
+    int i;
+    for (i = 0; i < num_globs; ++i)
+    {
+        free(globs[i]);
+    }
+    free(globs);
+}
+
 glob_t *I_StartMultiGlob(const char *directory, int flags,
                          const char *glob, ...)
 {
@@ -93,6 +103,10 @@
     va_list args;
 
     globs = malloc(sizeof(char *));
+    if (globs == NULL)
+    {
+        return NULL;
+    }
     globs[0] = M_StringDuplicate(glob);
     num_globs = 1;
 
@@ -100,12 +114,19 @@
     for (;;)
     {
         const char *arg = va_arg(args, const char *);
+        char **new_globs;
+
         if (arg == NULL)
         {
             break;
         }
 
-        globs = realloc(globs, sizeof(char *) * (num_globs + 1));
+        new_globs = realloc(globs, sizeof(char *) * (num_globs + 1));
+        if (new_globs == NULL)
+        {
+            FreeStringList(globs, num_globs);
+        }
+        globs = new_globs;
         globs[num_globs] = M_StringDuplicate(arg);
         ++num_globs;
     }
@@ -114,6 +135,7 @@
     result = malloc(sizeof(glob_t));
     if (result == NULL)
     {
+        FreeStringList(globs, num_globs);
         return NULL;
     }
 
@@ -120,6 +142,7 @@
     result->dir = opendir(directory);
     if (result->dir == NULL)
     {
+        FreeStringList(globs, num_globs);
         free(result);
         return NULL;
     }
@@ -142,25 +165,14 @@
 
 void I_EndGlob(glob_t *glob)
 {
-    int i;
-
     if (glob == NULL)
     {
         return;
     }
 
-    for (i = 0; i < glob->num_globs; ++i)
-    {
-        free(glob->globs[i]);
-    }
+    FreeStringList(glob->globs, glob->num_globs);
+    FreeStringList(glob->filenames, glob->filenames_len);
 
-    for (i = 0; i < glob->filenames_len; ++i)
-    {
-        free(glob->filenames[i]);
-    }
-
-    free(glob->globs);
-    free(glob->filenames);
     free(glob->directory);
     free(glob->last_filename);
     (void) closedir(glob->dir);