summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/diimage.cpp
diff options
context:
space:
mode:
author npwoods <npwoods@alumni.carnegiemellon.edu>2017-05-27 21:23:45 -0400
committer Vas Crabb <cuavas@users.noreply.github.com>2017-05-28 11:23:45 +1000
commit297bea495d0e62acb2cc609546b7da322cddf5b7 (patch)
tree1ce8dc10e1d40455e96f87e82778cece363a19f3 /src/emu/diimage.cpp
parent46eb9309484163f69c759d1c416b741a958f0549 (diff)
Fixed issue when the hash length is zero (#2314)
* Fixed issue when the hash length is zero The following is illegal, even if no elements in the pointer are accessed: std::vector<my_struct> my_vec(0); // create an empty std::vector my_struct *ptr = &my_vec[0]; While this is a degenerate scenario, this should be fixed
Diffstat (limited to 'src/emu/diimage.cpp')
-rw-r--r--src/emu/diimage.cpp118
1 files changed, 57 insertions, 61 deletions
diff --git a/src/emu/diimage.cpp b/src/emu/diimage.cpp
index 28dad1f82ee..64b09a101f2 100644
--- a/src/emu/diimage.cpp
+++ b/src/emu/diimage.cpp
@@ -175,23 +175,6 @@ iodevice_t device_image_interface::device_typeid(const char *name)
return (iodevice_t)-1;
}
-/*-------------------------------------------------
- device_compute_hash - compute a hash,
- using this device's partial hash if appropriate
--------------------------------------------------*/
-
-void device_image_interface::device_compute_hash(util::hash_collection &hashes, const void *data, size_t length, const char *types) const
-{
- /* retrieve the partial hash func */
- device_image_partialhash_func partialhash = get_partial_hash();
-
- /* compute the hash */
- if (partialhash)
- partialhash(hashes, (const unsigned char*)data, length, types);
- else
- hashes.compute(reinterpret_cast<const u8 *>(data), length, types);
-}
-
//-------------------------------------------------
// set_image_filename - specifies the filename of
// an image
@@ -513,37 +496,46 @@ bool device_image_interface::load_software_region(const char *tag, optional_shar
// to be loaded
// ****************************************************************************
-void device_image_interface::run_hash(util::core_file &file, void (*partialhash)(util::hash_collection &, const unsigned char *, unsigned long, const char *),
- util::hash_collection &hashes, const char *types)
+bool device_image_interface::run_hash(util::core_file &file, u32 skip_bytes, util::hash_collection &hashes, const char *types)
{
- u32 size;
- std::vector<u8> buf;
-
+ // reset the hash; we want to override existing data
hashes.reset();
- size = (u32) file.size();
- buf.resize(size);
- memset(&buf[0], 0, size);
+ // figure out the size, and "cap" the skip bytes
+ u64 size = file.size();
+ skip_bytes = (u32) std::min((u64) skip_bytes, size);
- // read the file
- file.seek(0, SEEK_SET);
- file.read(&buf[0], size);
+ // seek to the beginning
+ file.seek(skip_bytes, SEEK_SET);
+ u64 position = skip_bytes;
- if (partialhash)
- partialhash(hashes, &buf[0], size, types);
- else
- hashes.compute(&buf[0], size, types);
+ // keep on reading hashes
+ hashes.begin(types);
+ while (position < size)
+ {
+ uint8_t buffer[8192];
+
+ // read bytes
+ const u32 count = (u32) std::min(size - position, (u64) sizeof(buffer));
+ const u32 actual_count = file.read(buffer, count);
+ if (actual_count == 0)
+ return false;
+ position += actual_count;
+
+ // and compute the hashes
+ hashes.buffer(buffer, actual_count);
+ }
+ hashes.end();
// cleanup
file.seek(0, SEEK_SET);
+ return true;
}
-void device_image_interface::image_checkhash()
+bool device_image_interface::image_checkhash()
{
- device_image_partialhash_func partialhash;
-
// only calculate CRC if it hasn't been calculated, and the open_mode is read only
u32 crcval;
if (!m_hash.crc(crcval) && is_readonly() && !m_created)
@@ -551,29 +543,26 @@ void device_image_interface::image_checkhash()
// do not cause a linear read of 600 megs please
// TODO: use SHA1 in the CHD header as the hash
if (image_type() == IO_CDROM)
- return;
+ return true;
// Skip calculating the hash when we have an image mounted through a software list
if (loaded_through_softlist())
- return;
-
- // retrieve the partial hash func
- partialhash = get_partial_hash();
+ return true;
- run_hash(*m_file, partialhash, m_hash, util::hash_collection::HASH_TYPES_ALL);
+ // run the hash
+ if (!run_hash(*m_file, unhashed_header_length(), m_hash, util::hash_collection::HASH_TYPES_ALL))
+ return false;
}
- return;
+ return true;
}
util::hash_collection device_image_interface::calculate_hash_on_file(util::core_file &file) const
{
- // retrieve the partial hash func
- device_image_partialhash_func partialhash = get_partial_hash();
-
- // and calculate the hash
+ // calculate the hash
util::hash_collection hash;
- run_hash(file, partialhash, hash, util::hash_collection::HASH_TYPES_ALL);
+ if (!run_hash(file, unhashed_header_length(), hash, util::hash_collection::HASH_TYPES_ALL))
+ hash.reset();
return hash;
}
@@ -1150,25 +1139,32 @@ image_init_result device_image_interface::finish_load()
if (m_is_loading)
{
- image_checkhash();
+ if (!image_checkhash())
+ {
+ m_err = IMAGE_ERROR_INVALIDIMAGE;
+ err = image_init_result::FAIL;
+ }
- if (m_created)
+ if (err == image_init_result::PASS)
{
- err = call_create(m_create_format, m_create_args);
- if (err != image_init_result::PASS)
+ if (m_created)
{
- if (!m_err)
- m_err = IMAGE_ERROR_UNSPECIFIED;
+ err = call_create(m_create_format, m_create_args);
+ if (err != image_init_result::PASS)
+ {
+ if (!m_err)
+ m_err = IMAGE_ERROR_UNSPECIFIED;
+ }
}
- }
- else
- {
- // using device load
- err = call_load();
- if (err != image_init_result::PASS)
+ else
{
- if (!m_err)
- m_err = IMAGE_ERROR_UNSPECIFIED;
+ // using device load
+ err = call_load();
+ if (err != image_init_result::PASS)
+ {
+ if (!m_err)
+ m_err = IMAGE_ERROR_UNSPECIFIED;
+ }
}
}
}