comparison src/dmpack.c @ 1012:7666ba24e0c6

Cleanups and improve error handling.
author Matti Hamalainen <ccr@tnsp.org>
date Sun, 01 Mar 2015 04:42:04 +0200
parents 1e5cf1144f36
children 1684bf6aa1f8
comparison
equal deleted inserted replaced
1011:aa745d31612e 1012:7666ba24e0c6
69 * OPEN a packfile 69 * OPEN a packfile
70 */ 70 */
71 int dmPackOpen(const char *filename, DMPackFile ** ppPack, BOOL readOnly) 71 int dmPackOpen(const char *filename, DMPackFile ** ppPack, BOOL readOnly)
72 { 72 {
73 unsigned int i; 73 unsigned int i;
74 DMPackFile *pack; 74 DMPackFile *pack = NULL;
75 DMPackFileHeader hdr; 75 DMPackFileHeader hdr;
76 76 int ret = DMERR_OK;
77 *ppPack = NULL;
78 77
79 // Allocate packfile-structure 78 // Allocate packfile-structure
80 pack = (DMPackFile *) dmMalloc0(sizeof(DMPackFile)); 79 if ((pack = dmMalloc0(sizeof(DMPackFile))) == NULL)
81 if (pack == NULL) 80 {
82 return DMERR_MALLOC; 81 ret = DMERR_MALLOC;
82 goto out;
83 }
83 84
84 // Open the file 85 // Open the file
85 pack->file = fopen(filename, readOnly ? "rb" : "r+b"); 86 if ((pack->file = fopen(filename, readOnly ? "rb" : "r+b")) == NULL)
86 if (pack->file == NULL) 87 {
87 { 88 ret = DMERR_FOPEN;
88 dmFree(pack); 89 goto out;
89 return DMERR_FOPEN;
90 } 90 }
91 91
92 pack->filename = dm_strdup(filename); 92 pack->filename = dm_strdup(filename);
93 93
94 // Read PACK header 94 // Read PACK header
103 } 103 }
104 104
105 // Check information 105 // Check information
106 if (memcmp(&hdr.ident, DPACK_IDENT, sizeof(hdr.ident)) != 0) 106 if (memcmp(&hdr.ident, DPACK_IDENT, sizeof(hdr.ident)) != 0)
107 { 107 {
108 dmPackClose(pack); 108 ret = DMERR_NOTPACK;
109 return DMERR_NOTPACK; 109 goto out;
110 } 110 }
111 111
112 if (hdr.version != DPACK_VERSION) 112 if (hdr.version != DPACK_VERSION)
113 { 113 {
114 dmPackClose(pack); 114 ret = DMERR_VERSION;
115 return DMERR_VERSION; 115 goto out;
116 } 116 }
117 117
118 // Read directory 118 // Read directory
119 if (fseek(pack->file, hdr.dirOffset, SEEK_SET) != 0) 119 if (hdr.dirOffset < sizeof(hdr) ||
120 { 120 fseek(pack->file, hdr.dirOffset, SEEK_SET) != 0)
121 dmPackClose(pack); 121 {
122 return DMERR_INVALID; 122 ret = DMERR_INVALID;
123 goto out;
123 } 124 }
124 125
125 for (i = 0; i < hdr.dirEntries; i++) 126 for (i = 0; i < hdr.dirEntries; i++)
126 { 127 {
127 // Allocate and read directory entry 128 // Allocate and read directory entry
128 DMPackEntry *entry = dmPackEntryNew(); 129 DMPackEntry *entry;
129 130
130 if (entry == NULL) 131 if ((entry = dmPackEntryNew()) == NULL)
131 { 132 {
132 dmPackClose(pack); 133 ret = DMERR_MALLOC;
133 return DMERR_MALLOC; 134 goto out;
134 } 135 }
135 136
136 if (!dm_fread_str(pack->file, (Uint8 *) &entry->filename, sizeof(entry->filename)) || 137 if (!dm_fread_str(pack->file, (Uint8 *) &entry->filename, sizeof(entry->filename)) ||
137 !dm_fread_le32(pack->file, &entry->size) || 138 !dm_fread_le32(pack->file, &entry->size) ||
138 !dm_fread_le32(pack->file, &entry->offset) || 139 !dm_fread_le32(pack->file, &entry->offset) ||
139 !dm_fread_le32(pack->file, &entry->length) || 140 !dm_fread_le32(pack->file, &entry->length) ||
140 !dm_fread_le32(pack->file, &entry->flags)) 141 !dm_fread_le32(pack->file, &entry->flags))
141 { 142 {
142 *ppPack = pack; 143 ret = DMERR_FREAD;
143 return DMERR_FREAD; 144 goto out;
144 } 145 }
146
147 // Validate
148 if (entry->size == 0 || entry->length == 0 ||
149 entry->length > hdr.dirOffset ||
150 entry->offset > hdr.dirOffset)
145 151
146 // Insert into list 152 // Insert into list
147 dmPackEntryInsert(&pack->entries, entry); 153 dmPackEntryInsert(&pack->entries, entry);
148 } 154 }
149 155
150 // Set the result 156 out:
157 if (ret != DMERR_OK)
158 {
159 dmPackClose(pack);
160 pack = NULL;
161 }
162
151 *ppPack = pack; 163 *ppPack = pack;
152 return DMERR_OK; 164
165 return ret;
153 } 166 }
154 167
155 168
156 /* 169 /*
157 * CLOSE the packfile 170 * CLOSE the packfile
172 node = next; 185 node = next;
173 } 186 }
174 187
175 // Close the file 188 // Close the file
176 if (pack->file != NULL) 189 if (pack->file != NULL)
177 {
178 fclose(pack->file); 190 fclose(pack->file);
179 pack->file = NULL;
180 }
181 191
182 // Free structures 192 // Free structures
183 dmFree(pack->filename); 193 dmFree(pack->filename);
184 pack->filename = NULL;
185 194
186 // Free packfile 195 // Free packfile
187 pack->entries = NULL; 196 memset(pack, 0, sizeof(DMPackFile));
188 dmFree(pack); 197 dmFree(pack);
189 198
190 return DMERR_OK; 199 return DMERR_OK;
191 } 200 }