diff --git a/common/util/DgoReader.cpp b/common/util/DgoReader.cpp index 2e1def774f..2474eb1364 100644 --- a/common/util/DgoReader.cpp +++ b/common/util/DgoReader.cpp @@ -16,7 +16,17 @@ DgoReader::DgoReader(std::string file_name, const std::vector& data) // get all obj files... for (uint32_t i = 0; i < header.object_count; i++) { - auto obj_header = reader.read(); + ObjectHeader obj_header = reader.read(); + + if (reader.bytes_left() < obj_header.size && i == header.object_count - 1 && + obj_header.size - reader.bytes_left() <= 48) { + printf( + "Warning: final file %s in DGO %s has a size missing %d bytes. It will be adjusted from " + "%d to %d bytes.\n", + obj_header.name, header.name, obj_header.size - reader.bytes_left(), obj_header.size, + (int)reader.bytes_left()); + obj_header.size = reader.bytes_left(); + } assert(reader.bytes_left() >= obj_header.size); assert_string_empty_after(obj_header.name, 60); diff --git a/common/util/FileUtil.cpp b/common/util/FileUtil.cpp index 5721b39a41..9a4e52e189 100644 --- a/common/util/FileUtil.cpp +++ b/common/util/FileUtil.cpp @@ -15,6 +15,7 @@ #include "BinaryWriter.h" #include "common/common_types.h" #include "third-party/svpng.h" +#include "third-party/fmt/core.h" #include "third-party/lzokay/lzokay.hpp" #ifdef _WIN32 @@ -119,6 +120,21 @@ void write_text_file(const std::string& file_name, const std::string& text) { } std::vector read_binary_file(const std::string& filename) { + // make sure file exists and isn't a directory + std::filesystem::path path(filename); + + auto status = std::filesystem::status(std::filesystem::path(filename)); + + if (!std::filesystem::exists(status)) { + throw std::runtime_error(fmt::format("File {} cannot be opened: does not exist.", filename)); + } + + if (status.type() != std::filesystem::file_type::regular && + status.type() != std::filesystem::file_type::symlink) { + throw std::runtime_error( + fmt::format("File {} cannot be opened: not a regular file or symlink.", filename)); + } + auto fp = fopen(filename.c_str(), "rb"); if (!fp) throw std::runtime_error("File " + filename + diff --git a/tools/dgo_unpacker.cpp b/tools/dgo_unpacker.cpp index 289a28afe1..35ee96d6fb 100644 --- a/tools/dgo_unpacker.cpp +++ b/tools/dgo_unpacker.cpp @@ -1,9 +1,11 @@ #include +#include #include "common/versions.h" #include "common/util/FileUtil.h" #include "common/util/DgoReader.h" -int main(int argc, char** argv) { +namespace { +int run(int argc, char** argv) { printf("OpenGOAL version %d.%d\n", versions::GOAL_VERSION_MAJOR, versions::GOAL_VERSION_MINOR); printf("DGO Unpacking Tool\n"); @@ -42,3 +44,13 @@ int main(int argc, char** argv) { printf("Done\n"); return 0; } +} // namespace + +int main(int argc, char** argv) { + try { + return run(argc, argv); + } catch (const std::exception& e) { + printf("An error occurred: %s\n", e.what()); + return 1; + } +}