1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-10-14 21:56:36 +00:00

Handle errors when computing stream size for BSA

This commit is contained in:
elsid 2025-09-19 19:26:22 +02:00
parent 796202f435
commit 801224749f
No known key found for this signature in database
GPG key ID: B845CB9FEE18AB40
6 changed files with 47 additions and 28 deletions

View file

@ -321,7 +321,7 @@ ENDIF()
add_component_dir (files add_component_dir (files
linuxpath androidpath windowspath macospath fixedpath multidircollection collections configurationmanager linuxpath androidpath windowspath macospath fixedpath multidircollection collections configurationmanager
constrainedfilestream memorystream hash configfileparser openfile constrainedfilestreambuf conversion constrainedfilestream memorystream hash configfileparser openfile constrainedfilestreambuf conversion
istreamptr streamwithbuffer istreamptr streamwithbuffer utils
) )
if(NOT CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" AND NOT CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC") if(NOT CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" AND NOT CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC")

View file

@ -12,6 +12,7 @@
#include <components/esm/fourcc.hpp> #include <components/esm/fourcc.hpp>
#include <components/files/constrainedfilestream.hpp> #include <components/files/constrainedfilestream.hpp>
#include <components/files/conversion.hpp> #include <components/files/conversion.hpp>
#include <components/files/utils.hpp>
#include <components/misc/strings/lower.hpp> #include <components/misc/strings/lower.hpp>
#include "ba2file.hpp" #include "ba2file.hpp"
@ -80,13 +81,7 @@ namespace Bsa
std::ifstream input(mFilepath, std::ios_base::binary); std::ifstream input(mFilepath, std::ios_base::binary);
// Total archive size const std::streamsize fsize = Files::getStreamSizeLeft(input);
std::streamoff fsize = 0;
if (input.seekg(0, std::ios_base::end))
{
fsize = input.tellg();
input.seekg(0);
}
if (fsize < 24) // header is 24 bytes if (fsize < 24) // header is 24 bytes
fail("File too small to be a valid BSA archive"); fail("File too small to be a valid BSA archive");

View file

@ -11,6 +11,7 @@
#include <components/esm/fourcc.hpp> #include <components/esm/fourcc.hpp>
#include <components/files/constrainedfilestream.hpp> #include <components/files/constrainedfilestream.hpp>
#include <components/files/conversion.hpp> #include <components/files/conversion.hpp>
#include <components/files/utils.hpp>
#include <components/misc/strings/lower.hpp> #include <components/misc/strings/lower.hpp>
#include "ba2file.hpp" #include "ba2file.hpp"
@ -75,13 +76,7 @@ namespace Bsa
std::ifstream input(mFilepath, std::ios_base::binary); std::ifstream input(mFilepath, std::ios_base::binary);
// Total archive size const std::streamsize fsize = Files::getStreamSizeLeft(input);
std::streamoff fsize = 0;
if (input.seekg(0, std::ios_base::end))
{
fsize = input.tellg();
input.seekg(0);
}
if (fsize < 24) // header is 24 bytes if (fsize < 24) // header is 24 bytes
fail("File too small to be a valid BSA archive"); fail("File too small to be a valid BSA archive");

View file

@ -31,6 +31,7 @@
#include <components/esm/fourcc.hpp> #include <components/esm/fourcc.hpp>
#include <components/files/constrainedfilestream.hpp> #include <components/files/constrainedfilestream.hpp>
#include <components/files/utils.hpp>
using namespace Bsa; using namespace Bsa;
@ -106,12 +107,7 @@ void BSAFile::readHeader()
std::ifstream input(mFilepath, std::ios_base::binary); std::ifstream input(mFilepath, std::ios_base::binary);
// Total archive size // Total archive size
std::streamoff fsize = 0; const std::streamsize fsize = Files::getStreamSizeLeft(input);
if (input.seekg(0, std::ios_base::end))
{
fsize = input.tellg();
input.seekg(0);
}
if (fsize < 12) if (fsize < 12)
fail("File too small to be a valid BSA archive"); fail("File too small to be a valid BSA archive");

View file

@ -37,6 +37,7 @@
#include <components/files/constrainedfilestream.hpp> #include <components/files/constrainedfilestream.hpp>
#include <components/files/conversion.hpp> #include <components/files/conversion.hpp>
#include <components/files/utils.hpp>
#include <components/misc/strings/lower.hpp> #include <components/misc/strings/lower.hpp>
#include "memorystream.hpp" #include "memorystream.hpp"
@ -50,13 +51,7 @@ namespace Bsa
std::ifstream input(mFilepath, std::ios_base::binary); std::ifstream input(mFilepath, std::ios_base::binary);
// Total archive size const std::streamsize fsize = Files::getStreamSizeLeft(input);
std::streamoff fsize = 0;
if (input.seekg(0, std::ios_base::end))
{
fsize = input.tellg();
input.seekg(0);
}
if (fsize < 36) // Header is 36 bytes if (fsize < 36) // Header is 36 bytes
fail("File too small to be a valid BSA archive"); fail("File too small to be a valid BSA archive");

View file

@ -0,0 +1,38 @@
#ifndef COMPONENTS_FILES_UTILS_H
#define COMPONENTS_FILES_UTILS_H
#include <cerrno>
#include <format>
#include <istream>
#include <stdexcept>
#include <system_error>
namespace Files
{
inline std::streamsize getStreamSizeLeft(std::istream& stream)
{
const auto begin = stream.tellg();
if (stream.fail())
throw std::runtime_error(
std::format("Failed to get current file position: {}", std::generic_category().message(errno)));
stream.seekg(0, std::ios_base::end);
if (stream.fail())
throw std::runtime_error(
std::format("Failed to seek end file position: {}", std::generic_category().message(errno)));
const auto end = stream.tellg();
if (stream.fail())
throw std::runtime_error(
std::format("Failed to get current file position: {}", std::generic_category().message(errno)));
stream.seekg(begin);
if (stream.fail())
throw std::runtime_error(
std::format("Failed to seek original file position: {}", std::generic_category().message(errno)));
return end - begin;
}
}
#endif