summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/cc4group.c178
1 files changed, 152 insertions, 26 deletions
diff --git a/src/cc4group.c b/src/cc4group.c
index b3653b7..40b838c 100644
--- a/src/cc4group.c
+++ b/src/cc4group.c
@@ -266,7 +266,8 @@ static void deleteChildren(GroupEntryList* const entries)
cc4group_applyMemoryManagementEnd(entry->value.memoryManagement, entry->value.data);
}
- if(entry->value.core.Directory)
+ // if they are not loaded yet, there is no need to delete them
+ if(entry->value.core.Directory && entry->value.children != NULL)
{
deleteChildren(entry->value.children);
}
@@ -991,16 +992,27 @@ static void cc4group_init(CC4Group* const this)
this->error.lastFormattedMessage = NULL;
}
-static void cc4group_setMakerRecursively(CC4Group* const this, const C4GroupEntryData* groupEntry, const char* const maker)
+static bool cc4group_setMakerRecursively(CC4Group* const this, const C4GroupEntryData* groupEntry, const char* const maker)
{
- ForeachGroupEntry(cc4group_getChildren(this, groupEntry))
+ GroupEntryList* children = cc4group_getChildren(this, groupEntry);
+ if(children == NULL)
+ {
+ return false;
+ }
+
+ ForeachGroupEntry(children)
{
if(entry->value.core.Directory)
{
C4GroupHeader_setMaker(entry->value.header, maker);
- cc4group_setMakerRecursively(this, &entry->value, maker);
+ if(!cc4group_setMakerRecursively(this, &entry->value, maker))
+ {
+ return false;
+ }
}
}
+
+ return true;
}
static bool cc4group_setMaker(CC4Group* const this, const char* const maker, const char* const path, bool const recursive)
@@ -1018,21 +1030,32 @@ static bool cc4group_setMaker(CC4Group* const this, const char* const maker, con
C4GroupHeader_setMaker(entry->header, maker);
if(recursive)
{
- cc4group_setMakerRecursively(this, entry, maker);
+ return cc4group_setMakerRecursively(this, entry, maker);
}
return true;
}
-static void cc4group_setOfficialRecursively(CC4Group* const this, const C4GroupEntryData* groupEntry, bool const official)
+static bool cc4group_setOfficialRecursively(CC4Group* const this, const C4GroupEntryData* groupEntry, bool const official)
{
- ForeachGroupEntry(cc4group_getChildren(this, groupEntry))
+ GroupEntryList* children = cc4group_getChildren(this, groupEntry);
+ if(children == NULL)
+ {
+ return false;
+ }
+
+ ForeachGroupEntry(children)
{
if(entry->value.core.Directory)
{
C4GroupHeader_setOfficial(entry->value.header, official);
- cc4group_setOfficialRecursively(this, &entry->value, official);
+ if(!cc4group_setOfficialRecursively(this, &entry->value, official))
+ {
+ return false;
+ }
}
}
+
+ return true;
}
static bool cc4group_setOfficial(CC4Group* const this, bool const official, const char* const path, bool const recursive)
@@ -1049,22 +1072,33 @@ static bool cc4group_setOfficial(CC4Group* const this, bool const official, cons
C4GroupHeader_setOfficial(entry->header, official);
if(recursive)
{
- cc4group_setOfficialRecursively(this, entry, official);
+ return cc4group_setOfficialRecursively(this, entry, official);
}
return true;
}
-static void cc4group_setCreationRecursively(CC4Group* const this, const C4GroupEntryData* groupEntry, int32_t const creation)
+static bool cc4group_setCreationRecursively(CC4Group* const this, const C4GroupEntryData* groupEntry, int32_t const creation)
{
- ForeachGroupEntry(cc4group_getChildren(this, groupEntry))
+ GroupEntryList* children = cc4group_getChildren(this, groupEntry);
+ if(children == NULL)
+ {
+ return false;
+ }
+
+ ForeachGroupEntry(children)
{
entry->value.core.Modified = creation;
if(entry->value.core.Directory)
{
C4GroupHeader_setCreation(entry->value.header, creation);
- cc4group_setCreationRecursively(this, &entry->value, creation);
+ if(!cc4group_setCreationRecursively(this, &entry->value, creation))
+ {
+ return false;
+ }
}
}
+
+ return true;
}
static bool cc4group_setCreation(CC4Group* const this, int32_t const creation, const char* const path, bool const recursive)
@@ -1085,7 +1119,7 @@ static bool cc4group_setCreation(CC4Group* const this, int32_t const creation, c
C4GroupHeader_setCreation(entry->header, creation);
if(recursive)
{
- cc4group_setCreationRecursively(this, entry, creation);
+ return cc4group_setCreationRecursively(this, entry, creation);
}
}
return true;
@@ -1206,7 +1240,12 @@ static bool cc4group_extractEntry(CC4Group* const this, const C4GroupEntryData*
SET_ERRNO_ERROR("open: Creating target file");
return false;
}
- write(file, cc4group_getOnlyEntryData(this, root), root->core.Size);
+ const uint8_t* data = cc4group_getOnlyEntryData(this, root);
+ if(data == NULL)
+ {
+ return false;
+ }
+ write(file, data, root->core.Size);
if(close(file) == -1)
{
@@ -1254,7 +1293,14 @@ static bool cc4group_extractChildren(CC4Group* const this, const C4GroupEntryDat
goto ret;
}
- ForeachGroupEntry(cc4group_getChildren(this, root))
+ GroupEntryList* children = cc4group_getChildren(this, root);
+ if(children == NULL)
+ {
+ success = false;
+ goto ret;
+ }
+
+ ForeachGroupEntry(children)
{
if(!cc4group_extractChildren(this, &entry->value, tmpPath))
{
@@ -1268,7 +1314,7 @@ static bool cc4group_extractChildren(CC4Group* const this, const C4GroupEntryDat
}
else
{
- success = cc4group_extractEntry(this ,root, tmpPath);
+ success = cc4group_extractEntry(this, root, tmpPath);
goto ret;
}
@@ -1329,8 +1375,16 @@ static const C4GroupEntryData* cc4group_getEntryByPath(CC4Group* const this, con
break;
}
+ GroupEntryList* children = cc4group_getChildren(this, currentParent);
+ if(!children)
+ {
+ *error = true;
+ currentParent = NULL;
+ goto ret;
+ }
+
bool found = false;
- ForeachGroupEntry(cc4group_getChildren(this, currentParent))
+ ForeachGroupEntry(children)
{
if(strcmp(entry->value.core.FileName, part) == 0)
{
@@ -1347,6 +1401,7 @@ static const C4GroupEntryData* cc4group_getEntryByPath(CC4Group* const this, con
}
}
+ret:
free(path);
return currentParent;
@@ -1468,7 +1523,7 @@ static bool cc4group_getEntryData(CC4Group* const this, const char* const entryP
*data = cc4group_getOnlyEntryData(this, entry);
*size = entry->core.Size;
- return true;
+ return *data != NULL || *size == 0;
}
static void cc4group_setTmpMemoryStrategy(const CC4Group_TmpMemoryStrategy strategy)
@@ -1515,6 +1570,11 @@ static size_t cc4group_calculateEntrySizes(CC4Group* const this, C4GroupEntryDat
if(entryData->core.Directory)
{
GroupEntryList* children = cc4group_getChildren(this, entryData);
+ if(children == NULL)
+ {
+ return 0;
+ }
+
size_t sum = sizeof(C4GroupHeader) + GroupEntryListSize(children) * sizeof(C4GroupEntryCore);
ForeachGroupEntry(children)
{
@@ -1533,8 +1593,14 @@ static void cc4group_calculateEntryCRC(CC4Group* const this, C4GroupEntryData* c
{
if(groupEntry->core.Directory)
{
+ GroupEntryList* children = cc4group_getChildren(this, groupEntry);
+ if(children == NULL)
+ {
+ return;
+ }
+
uint32_t crc = 0;
- ForeachGroupEntry(cc4group_getChildren(this, groupEntry))
+ ForeachGroupEntry(children)
{
cc4group_calculateEntryCRC(this, &entry->value);
crc ^= entry->value.core.CRC;
@@ -1544,7 +1610,12 @@ static void cc4group_calculateEntryCRC(CC4Group* const this, C4GroupEntryData* c
}
else if(groupEntry->core.HasCRC != C4GroupEntryCore_ContentsFileNameCRC)
{
- uint32_t crc = crc32(0, cc4group_getOnlyEntryData(this, groupEntry), groupEntry->core.Size);
+ const uint8_t* data = cc4group_getOnlyEntryData(this, groupEntry);
+ if(data == NULL)
+ {
+ return;
+ }
+ uint32_t crc = crc32(0, data, groupEntry->core.Size);
crc = crc32(crc, (uint8_t*)groupEntry->core.FileName, strlen(groupEntry->core.FileName));
groupEntry->core.HasCRC = C4GroupEntryCore_ContentsFileNameCRC;
@@ -1651,8 +1722,20 @@ static bool cc4group_deflateToCallback(WriteCallback* const callback, const void
static bool cc4group_writeEntries(CC4Group* const this, C4GroupEntryData* const entryData, WriteCallback* const callback)
{
- C4GroupHeader header = *(C4GroupHeader*)cc4group_getOnlyEntryData(this, entryData);
+ const C4GroupHeader* origHeader = (const C4GroupHeader*)cc4group_getOnlyEntryData(this, entryData);
+ if(origHeader == NULL)
+ {
+ return false;
+ }
+
+ C4GroupHeader header = *origHeader;
GroupEntryList* children = cc4group_getChildren(this, entryData);
+
+ if(children == NULL)
+ {
+ return false;
+ }
+
header.Entries = GroupEntryListSize(children);
header.Ver1 = 1;
header.Ver2 = 2;
@@ -1698,7 +1781,13 @@ static bool cc4group_writeEntries(CC4Group* const this, C4GroupEntryData* const
}
else if(entry->value.core.Size > 0)
{
- if(!cc4group_deflateToCallback(callback, cc4group_getOnlyEntryData(this, &entry->value), entry->value.core.Size, Z_NO_FLUSH, Z_OK))
+ const uint8_t* data = cc4group_getOnlyEntryData(this, &entry->value);
+ if(data == NULL)
+ {
+ return false;
+ }
+
+ if(!cc4group_deflateToCallback(callback, data, entry->value.core.Size, Z_NO_FLUSH, Z_OK))
{
SET_MESSAGE_ERROR("Failed writing entry data");
return false;
@@ -1939,6 +2028,11 @@ static bool cc4group_getEntryInfos(CC4Group* const this, const char* const path,
}
GroupEntryList* children = cc4group_getChildren(this, node);
+ if(children == NULL)
+ {
+ return false;
+ }
+
*size = GroupEntryListSize(children);
CC4Group_EntryInfo* myInfos = malloc(*size * sizeof(CC4Group_EntryInfo));
if(myInfos == NULL)
@@ -2004,8 +2098,16 @@ static bool cc4group_getParentAndChildEntries(CC4Group* const this, const char*
}
*parentEntry = parent;
+
+ GroupEntryList* children = cc4group_getChildren(this, parent);
+ if(children == NULL)
+ {
+ free(myPath);
+ return false;
+ }
+
GroupEntryListEntry* child = NULL;
- ForeachGroupEntry(cc4group_getChildren(this, parent))
+ ForeachGroupEntry(children)
{
if(strcmp(entry->value.core.FileName, entryName) == 0)
{
@@ -2046,10 +2148,16 @@ static bool cc4group_deleteEntry(CC4Group* const this, const char* const path, b
return false;
}
- deleteChildren(cc4group_getChildren(this, &deleteEntry->value));
+ // if they are not loaded yet, there is no need to delete them
+ if(deleteEntry->value.children != NULL)
+ {
+ deleteChildren(deleteEntry->value.children);
+ }
}
GroupEntryList* parentChildren = cc4group_getChildren(this, parent);
+ assert(parentChildren); // if there was an error, it should have really been catched already in cc4group_getParentAndChildEntries
+
GroupEntryListRemove(parentChildren, deleteEntry);
parent->header->Entries = GroupEntryListSize(parentChildren);
@@ -2062,6 +2170,11 @@ static C4GroupEntryData* cc4group_addEntryToDirectory(CC4Group* const this, C4Gr
// TODO? Implement engine-optimized order sorting here?
GroupEntryList* directoryChildren = cc4group_getChildren(this, directory);
+ if(directoryChildren == NULL)
+ {
+ return NULL; // TODO: error checking in callees of this
+ }
+
C4GroupEntryData* newEntry = &GroupEntryListAppend(directoryChildren, *entry)->value;
newEntry->parent = directory;
directory->header->Entries = GroupEntryListSize(directoryChildren);
@@ -2113,7 +2226,13 @@ static bool cc4group_renameEntry(CC4Group* const this, const char* const oldPath
}
C4GroupEntryCore_setFileName(&entry->value.core, targetName);
- cc4group_addEntryToDirectory(this, newParent, &entry->value);
+ if(cc4group_addEntryToDirectory(this, newParent, &entry->value) == NULL)
+ {
+ free(targetPath);
+ return false;
+ }
+
+ assert(cc4group_getChildren(this, oldParent)); // again, should have been catched already with cc4group_getParentAndChildEntries
GroupEntryListRemove(cc4group_getChildren(this, oldParent), entry);
free(targetPath);
@@ -2131,7 +2250,7 @@ static C4GroupEntryData* cc4group_createEntry(CC4Group* const this, const char*
if(error)
{
- return false;
+ return NULL;
}
char* targetPath = strdup(path);
@@ -2294,6 +2413,13 @@ static CC4Group* cc4group_openAsChild(CC4Group* const this, const char* const pa
child->root.core.Directory = 1;
child->root.core.FileName[0] = '\0';
child->root.children = cc4group_getChildren(this, entry);
+
+ if(child->root.children == NULL)
+ {
+ cc4group_delete(child);
+ return NULL;
+ }
+
child->parent = this;
++this->referenceCounter;