mirror of
https://github.com/holub/mame
synced 2025-04-18 22:49:58 +03:00
formats/cassimg.cpp: Fixed bad image crash in tap format (MT8952)
This commit is contained in:
parent
55e8b75801
commit
8d346a669e
@ -798,7 +798,7 @@ cassette_image::error cassette_image::legacy_construct(const LegacyWaveFiller *l
|
||||
/* sanity check the args */
|
||||
assert(legacy_args->header_samples >= -1);
|
||||
assert(legacy_args->trailer_samples >= 0);
|
||||
assert(legacy_args->fill_wave);
|
||||
assert(legacy_args->fill_wave || legacy_args->fill_wave_ext);
|
||||
|
||||
const uint64_t size = image_size();
|
||||
|
||||
@ -859,22 +859,16 @@ cassette_image::error cassette_image::legacy_construct(const LegacyWaveFiller *l
|
||||
/* convert the file data to samples */
|
||||
while ((pos < sample_count) && (offset < size))
|
||||
{
|
||||
/* allocate a buffer for the binary data */
|
||||
std::vector<uint8_t> chunk(args.chunk_size);
|
||||
image_read(&chunk[0], offset, args.chunk_size);
|
||||
offset += args.chunk_size;
|
||||
const int slice = std::min<int>(args.chunk_size, size - offset);
|
||||
|
||||
/*
|
||||
This approach is problematic because we don't have control on incomming image size when processing the data
|
||||
(at least in tap implementation).
|
||||
The method sending the size of output (calculated in 'chunk_sample_calc' above) which uses same data as a input but
|
||||
without knowing how much data available in the image. Having wrong header with size bigger than image couses illegal
|
||||
access beyond image data.
|
||||
Desired state is:
|
||||
length = args.fill_wave(&samples[pos], args.chunk_size, &chunk[0]);
|
||||
aslo the fix for tap is commented out in 'tap_cas_fill_wave'
|
||||
*/
|
||||
length = args.fill_wave(&samples[pos], sample_count - pos, &chunk[0]);
|
||||
/* allocate a buffer for the binary data */
|
||||
std::vector<uint8_t> chunk(slice);
|
||||
image_read(&chunk[0], offset, slice);
|
||||
offset += slice;
|
||||
|
||||
length = (args.fill_wave_ext != nullptr)
|
||||
? args.fill_wave_ext(&samples[pos], sample_count - pos, &chunk[0], slice)
|
||||
: args.fill_wave(&samples[pos], sample_count - pos, &chunk[0]);
|
||||
if (length < 0)
|
||||
{
|
||||
err = error::INVALID_IMAGE;
|
||||
|
@ -127,6 +127,7 @@ public:
|
||||
uint32_t sample_frequency = 0;
|
||||
int header_samples = 0;
|
||||
int trailer_samples = 0;
|
||||
int (*fill_wave_ext)(int16_t *, int, const uint8_t *, int) = nullptr;
|
||||
};
|
||||
|
||||
~cassette_image();
|
||||
|
@ -809,16 +809,17 @@ static int tap_cas_to_wav_size( const uint8_t *casdata, int caslen )
|
||||
int size = 0;
|
||||
const uint8_t *p = casdata;
|
||||
|
||||
while (caslen > 0)
|
||||
while (caslen > 2)
|
||||
{
|
||||
int data_size = get_u16le(&p[0]);
|
||||
int pilot_length = (p[2] == 0x00) ? 8063 : 3223;
|
||||
caslen -= data_size;
|
||||
if (caslen < 0)
|
||||
caslen -= 2;
|
||||
if (caslen < data_size)
|
||||
{
|
||||
LOG_FORMATS("tap_cas_to_wav_size: Requested 0x%X byte but only 0x%X available.\n", data_size, data_size + caslen);
|
||||
data_size += caslen;
|
||||
LOG_FORMATS("tap_cas_to_wav_size: Requested 0x%X byte but only 0x%X available.\n", data_size, caslen);
|
||||
data_size = caslen;
|
||||
}
|
||||
caslen -= data_size;
|
||||
LOG_FORMATS("tap_cas_to_wav_size: Handling TAP block containing 0x%X bytes", data_size);
|
||||
p += 2;
|
||||
size += tzx_cas_handle_block(nullptr, p, 1000, data_size, 2168, pilot_length, 667, 735, 855, 1710, 8);
|
||||
@ -828,24 +829,22 @@ static int tap_cas_to_wav_size( const uint8_t *casdata, int caslen )
|
||||
return size;
|
||||
}
|
||||
|
||||
static int tap_cas_fill_wave( int16_t *buffer, int length, const uint8_t *bytes )
|
||||
static int tap_cas_fill_wave( int16_t *buffer, int length, const uint8_t *bytes, int bytes_length )
|
||||
{
|
||||
int16_t *p = buffer;
|
||||
int size = 0;
|
||||
|
||||
//while (length > 0)
|
||||
while (size < length)
|
||||
while (bytes_length > 2)
|
||||
{
|
||||
int data_size = get_u16le(&bytes[0]);
|
||||
int pilot_length = (bytes[2] == 0x00) ? 8063 : 3223;
|
||||
LOG_FORMATS("tap_cas_fill_wave: Handling TAP block containing 0x%X bytes\n", data_size);
|
||||
/*
|
||||
length -= data_size;
|
||||
if (length < 0)
|
||||
bytes_length -= 2;
|
||||
if (bytes_length < data_size)
|
||||
{
|
||||
data_size += length; // Take as much as we can.
|
||||
data_size = bytes_length; // Take as much as we can.
|
||||
}
|
||||
*/
|
||||
bytes_length -= data_size;
|
||||
bytes += 2;
|
||||
size += tzx_cas_handle_block(&p, bytes, 1000, data_size, 2168, pilot_length, 667, 735, 855, 1710, 8);
|
||||
bytes += data_size;
|
||||
@ -855,35 +854,36 @@ static int tap_cas_fill_wave( int16_t *buffer, int length, const uint8_t *bytes
|
||||
|
||||
static const cassette_image::LegacyWaveFiller tzx_legacy_fill_wave =
|
||||
{
|
||||
tzx_cas_fill_wave, /* fill_wave */
|
||||
-1, /* chunk_size */
|
||||
0, /* chunk_samples */
|
||||
tzx_cas_to_wav_size, /* chunk_sample_calc */
|
||||
TZX_WAV_FREQUENCY, /* sample_frequency */
|
||||
0, /* header_samples */
|
||||
0 /* trailer_samples */
|
||||
tzx_cas_fill_wave, // fill_wave
|
||||
-1, // chunk_size
|
||||
0, // chunk_samples
|
||||
tzx_cas_to_wav_size, // chunk_sample_calc
|
||||
TZX_WAV_FREQUENCY, // sample_frequency
|
||||
0, // header_samples
|
||||
0, // trailer_samples
|
||||
};
|
||||
|
||||
static const cassette_image::LegacyWaveFiller tap_legacy_fill_wave =
|
||||
{
|
||||
tap_cas_fill_wave, /* fill_wave */
|
||||
-1, /* chunk_size */
|
||||
0, /* chunk_samples */
|
||||
tap_cas_to_wav_size, /* chunk_sample_calc */
|
||||
TZX_WAV_FREQUENCY, /* sample_frequency */
|
||||
0, /* header_samples */
|
||||
0 /* trailer_samples */
|
||||
nullptr, // fill_wave
|
||||
-1, // chunk_size
|
||||
0, // chunk_samples
|
||||
tap_cas_to_wav_size, // chunk_sample_calc
|
||||
TZX_WAV_FREQUENCY, // sample_frequency
|
||||
0, // header_samples
|
||||
0, // trailer_samples
|
||||
tap_cas_fill_wave // fill_wave_ext
|
||||
};
|
||||
|
||||
static const cassette_image::LegacyWaveFiller cdt_legacy_fill_wave =
|
||||
{
|
||||
cdt_cas_fill_wave, /* fill_wave */
|
||||
-1, /* chunk_size */
|
||||
0, /* chunk_samples */
|
||||
tzx_cas_to_wav_size, /* chunk_sample_calc */
|
||||
TZX_WAV_FREQUENCY, /* sample_frequency */
|
||||
0, /* header_samples */
|
||||
0 /* trailer_samples */
|
||||
cdt_cas_fill_wave, // fill_wave
|
||||
-1, // chunk_size
|
||||
0, // chunk_samples
|
||||
tzx_cas_to_wav_size, // chunk_sample_calc
|
||||
TZX_WAV_FREQUENCY, // sample_frequency
|
||||
0, // header_samples
|
||||
0 // trailer_samples
|
||||
};
|
||||
|
||||
static cassette_image::error tzx_cassette_identify( cassette_image *cassette, cassette_image::Options *opts )
|
||||
|
Loading…
Reference in New Issue
Block a user