mirror of
https://github.com/holub/mame
synced 2025-06-16 01:09:09 +03:00
chdman.cpp: fix for code that expects to be able to dereference a pointer that it knows may be null (Vas Crabb)
This commit is contained in:
parent
cfee536f22
commit
00fd6ba0bd
@ -25,6 +25,10 @@
|
|||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <cassert>
|
||||||
|
#include <cstring>
|
||||||
|
#include <limits>
|
||||||
|
#include <memory>
|
||||||
#include <new>
|
#include <new>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
@ -191,19 +195,52 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// ======================> chd_zero_compressor
|
||||||
|
|
||||||
|
class chd_zero_compressor : public chd_file_compressor
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// construction/destruction
|
||||||
|
chd_zero_compressor(std::uint64_t offset = 0, std::uint64_t maxoffset = 0)
|
||||||
|
: m_offset(offset)
|
||||||
|
, m_maxoffset(maxoffset)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// read interface
|
||||||
|
virtual std::uint32_t read_data(void *dest, std::uint64_t offset, std::uint32_t length) override
|
||||||
|
{
|
||||||
|
offset += m_offset;
|
||||||
|
if (offset >= m_maxoffset)
|
||||||
|
return 0;
|
||||||
|
if (offset + length > m_maxoffset)
|
||||||
|
length = m_maxoffset - offset;
|
||||||
|
std::memset(dest, 0, length);
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
// internal state
|
||||||
|
std::uint64_t m_offset;
|
||||||
|
std::uint64_t m_maxoffset;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// ======================> chd_rawfile_compressor
|
// ======================> chd_rawfile_compressor
|
||||||
|
|
||||||
class chd_rawfile_compressor : public chd_file_compressor
|
class chd_rawfile_compressor : public chd_file_compressor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// construction/destruction
|
// construction/destruction
|
||||||
chd_rawfile_compressor(util::core_file &file, UINT64 offset = 0, UINT64 maxoffset = ~0)
|
chd_rawfile_compressor(util::core_file &file, std::uint64_t offset = 0, std::uint64_t maxoffset = std::numeric_limits<std::uint64_t>::max())
|
||||||
: m_file(file),
|
: m_file(file)
|
||||||
m_offset(offset),
|
, m_offset(offset)
|
||||||
m_maxoffset((std::min)(maxoffset, file.size())) { }
|
, m_maxoffset((std::min)(maxoffset, file.size()))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
// read interface
|
// read interface
|
||||||
virtual UINT32 read_data(void *dest, UINT64 offset, UINT32 length)
|
virtual std::uint32_t read_data(void *dest, std::uint64_t offset, std::uint32_t length) override
|
||||||
{
|
{
|
||||||
offset += m_offset;
|
offset += m_offset;
|
||||||
if (offset >= m_maxoffset)
|
if (offset >= m_maxoffset)
|
||||||
@ -217,8 +254,8 @@ public:
|
|||||||
private:
|
private:
|
||||||
// internal state
|
// internal state
|
||||||
util::core_file & m_file;
|
util::core_file & m_file;
|
||||||
UINT64 m_offset;
|
std::uint64_t m_offset;
|
||||||
UINT64 m_maxoffset;
|
std::uint64_t m_maxoffset;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -1626,11 +1663,10 @@ static void do_create_raw(parameters_t ¶ms)
|
|||||||
printf("Logical size: %s\n", big_int_string(tempstr, input_end - input_start));
|
printf("Logical size: %s\n", big_int_string(tempstr, input_end - input_start));
|
||||||
|
|
||||||
// catch errors so we can close & delete the output file
|
// catch errors so we can close & delete the output file
|
||||||
chd_rawfile_compressor *chd = nullptr;
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// create the new CHD
|
// create the new CHD
|
||||||
chd = new chd_rawfile_compressor(*input_file, input_start, input_end);
|
std::unique_ptr<chd_file_compressor> chd(new chd_rawfile_compressor(*input_file, input_start, input_end));
|
||||||
chd_error err;
|
chd_error err;
|
||||||
if (output_parent.opened())
|
if (output_parent.opened())
|
||||||
err = chd->create(output_chd_str->c_str(), input_end - input_start, hunk_size, compression, output_parent);
|
err = chd->create(output_chd_str->c_str(), input_end - input_start, hunk_size, compression, output_parent);
|
||||||
@ -1645,11 +1681,9 @@ static void do_create_raw(parameters_t ¶ms)
|
|||||||
|
|
||||||
// compress it generically
|
// compress it generically
|
||||||
compress_common(*chd);
|
compress_common(*chd);
|
||||||
delete chd;
|
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
delete chd;
|
|
||||||
// delete the output file
|
// delete the output file
|
||||||
auto output_chd_str = params.find(OPTION_OUTPUT);
|
auto output_chd_str = params.find(OPTION_OUTPUT);
|
||||||
if (output_chd_str != params.end())
|
if (output_chd_str != params.end())
|
||||||
@ -1804,11 +1838,12 @@ static void do_create_hd(parameters_t ¶ms)
|
|||||||
printf("Logical size: %s\n", big_int_string(tempstr, UINT64(totalsectors) * UINT64(sector_size)));
|
printf("Logical size: %s\n", big_int_string(tempstr, UINT64(totalsectors) * UINT64(sector_size)));
|
||||||
|
|
||||||
// catch errors so we can close & delete the output file
|
// catch errors so we can close & delete the output file
|
||||||
chd_rawfile_compressor *chd = nullptr;
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// create the new hard drive
|
// create the new hard drive
|
||||||
chd = new chd_rawfile_compressor(*input_file, input_start, input_end);
|
std::unique_ptr<chd_file_compressor> chd;
|
||||||
|
if (input_file) chd.reset(new chd_rawfile_compressor(*input_file, input_start, input_end));
|
||||||
|
else chd.reset(new chd_zero_compressor(input_start, input_end));
|
||||||
chd_error err;
|
chd_error err;
|
||||||
if (output_parent.opened())
|
if (output_parent.opened())
|
||||||
err = chd->create(output_chd_str->c_str(), UINT64(totalsectors) * UINT64(sector_size), hunk_size, compression, output_parent);
|
err = chd->create(output_chd_str->c_str(), UINT64(totalsectors) * UINT64(sector_size), hunk_size, compression, output_parent);
|
||||||
@ -1834,11 +1869,9 @@ static void do_create_hd(parameters_t ¶ms)
|
|||||||
// compress it generically
|
// compress it generically
|
||||||
if (input_file)
|
if (input_file)
|
||||||
compress_common(*chd);
|
compress_common(*chd);
|
||||||
delete chd;
|
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
delete chd;
|
|
||||||
// delete the output file
|
// delete the output file
|
||||||
auto output_chd_str = params.find(OPTION_OUTPUT);
|
auto output_chd_str = params.find(OPTION_OUTPUT);
|
||||||
if (output_chd_str != params.end())
|
if (output_chd_str != params.end())
|
||||||
|
Loading…
Reference in New Issue
Block a user