mirror of
https://github.com/OpenMW/openmw.git
synced 2025-10-14 15:26:35 +00:00
Handle errors when computing stream size for BSA
This commit is contained in:
parent
796202f435
commit
801224749f
6 changed files with 47 additions and 28 deletions
|
@ -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")
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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");
|
||||||
|
|
38
components/files/utils.hpp
Normal file
38
components/files/utils.hpp
Normal 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
|
Loading…
Reference in a new issue