mirror of
https://github.com/OpenMW/openmw.git
synced 2026-05-06 07:56:40 -04:00
Handle errors when computing stream size for BSA
This commit is contained in:
@@ -321,7 +321,7 @@ ENDIF()
|
||||
add_component_dir (files
|
||||
linuxpath androidpath windowspath macospath fixedpath multidircollection collections configurationmanager
|
||||
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")
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <components/esm/fourcc.hpp>
|
||||
#include <components/files/constrainedfilestream.hpp>
|
||||
#include <components/files/conversion.hpp>
|
||||
#include <components/files/utils.hpp>
|
||||
#include <components/misc/strings/lower.hpp>
|
||||
|
||||
#include "ba2file.hpp"
|
||||
@@ -80,13 +81,7 @@ namespace Bsa
|
||||
|
||||
std::ifstream input(mFilepath, std::ios_base::binary);
|
||||
|
||||
// Total archive size
|
||||
std::streamoff fsize = 0;
|
||||
if (input.seekg(0, std::ios_base::end))
|
||||
{
|
||||
fsize = input.tellg();
|
||||
input.seekg(0);
|
||||
}
|
||||
const std::streamsize fsize = Files::getStreamSizeLeft(input);
|
||||
|
||||
if (fsize < 24) // header is 24 bytes
|
||||
fail("File too small to be a valid BSA archive");
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <components/esm/fourcc.hpp>
|
||||
#include <components/files/constrainedfilestream.hpp>
|
||||
#include <components/files/conversion.hpp>
|
||||
#include <components/files/utils.hpp>
|
||||
#include <components/misc/strings/lower.hpp>
|
||||
|
||||
#include "ba2file.hpp"
|
||||
@@ -75,13 +76,7 @@ namespace Bsa
|
||||
|
||||
std::ifstream input(mFilepath, std::ios_base::binary);
|
||||
|
||||
// Total archive size
|
||||
std::streamoff fsize = 0;
|
||||
if (input.seekg(0, std::ios_base::end))
|
||||
{
|
||||
fsize = input.tellg();
|
||||
input.seekg(0);
|
||||
}
|
||||
const std::streamsize fsize = Files::getStreamSizeLeft(input);
|
||||
|
||||
if (fsize < 24) // header is 24 bytes
|
||||
fail("File too small to be a valid BSA archive");
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
|
||||
#include <components/esm/fourcc.hpp>
|
||||
#include <components/files/constrainedfilestream.hpp>
|
||||
#include <components/files/utils.hpp>
|
||||
|
||||
using namespace Bsa;
|
||||
|
||||
@@ -106,12 +107,7 @@ void BSAFile::readHeader()
|
||||
std::ifstream input(mFilepath, std::ios_base::binary);
|
||||
|
||||
// Total archive size
|
||||
std::streamoff fsize = 0;
|
||||
if (input.seekg(0, std::ios_base::end))
|
||||
{
|
||||
fsize = input.tellg();
|
||||
input.seekg(0);
|
||||
}
|
||||
const std::streamsize fsize = Files::getStreamSizeLeft(input);
|
||||
|
||||
if (fsize < 12)
|
||||
fail("File too small to be a valid BSA archive");
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
|
||||
#include <components/files/constrainedfilestream.hpp>
|
||||
#include <components/files/conversion.hpp>
|
||||
#include <components/files/utils.hpp>
|
||||
#include <components/misc/strings/lower.hpp>
|
||||
|
||||
#include "memorystream.hpp"
|
||||
@@ -50,13 +51,7 @@ namespace Bsa
|
||||
|
||||
std::ifstream input(mFilepath, std::ios_base::binary);
|
||||
|
||||
// Total archive size
|
||||
std::streamoff fsize = 0;
|
||||
if (input.seekg(0, std::ios_base::end))
|
||||
{
|
||||
fsize = input.tellg();
|
||||
input.seekg(0);
|
||||
}
|
||||
const std::streamsize fsize = Files::getStreamSizeLeft(input);
|
||||
|
||||
if (fsize < 36) // Header is 36 bytes
|
||||
fail("File too small to be a valid BSA archive");
|
||||
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user