From c369af4adfba9aaf8e15745c49a61639d3e2fb67 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Sun, 31 May 2020 07:04:00 -0400 Subject: [PATCH] assetnameparser: Make Fopen return a unique_ptr Prevents leaks from occurring (aside from obvious .release() calls). --- assetnameparser/main.cpp | 61 ++++++++++++++++++++++------------------ 1 file changed, 33 insertions(+), 28 deletions(-) diff --git a/assetnameparser/main.cpp b/assetnameparser/main.cpp index af86b8bf0..a4a2c6465 100644 --- a/assetnameparser/main.cpp +++ b/assetnameparser/main.cpp @@ -1,8 +1,10 @@ -#include #include +#include +#include #include + +#include #include "tinyxml2/tinyxml2.h" -#include "logvisor/logvisor.hpp" #ifndef _WIN32 #include @@ -150,25 +152,33 @@ using SystemString = std::string; using Sstat = struct stat; #endif -FILE* Fopen(const SystemChar* path, const SystemChar* mode, FileLockType lock = FileLockType::None) { +struct FILEDeleter { + void operator()(FILE* file) const { std::fclose(file); } +}; +using FILEPtr = std::unique_ptr; + +FILEPtr Fopen(const SystemChar* path, const SystemChar* mode, FileLockType lock = FileLockType::None) { #if IS_UCS2 - FILE* fp = _wfopen(path, mode); - if (!fp) + FILEPtr fp{_wfopen(path, mode)}; + if (!fp) { return nullptr; + } #else - FILE* fp = fopen(path, mode); - if (!fp) + FILEPtr fp{std::fopen(path, mode)}; + if (!fp) { return nullptr; + } #endif if (lock != FileLockType::None) { #if _WIN32 OVERLAPPED ov = {}; - LockFileEx((HANDLE)(uintptr_t)_fileno(fp), (lock == FileLockType::Write) ? LOCKFILE_EXCLUSIVE_LOCK : 0, 0, 0, 1, - &ov); + LockFileEx((HANDLE)(uintptr_t)_fileno(fp.get()), (lock == FileLockType::Write) ? LOCKFILE_EXCLUSIVE_LOCK : 0, 0, 0, + 1, &ov); #else - if (flock(fileno(fp), ((lock == FileLockType::Write) ? LOCK_EX : LOCK_SH) | LOCK_NB)) - fprintf(stderr, "flock %s: %s", path, strerror(errno)); + if (flock(fileno(fp.get()), ((lock == FileLockType::Write) ? LOCK_EX : LOCK_SH) | LOCK_NB)) { + std::fprintf(stderr, "flock %s: %s", path, strerror(errno)); + } #endif } @@ -194,8 +204,8 @@ int main(int argc, const char* argv[]) tinyxml2::XMLDocument doc; std::vector assets; - FILE* docF = Fopen(inPath.c_str(), _SYS_STR("rb")); - if (doc.LoadFile(docF) == tinyxml2::XML_SUCCESS) { + FILEPtr docF = Fopen(inPath.c_str(), _SYS_STR("rb")); + if (doc.LoadFile(docF.get()) == tinyxml2::XML_SUCCESS) { const tinyxml2::XMLElement* elm = doc.RootElement(); if (strcmp(elm->Name(), "AssetNameMap") != 0) { Log.report(logvisor::Fatal, FMT_STRING(_SYS_STR("Invalid database supplied"))); @@ -241,7 +251,7 @@ int main(int argc, const char* argv[]) elm = elm->NextSiblingElement("Asset"); } - FILE* f = Fopen(outPath.c_str(), _SYS_STR("wb")); + FILEPtr f = Fopen(outPath.c_str(), _SYS_STR("wb")); if (f == nullptr) { Log.report(logvisor::Fatal, FMT_STRING(_SYS_STR("Unable to open destination"))); return 0; @@ -249,28 +259,23 @@ int main(int argc, const char* argv[]) uint32_t assetCount = SBig(uint32_t(assets.size())); FourCC sentinel(SBIG('AIDM')); - fwrite(&sentinel, 1, 4, f); - fwrite(&assetCount, 1, 4, f); + fwrite(&sentinel, 1, sizeof(sentinel), f.get()); + fwrite(&assetCount, 1, sizeof(assetCount), f.get()); for (const SAsset& asset : assets) { - fwrite(&asset.type, 1, 4, f); + fwrite(&asset.type, 1, sizeof(asset.type), f.get()); uint64_t id = SBig(asset.id); - fwrite(&id, 1, 8, f); + fwrite(&id, 1, sizeof(id), f.get()); uint32_t tmp = SBig(uint32_t(asset.name.length())); - fwrite(&tmp, 1, 4, f); - fwrite(asset.name.c_str(), 1, SBig(tmp), f); + fwrite(&tmp, 1, sizeof(tmp), f.get()); + fwrite(asset.name.c_str(), 1, SBig(tmp), f.get()); tmp = SBig(uint32_t(asset.dir.length())); - fwrite(&tmp, 1, 4, f); - fwrite(asset.dir.c_str(), 1, SBig(tmp), f); + fwrite(&tmp, 1, sizeof(tmp), f.get()); + fwrite(asset.dir.c_str(), 1, SBig(tmp), f.get()); } - fflush(f); - fclose(f); - fclose(docF); + fflush(f.get()); return 0; } - if (docF) - fclose(docF); - Log.report(logvisor::Fatal, FMT_STRING(_SYS_STR("failed to load"))); return 1; }