changeset 1012:7666ba24e0c6

Cleanups and improve error handling.
author Matti Hamalainen <ccr@tnsp.org>
date Sun, 01 Mar 2015 04:42:04 +0200
parents aa745d31612e
children 1684bf6aa1f8
files src/dmpack.c
diffstat 1 files changed, 39 insertions(+), 30 deletions(-) [+]
line wrap: on
line diff
--- a/src/dmpack.c	Sun Mar 01 04:34:54 2015 +0200
+++ b/src/dmpack.c	Sun Mar 01 04:42:04 2015 +0200
@@ -71,22 +71,22 @@
 int dmPackOpen(const char *filename, DMPackFile ** ppPack, BOOL readOnly)
 {
     unsigned int i;
-    DMPackFile *pack;
+    DMPackFile *pack = NULL;
     DMPackFileHeader hdr;
-
-    *ppPack = NULL;
+    int ret = DMERR_OK;
 
     // Allocate packfile-structure
-    pack = (DMPackFile *) dmMalloc0(sizeof(DMPackFile));
-    if (pack == NULL)
-        return DMERR_MALLOC;
+    if ((pack = dmMalloc0(sizeof(DMPackFile))) == NULL)
+    {
+        ret = DMERR_MALLOC;
+        goto out;
+    }
 
     // Open the file
-    pack->file = fopen(filename, readOnly ? "rb" : "r+b");
-    if (pack->file == NULL)
+    if ((pack->file = fopen(filename, readOnly ? "rb" : "r+b")) == NULL)
     {
-        dmFree(pack);
-        return DMERR_FOPEN;
+        ret = DMERR_FOPEN;
+        goto out;
     }
 
     pack->filename = dm_strdup(filename);
@@ -105,32 +105,33 @@
     // Check information
     if (memcmp(&hdr.ident, DPACK_IDENT, sizeof(hdr.ident)) != 0)
     {
-        dmPackClose(pack);
-        return DMERR_NOTPACK;
+        ret = DMERR_NOTPACK;
+        goto out;
     }
 
     if (hdr.version != DPACK_VERSION)
     {
-        dmPackClose(pack);
-        return DMERR_VERSION;
+        ret = DMERR_VERSION;
+        goto out;
     }
 
     // Read directory
-    if (fseek(pack->file, hdr.dirOffset, SEEK_SET) != 0)
+    if (hdr.dirOffset < sizeof(hdr) ||
+        fseek(pack->file, hdr.dirOffset, SEEK_SET) != 0)
     {
-        dmPackClose(pack);
-        return DMERR_INVALID;
+        ret = DMERR_INVALID;
+        goto out;
     }
 
     for (i = 0; i < hdr.dirEntries; i++)
     {
         // Allocate and read directory entry
-        DMPackEntry *entry = dmPackEntryNew();
+        DMPackEntry *entry;
 
-        if (entry == NULL)
+        if ((entry = dmPackEntryNew()) == NULL)
         {
-            dmPackClose(pack);
-            return DMERR_MALLOC;
+            ret = DMERR_MALLOC;
+            goto out;
         }
 
         if (!dm_fread_str(pack->file, (Uint8 *) &entry->filename, sizeof(entry->filename)) ||
@@ -139,17 +140,29 @@
             !dm_fread_le32(pack->file, &entry->length) ||
             !dm_fread_le32(pack->file, &entry->flags))
         {
-            *ppPack = pack;
-            return DMERR_FREAD;
+            ret = DMERR_FREAD;
+            goto out;
         }
 
+        // Validate
+        if (entry->size == 0 || entry->length == 0 ||
+            entry->length > hdr.dirOffset ||
+            entry->offset > hdr.dirOffset)
+
         // Insert into list
         dmPackEntryInsert(&pack->entries, entry);
     }
 
-    // Set the result
+out:
+    if (ret != DMERR_OK)
+    {
+        dmPackClose(pack);
+        pack = NULL;
+    }
+
     *ppPack = pack;
-    return DMERR_OK;
+
+    return ret;
 }
 
 
@@ -174,17 +187,13 @@
 
     // Close the file
     if (pack->file != NULL)
-    {
         fclose(pack->file);
-        pack->file = NULL;
-    }
 
     // Free structures
     dmFree(pack->filename);
-    pack->filename = NULL;
 
     // Free packfile
-    pack->entries = NULL;
+    memset(pack, 0, sizeof(DMPackFile));
     dmFree(pack);
 
     return DMERR_OK;