diff --git a/Frameworks/midi_processing/midi_processing/midi_processor.h b/Frameworks/midi_processing/midi_processing/midi_processor.h index 20c289901..fac8b94f4 100644 --- a/Frameworks/midi_processing/midi_processing/midi_processor.h +++ b/Frameworks/midi_processing/midi_processing/midi_processor.h @@ -24,8 +24,8 @@ class midi_processor static const uint8_t lds_default_tempo[5]; - static int decode_delta( std::vector::const_iterator & it ); - static unsigned decode_hmp_delta( std::vector::const_iterator & it ); + static int decode_delta( std::vector::const_iterator & it, std::vector::const_iterator end ); + static unsigned decode_hmp_delta( std::vector::const_iterator & it, std::vector::const_iterator end ); static unsigned decode_xmi_delta( std::vector::const_iterator & it, std::vector::const_iterator end ); static bool is_standard_midi( std::vector const& p_file ); diff --git a/Frameworks/midi_processing/midi_processing/midi_processor_helpers.cpp b/Frameworks/midi_processing/midi_processing/midi_processor_helpers.cpp index 0fec3bee5..9175555b8 100644 --- a/Frameworks/midi_processing/midi_processing/midi_processor_helpers.cpp +++ b/Frameworks/midi_processing/midi_processing/midi_processor_helpers.cpp @@ -4,12 +4,13 @@ const uint8_t midi_processor::end_of_track[2] = {0xFF, 0x2F}; const uint8_t midi_processor::loop_start[11] = {0xFF, 0x06, 'l', 'o', 'o', 'p', 'S', 't', 'a', 'r', 't'}; const uint8_t midi_processor::loop_end[9] = {0xFF, 0x06, 'l', 'o', 'o', 'p', 'E', 'n', 'd'}; -int midi_processor::decode_delta( std::vector::const_iterator & it ) +int midi_processor::decode_delta( std::vector::const_iterator & it, std::vector::const_iterator end ) { int delta = 0; unsigned char byte; do { + if ( it == end ) return 0; byte = *it++; delta = ( delta << 7 ) + ( byte & 0x7F ); } diff --git a/Frameworks/midi_processing/midi_processing/midi_processor_hmi.cpp b/Frameworks/midi_processing/midi_processing/midi_processor_hmi.cpp index 9581f016b..56e70bfce 100644 --- a/Frameworks/midi_processing/midi_processing/midi_processor_hmi.cpp +++ b/Frameworks/midi_processing/midi_processing/midi_processor_hmi.cpp @@ -18,6 +18,9 @@ bool midi_processor::process_hmi( std::vector const& p_file, midi_conta uint32_t track_count = it[ 0 ] | ( it[ 1 ] << 8 ) | ( it[ 2 ] << 16 ) | ( it[ 3 ] << 24 ); uint32_t track_table_offset = it[ 4 ] | ( it[ 5 ] << 8 ) | ( it[ 6 ] << 16 ) | ( it[ 7 ] << 24 ); + if ( track_table_offset >= p_file.size() || track_table_offset + track_count * 4 > p_file.size() ) + return false; + it = p_file.begin() + track_table_offset; std::vector track_offsets; @@ -50,6 +53,9 @@ bool midi_processor::process_hmi( std::vector const& p_file, midi_conta { track_length = p_file.size() - track_offset; } + if ( track_offset >= p_file.size() || track_offset + track_length > p_file.size() ) + return false; + std::vector::const_iterator track_body = p_file.begin() + track_offset; std::vector::const_iterator track_end = track_body + track_length; @@ -93,9 +99,9 @@ bool midi_processor::process_hmi( std::vector const& p_file, midi_conta buffer.resize( 3 ); - while ( it < track_end ) + while ( it != track_end ) { - int delta = decode_delta( it ); + int delta = decode_delta( it, track_end ); if ( delta > 0xFFFF || delta < 0 ) { current_timestamp = last_event_timestamp; @@ -110,13 +116,16 @@ bool midi_processor::process_hmi( std::vector const& p_file, midi_conta } } + if ( it == track_end ) return false; buffer[ 0 ] = *it++; if ( buffer[ 0 ] == 0xFF ) { last_event_code = 0xFF; + if ( it == track_end ) return false; buffer[ 1 ] = *it++; - int meta_count = decode_delta( it ); + int meta_count = decode_delta( it, track_end ); if ( meta_count < 0 ) return false; /*throw exception_io_data( "Invalid HMI meta message" );*/ + if ( track_end - it < meta_count ) return false; buffer.resize( meta_count + 2 ); std::copy( it, it + meta_count, buffer.begin() + 2 ); it += meta_count; @@ -130,8 +139,9 @@ bool midi_processor::process_hmi( std::vector const& p_file, midi_conta else if ( buffer[ 0 ] == 0xF0 ) { last_event_code = 0xFF; - int system_exclusive_count = decode_delta( it ); + int system_exclusive_count = decode_delta( it, track_end ); if ( system_exclusive_count < 0 ) return false; /*throw exception_io_data( "Invalid HMI System Exclusive message" );*/ + if ( track_end - it < system_exclusive_count ) return false; buffer.resize( system_exclusive_count + 1 ); std::copy( it, it + system_exclusive_count, buffer.begin() + 1 ); it += system_exclusive_count; @@ -140,28 +150,35 @@ bool midi_processor::process_hmi( std::vector const& p_file, midi_conta else if ( buffer[ 0 ] == 0xFE ) { last_event_code = 0xFF; + if ( it == track_end ) return false; buffer[ 1 ] = *it++; if ( buffer[ 1 ] == 0x10 ) { + if ( track_end - it < 3 ) return false; it += 2; buffer[ 2 ] = *it++; + if ( track_end - it < buffer[ 2 ] + 4 ) return false; it += buffer[ 2 ] + 4; } else if ( buffer[ 1 ] == 0x12 ) { + if ( track_end - it < 2 ) return false; it += 2; } else if ( buffer[ 1 ] == 0x13 ) { + if ( track_end - it < 10 ) return false; it += 10; } else if ( buffer[ 1 ] == 0x14 ) { + if ( track_end - it < 2 ) return false; it += 2; p_out.add_track_event( 0, midi_event( current_timestamp, midi_event::extended, 0, loop_start, _countof( loop_start ) ) ); } else if ( buffer[ 1 ] == 0x15 ) { + if ( track_end - it < 6 ) return false; it += 6; p_out.add_track_event( 0, midi_event( current_timestamp, midi_event::extended, 0, loop_end, _countof( loop_end ) ) ); } @@ -172,6 +189,7 @@ bool midi_processor::process_hmi( std::vector const& p_file, midi_conta unsigned bytes_read = 1; if ( buffer[ 0 ] >= 0x80 ) { + if ( it == track_end ) return false; buffer[ 1 ] = *it++; last_event_code = buffer[ 0 ]; } @@ -185,6 +203,7 @@ bool midi_processor::process_hmi( std::vector const& p_file, midi_conta unsigned channel = buffer[ 0 ] & 0x0F; if ( type != midi_event::program_change && type != midi_event::channel_aftertouch ) { + if ( it == track_end ) return false; buffer[ 2 ] = *it++; bytes_read = 2; } @@ -192,7 +211,7 @@ bool midi_processor::process_hmi( std::vector const& p_file, midi_conta if ( type == midi_event::note_on ) { buffer[ 2 ] = 0x00; - int note_length = decode_delta( it ); + int note_length = decode_delta( it, track_end ); if ( note_length < 0 ) return false; /*throw exception_io_data( "Invalid HMI note message" );*/ unsigned note_end_timestamp = current_timestamp + note_length; if ( note_end_timestamp > last_event_timestamp ) last_event_timestamp = note_end_timestamp; diff --git a/Frameworks/midi_processing/midi_processing/midi_processor_hmp.cpp b/Frameworks/midi_processing/midi_processing/midi_processor_hmp.cpp index 6e0ec068c..b634b0d0d 100644 --- a/Frameworks/midi_processing/midi_processing/midi_processor_hmp.cpp +++ b/Frameworks/midi_processing/midi_processing/midi_processor_hmp.cpp @@ -11,13 +11,14 @@ bool midi_processor::is_hmp( std::vector const& p_file ) return true; } -unsigned midi_processor::decode_hmp_delta( std::vector::const_iterator & it ) +unsigned midi_processor::decode_hmp_delta( std::vector::const_iterator & it, std::vector::const_iterator end ) { unsigned delta = 0; unsigned shift = 0; unsigned char byte; do { + if ( it == end ) return 0; byte = *it++; delta = delta + ( ( byte & 0x7F ) << shift ); shift += 7; @@ -33,12 +34,20 @@ bool midi_processor::process_hmp( std::vector const& p_file, midi_conta uint8_t track_count_8; uint16_t dtx = 0xC0; - std::vector::const_iterator it = p_file.begin() + ( is_funky ? 0x1A : 0x30 ); + uint32_t offset = is_funky ? 0x1A : 0x30; + + if ( offset >= p_file.size() ) + return false; + + std::vector::const_iterator it = p_file.begin() + offset; + std::vector::const_iterator end = p_file.end(); track_count_8 = *it; if ( is_funky ) { + if ( p_file.size() <= 0x4D ) + return false; dtx = ( p_file[ 0x4C ] << 16 ) | p_file[ 0x4D ]; } @@ -53,15 +62,17 @@ bool midi_processor::process_hmp( std::vector const& p_file, midi_conta uint8_t buffer[ 4 ]; + if ( it == end ) return false; buffer[ 0 ] = *it++; - while ( it < p_file.end() ) + while ( it != end ) { if ( buffer[ 0 ] != 0xFF ) { buffer[ 0 ] = *it++; continue; } + if ( it == end ) break; buffer[ 1 ] = *it++; if ( buffer[ 1 ] != 0x2F ) { @@ -71,7 +82,9 @@ bool midi_processor::process_hmp( std::vector const& p_file, midi_conta break; } - it += ( is_funky ? 3 : 5 ); + offset = is_funky ? 3 : 5; + if ( (unsigned long)(end - it) < offset ) return false; + it += offset; unsigned track_count = track_count_8; @@ -82,18 +95,20 @@ bool midi_processor::process_hmp( std::vector const& p_file, midi_conta if ( is_funky ) { + if ( end - it < 4 ) break; track_size_16 = it[ 0 ] | ( it[ 1 ] << 8 ); it += 2; track_size_32 = track_size_16 - 4; - if ( p_file.end() - it < track_size_32 + 2 ) break; + if ( (unsigned long)(end - it) < track_size_32 + 2 ) break; it += 2; } else { + if ( end - it < 8 ) break; track_size_32 = it[ 0 ] | ( it[ 1 ] << 8 ) | ( it[ 2 ] << 16 ) | ( it[ 3 ] << 24 ); it += 4; track_size_32 -= 12; - if ( p_file.end() - it < track_size_32 + 8 ) break; + if ( (unsigned long)(end - it) < track_size_32 + 8 ) break; it += 4; } @@ -106,16 +121,19 @@ bool midi_processor::process_hmp( std::vector const& p_file, midi_conta std::vector::const_iterator track_end = it + track_size_32; - while ( it < track_end ) + while ( it != track_end ) { - unsigned delta = decode_hmp_delta( it ); + unsigned delta = decode_hmp_delta( it, track_end ); current_timestamp += delta; + if ( it == track_end ) return false; buffer[ 0 ] = *it++; if ( buffer[ 0 ] == 0xFF ) { + if ( it == track_end ) return false; buffer[ 1 ] = *it++; - int meta_count = decode_delta( it ); + int meta_count = decode_delta( it, track_end ); if ( meta_count < 0 ) return false; /*throw exception_io_data( "Invalid HMP meta message" );*/ + if ( track_end - it < meta_count ) return false; buffer.resize( meta_count + 2 ); std::copy( it, it + meta_count, buffer.begin() + 2 ); it += meta_count; @@ -131,6 +149,7 @@ bool midi_processor::process_hmp( std::vector const& p_file, midi_conta case 0xD0: bytes_read = 1; } + if ( (unsigned long)(track_end - it) < bytes_read ) return false; std::copy( it, it + bytes_read, buffer.begin() + 1 ); it += bytes_read; track.add_event( midi_event( current_timestamp, (midi_event::event_type)( ( buffer[ 0 ] >> 4 ) - 8 ), buffer[ 0 ] & 0x0F, &buffer[1], bytes_read ) ); @@ -138,7 +157,9 @@ bool midi_processor::process_hmp( std::vector const& p_file, midi_conta else return false; /*throw exception_io_data( "Unexpected status code in HMP track" );*/ } - it = track_end + ( is_funky ? 0 : 4 ); + offset = is_funky ? 0 : 4; + if ( end - it < (signed long)offset ) return false; + it = track_end + offset; p_out.add_track( track ); } diff --git a/Frameworks/midi_processing/midi_processing/midi_processor_lds.cpp b/Frameworks/midi_processing/midi_processing/midi_processor_lds.cpp index 050ab5f2b..4583057a3 100644 --- a/Frameworks/midi_processing/midi_processing/midi_processor_lds.cpp +++ b/Frameworks/midi_processing/midi_processing/midi_processor_lds.cpp @@ -334,20 +334,26 @@ bool midi_processor::process_lds( std::vector const& p_file, midi_conta std::vector patterns; std::vector::const_iterator it = p_file.begin(); + std::vector::const_iterator end = p_file.end(); + if ( end == it ) return false; mode = *it++; if ( mode > 2 ) return false; /*throw exception_io_data( "Invalid LDS mode" );*/ /*speed = it[ 0 ] | ( it[ 1 ] << 8 );*/ + if ( end - it < 4 ) return false; tempo = it[ 2 ]; pattern_length = it[ 3 ]; it += 4; + if ( end - it < 9 ) return false; for ( unsigned i = 0; i < 9; ++i ) channel_delay[ i ] = *it++; /*register_bd = *it++;*/ it++; + if ( end - it < 2 ) return false; patch_count = it[ 0 ] | ( it[ 1 ] << 8 ); it += 2; patches.resize( patch_count ); + if ( end - it < 46 * patch_count ) return false; for ( unsigned i = 0; i < patch_count; ++i ) { sound_patch & patch = patches[ i ]; @@ -396,9 +402,11 @@ bool midi_processor::process_lds( std::vector const& p_file, midi_conta #endif } + if ( end - it < 2 ) return false; position_count = it[ 0 ] | ( it[ 1 ] << 8 ); it += 2; positions.resize( 9 * position_count ); + if ( end - it < 3 * position_count ) return false; for ( unsigned i = 0; i < position_count; ++i ) { for ( unsigned j = 0; j < 9; ++j ) @@ -412,9 +420,10 @@ bool midi_processor::process_lds( std::vector const& p_file, midi_conta } } + if ( end - it < 2 ) return false; it += 2; - pattern_count = ( p_file.end() - it ) / 2; + pattern_count = ( end - it ) / 2; patterns.resize( pattern_count ); for ( unsigned i = 0; i < pattern_count; ++i ) { @@ -550,7 +559,7 @@ bool midi_processor::process_lds( std::vector const& p_file, midi_conta } } } - else if(((allvolume + (0x100 - fadeonoff)) & 0xff) <= mainvolume) + else if((unsigned)((allvolume + (0x100 - fadeonoff)) & 0xff) <= mainvolume) { allvolume += 0x100 - fadeonoff; } @@ -596,7 +605,7 @@ bool midi_processor::process_lds( std::vector const& p_file, midi_conta unsigned short patnum = positions[posplay * 9 + chan].pattern_number; unsigned char transpose = positions[posplay * 9 + chan].transpose; - if ( patnum + c->packpos >= patterns.size() ) return false; /*throw exception_io_data( "Invalid LDS pattern number" );*/ + if ( (unsigned long)(patnum + c->packpos) >= patterns.size() ) return false; /*throw exception_io_data( "Invalid LDS pattern number" );*/ unsigned comword = patterns[patnum + c->packpos]; unsigned comhi = comword >> 8; diff --git a/Frameworks/midi_processing/midi_processing/midi_processor_mids.cpp b/Frameworks/midi_processing/midi_processing/midi_processor_mids.cpp index 3807a3f4b..88ed83d13 100644 --- a/Frameworks/midi_processing/midi_processing/midi_processor_mids.cpp +++ b/Frameworks/midi_processing/midi_processing/midi_processor_mids.cpp @@ -13,10 +13,13 @@ bool midi_processor::is_mids( std::vector const& p_file ) bool midi_processor::process_mids( std::vector const& p_file, midi_container & p_out ) { + if ( p_file.size() < 20 ) return false; std::vector::const_iterator it = p_file.begin() + 16; + std::vector::const_iterator end = p_file.end(); uint32_t fmt_size = it[ 0 ] | ( it[ 1 ] << 8 ) | ( it[ 2 ] << 16 ) | ( it[ 3 ] << 24 ); it += 4; + if ( (unsigned long)(end - it) < fmt_size ) return false; uint32_t time_format = 1; /*uint32_t max_buffer = 0;*/ @@ -42,10 +45,12 @@ bool midi_processor::process_mids( std::vector const& p_file, midi_cont } it += fmt_size; + if ( it == end ) return false; if ( fmt_size & 1 ) ++it; p_out.initialize( 0, time_format ); + if ( end - it < 4 ) return false; if ( it[ 0 ] != 'd' || it[ 1 ] != 'a' || it[ 2 ] != 't' || it[ 3 ] != 'a' ) return false; /*throw exception_io_data( "MIDS missing RIFF data chunk" );*/ it += 4; @@ -56,11 +61,13 @@ bool midi_processor::process_mids( std::vector const& p_file, midi_cont p_out.add_track( track ); } + if ( end - it < 4 ) return false; uint32_t data_size = it[ 0 ] | ( it[ 1 ] << 8 ) | ( it[ 2 ] << 16 ) | ( it[ 3 ] << 24 ); it += 4; std::vector::const_iterator body_end = it + data_size; + if ( body_end - it < 4 ) return false; uint32_t segment_count = it[ 0 ] | ( it[ 1 ] << 8 ) | ( it[ 2 ] << 16 ) | ( it[ 3 ] << 24 ); it += 4; @@ -72,17 +79,24 @@ bool midi_processor::process_mids( std::vector const& p_file, midi_cont for ( unsigned i = 0; i < segment_count; ++i ) { + if ( end - it < 12 ) return false; it += 4; uint32_t segment_size = it[ 0 ] | ( it[ 1 ] << 8 ) | ( it[ 2 ] << 16 ) | ( it[ 3 ] << 24 ); it += 4; std::vector::const_iterator segment_end = it + segment_size; - while ( it < segment_end && it < body_end ) + while ( it != segment_end && it != body_end ) { + if ( segment_end - it < 4 ) return false; uint32_t delta = it[ 0 ] | ( it[ 1 ] << 8 ) | ( it[ 2 ] << 16 ) | ( it[ 3 ] << 24 ); it += 4; uint32_t event; current_timestamp += delta; - if ( !is_eight_byte ) it += 4; + if ( !is_eight_byte ) + { + if ( segment_end - it < 4 ) return false; + it += 4; + } + if ( segment_end - it < 4 ) return false; event = it[ 0 ] | ( it[ 1 ] << 8 ) | ( it[ 2 ] << 16 ) | ( it[ 3 ] << 24 ); it += 4; if ( event >> 24 == 0x01 ) diff --git a/Frameworks/midi_processing/midi_processing/midi_processor_mus.cpp b/Frameworks/midi_processing/midi_processing/midi_processor_mus.cpp index d65385a20..9c25b0aa6 100644 --- a/Frameworks/midi_processing/midi_processing/midi_processor_mus.cpp +++ b/Frameworks/midi_processing/midi_processing/midi_processor_mus.cpp @@ -35,11 +35,14 @@ bool midi_processor::process_mus( std::vector const& p_file, midi_conta uint8_t velocity_levels[ 16 ] = { 0 }; + if ( offset >= p_file.size() || offset + length > p_file.size() ) + return false; + std::vector::const_iterator it = p_file.begin() + offset, end = p_file.begin() + offset + length; uint8_t buffer[ 4 ]; - while ( it < end ) + while ( it != end ) { buffer[ 0 ] = *it++; if ( buffer[ 0 ] == 0x60 ) break; @@ -56,6 +59,7 @@ bool midi_processor::process_mus( std::vector const& p_file, midi_conta { case 0x00: type = midi_event::note_on; + if ( it == end ) return false; buffer[ 1 ] = *it++; buffer[ 2 ] = 0; bytes_to_write = 2; @@ -63,9 +67,11 @@ bool midi_processor::process_mus( std::vector const& p_file, midi_conta case 0x10: type = midi_event::note_on; + if ( it == end ) return false; buffer[ 1 ] = *it++; if ( buffer[ 1 ] & 0x80 ) { + if ( it == end ) return false; buffer[ 2 ] = *it++; velocity_levels[ channel ] = buffer[ 2 ]; buffer[ 1 ] &= 0x7F; @@ -79,6 +85,7 @@ bool midi_processor::process_mus( std::vector const& p_file, midi_conta case 0x20: type = midi_event::pitch_wheel; + if ( it == end ) return false; buffer[ 1 ] = *it++; buffer[ 2 ] = buffer[ 1 ] >> 1; buffer[ 1 ] <<= 7; @@ -87,6 +94,7 @@ bool midi_processor::process_mus( std::vector const& p_file, midi_conta case 0x30: type = midi_event::control_change; + if ( it == end ) return false; buffer[ 1 ] = *it++; if ( buffer[ 1 ] >= 10 && buffer[ 1 ] <= 14 ) { @@ -98,6 +106,7 @@ bool midi_processor::process_mus( std::vector const& p_file, midi_conta break; case 0x40: + if ( it == end ) return false; buffer[ 1 ] = *it++; if ( buffer[ 1 ] ) { @@ -105,6 +114,7 @@ bool midi_processor::process_mus( std::vector const& p_file, midi_conta { type = midi_event::control_change; buffer[ 1 ] = mus_controllers[ buffer[ 1 ] ]; + if ( it == end ) return false; buffer[ 2 ] = *it++; bytes_to_write = 2; } @@ -113,6 +123,7 @@ bool midi_processor::process_mus( std::vector const& p_file, midi_conta else { type = midi_event::program_change; + if ( it == end ) return false; buffer[ 1 ] = *it++; bytes_to_write = 1; } @@ -126,7 +137,7 @@ bool midi_processor::process_mus( std::vector const& p_file, midi_conta if ( buffer[ 0 ] & 0x80 ) { - int delta = decode_delta( it ); + int delta = decode_delta( it, end ); if ( delta < 0 ) return false; /*throw exception_io_data( "Invalid MUS delta" );*/ current_timestamp += delta; } diff --git a/Frameworks/midi_processing/midi_processing/midi_processor_riff_midi.cpp b/Frameworks/midi_processing/midi_processing/midi_processor_riff_midi.cpp index 8ec05e56e..af19255d9 100644 --- a/Frameworks/midi_processing/midi_processing/midi_processor_riff_midi.cpp +++ b/Frameworks/midi_processing/midi_processing/midi_processor_riff_midi.cpp @@ -41,10 +41,6 @@ static const char * riff_tag_mappings[][2] = { "ITCH", "technician" } }; -#define CF_TEXT 1 -#define CF_TIFF 6 -#define CF_DIB 8 - bool midi_processor::process_riff_midi( std::vector const& p_file, midi_container & p_out ) { uint32_t file_size = p_file[ 4 ] | ( p_file[ 5 ] << 8 ) | ( p_file[ 6 ] << 16 ) | ( p_file[ 7 ] << 24 ); @@ -60,9 +56,11 @@ bool midi_processor::process_riff_midi( std::vector const& p_file, midi std::vector extra_buffer; - while ( it < body_end ) + while ( it != body_end ) { + if ( body_end - it < 8 ) return false; uint32_t chunk_size = it[ 4 ] | ( it[ 5 ] << 8 ) | ( it[ 6 ] << 16 ) | ( it[ 7 ] << 24 ); + if ( (unsigned long)(body_end - it) < chunk_size ) return false; if ( it[ 0 ] == 'd' && it[ 1 ] == 'a' && it[ 2 ] == 't' && it[ 3 ] == 'a' ) { if ( !found_data ) @@ -74,52 +72,19 @@ bool midi_processor::process_riff_midi( std::vector const& p_file, midi } else return false; /*throw exception_io_data( "Multiple RIFF data chunks found" );*/ it += 8 + chunk_size; - if ( chunk_size & 1 && it < body_end ) ++it; + if ( chunk_size & 1 && it != body_end ) ++it; } else if ( it[ 0 ] == 'D' && it[ 1 ] == 'I' && it[ 2 ] == 'S' && it[ 3 ] == 'P' ) { uint32_t type = it[ 8 ] | ( it[ 9 ] << 8 ) | ( it[ 10 ] << 16 ) | ( it[ 11 ] << 24 ); - if ( type == CF_TEXT ) + if ( type == 1 ) { extra_buffer.resize( chunk_size - 4 ); std::copy( it + 12, it + 8 + chunk_size, extra_buffer.begin() ); meta_data.add_item( midi_meta_data_item( 0, "display_name", (const char *) &extra_buffer[0] ) ); } - else if ( type == CF_TIFF ) - { - meta_data.assign_bitmap( it + 12, it + 8 + chunk_size ); - } - else if ( type == CF_DIB ) - { - if ( chunk_size >= 8 ) - { - uint32_t dib_header_size = it[ 12 ] | ( it[13] << 8 ) | ( it[14] << 16 ) | ( it[15] << 24 ); - if ( chunk_size >= 4 + dib_header_size ) - { - uint32_t dib_image_offset = 14 + dib_header_size; - uint32_t dib_size = chunk_size + 10; - extra_buffer.resize( dib_size ); - extra_buffer[ 0 ] = 'B'; - extra_buffer[ 1 ] = 'M'; - extra_buffer[ 2 ] = dib_size; - extra_buffer[ 3 ] = dib_size >> 8; - extra_buffer[ 4 ] = dib_size >> 16; - extra_buffer[ 5 ] = dib_size >> 24; - extra_buffer[ 6 ] = 0; - extra_buffer[ 7 ] = 0; - extra_buffer[ 8 ] = 0; - extra_buffer[ 9 ] = 0; - extra_buffer[ 10 ] = dib_image_offset; - extra_buffer[ 11 ] = dib_image_offset >> 8; - extra_buffer[ 12 ] = dib_image_offset >> 16; - extra_buffer[ 13 ] = dib_image_offset >> 24; - std::copy(it + 12, it + 8 + chunk_size, extra_buffer.begin() + 14); - meta_data.assign_bitmap(extra_buffer.begin(), extra_buffer.end()); - } - } - } it += 8 + chunk_size; - if ( chunk_size & 1 && it < body_end ) ++it; + if ( chunk_size & 1 && it != body_end ) ++it; } else if ( it[ 0 ] == 'L' && it[ 1 ] == 'I' && it[ 2 ] == 'S' && it[ 3 ] == 'T' ) { @@ -128,10 +93,13 @@ bool midi_processor::process_riff_midi( std::vector const& p_file, midi { if ( !found_info ) { + if ( chunk_end - it < 12 ) return false; it += 12; - while ( it < chunk_end ) + while ( it != chunk_end ) { + if ( chunk_end - it < 4 ) return false; uint32_t field_size = it[ 4 ] | ( it[ 5 ] << 8 ) | ( it[ 6 ] << 16 ) | ( it[ 7 ] << 24 ); + if ( (unsigned long)(chunk_end - it) < 8 + field_size ) return false; std::string field; field.assign( it, it + 4 ); for ( unsigned i = 0; i < _countof(riff_tag_mappings); ++i ) @@ -146,7 +114,7 @@ bool midi_processor::process_riff_midi( std::vector const& p_file, midi std::copy( it + 8, it + 8 + field_size, extra_buffer.begin() ); it += 8 + field_size; meta_data.add_item( midi_meta_data_item( 0, field.c_str(), ( const char * ) &extra_buffer[0] ) ); - if ( field_size & 1 && it < chunk_end ) ++it; + if ( field_size & 1 && it != chunk_end ) ++it; } found_info = true; } @@ -154,12 +122,12 @@ bool midi_processor::process_riff_midi( std::vector const& p_file, midi } else return false; /* unknown LIST chunk */ it = chunk_end; - if ( chunk_size & 1 && it < body_end ) ++it; + if ( chunk_size & 1 && it != body_end ) ++it; } else { it += chunk_size; - if ( chunk_size & 1 && it < body_end ) ++it; + if ( chunk_size & 1 && it != body_end ) ++it; } if ( found_data && found_info ) break; diff --git a/Frameworks/midi_processing/midi_processing/midi_processor_standard_midi.cpp b/Frameworks/midi_processing/midi_processing/midi_processor_standard_midi.cpp index 084da5066..48e94788d 100644 --- a/Frameworks/midi_processing/midi_processing/midi_processor_standard_midi.cpp +++ b/Frameworks/midi_processing/midi_processing/midi_processor_standard_midi.cpp @@ -20,9 +20,9 @@ bool midi_processor::process_standard_midi_track( std::vector::const_it for (;;) { - if ( !needs_end_marker && it >= end ) break; - int delta = decode_delta( it ); - if ( !needs_end_marker && it >= end ) break; + if ( !needs_end_marker && it == end ) break; + int delta = decode_delta( it, end ); + if ( !needs_end_marker && it == end ) break; if ( delta < 0 ) { @@ -45,6 +45,7 @@ bool midi_processor::process_standard_midi_track( std::vector::const_it if ( !needs_end_marker && ( event_code & 0xF0 ) == 0xE0 ) continue; if ( data_bytes_read < 1 ) { + if ( it == end ) return false; buffer[ 0 ] = *it++; ++data_bytes_read; } @@ -54,6 +55,7 @@ bool midi_processor::process_standard_midi_track( std::vector::const_it case 0xD0: break; default: + if ( it == end ) return false; buffer[ data_bytes_read ] = *it++; ++data_bytes_read; } @@ -61,8 +63,9 @@ bool midi_processor::process_standard_midi_track( std::vector::const_it } else if ( event_code == 0xF0 ) { - int data_count = decode_delta( it ); + int data_count = decode_delta( it, end ); if ( data_count < 0 ) return false; /*throw exception_io_data( "Invalid System Exclusive message" );*/ + if ( end - it > data_count ) return false; buffer.resize( data_count + 1 ); buffer[ 0 ] = 0xF0; std::copy( it, it + data_count, buffer.begin() + 1 ); @@ -71,9 +74,11 @@ bool midi_processor::process_standard_midi_track( std::vector::const_it } else if ( event_code == 0xFF ) { + if ( it == end ) return false; unsigned char meta_type = *it++; - int data_count = decode_delta( it ); + int data_count = decode_delta( it, end ); if ( data_count < 0 ) return false; /*throw exception_io_data( "Invalid meta message" );*/ + if ( end - it < data_count ) return false; buffer.resize( data_count + 2 ); buffer[ 0 ] = 0xFF; buffer[ 1 ] = meta_type; @@ -112,6 +117,7 @@ bool midi_processor::process_standard_midi( std::vector const& p_file, if ( p_file[ 4 ] != 0 || p_file[ 5 ] != 0 || p_file[ 6 ] != 0 || p_file[ 7 ] != 6 ) return false; /*throw exception_io_data("Bad MIDI header size");*/ std::vector::const_iterator it = p_file.begin() + 8; + std::vector::const_iterator end = p_file.end(); uint16_t form = ( it[0] << 8 ) | it[1]; if ( form > 2 ) return false; @@ -127,9 +133,11 @@ bool midi_processor::process_standard_midi( std::vector const& p_file, for ( std::size_t i = 0; i < track_count; ++i ) { + if ( end - it < 8 ) return false; if ( it[0] != 'M' || it[1] != 'T' || it[2] != 'r' || it[3] != 'k' ) return false; uint32_t track_size = ( it[4] << 24 ) | ( it[5] << 16 ) | ( it[6] << 8 ) | it[7]; + if ( (unsigned long)(end - it) < track_size ) return false; it += 8; diff --git a/Frameworks/midi_processing/midi_processing/midi_processor_xmi.cpp b/Frameworks/midi_processing/midi_processing/midi_processor_xmi.cpp index 6cb4c7daa..cff7d3403 100644 --- a/Frameworks/midi_processing/midi_processing/midi_processor_xmi.cpp +++ b/Frameworks/midi_processing/midi_processing/midi_processor_xmi.cpp @@ -16,15 +16,17 @@ const uint8_t midi_processor::xmi_default_tempo[5] = {0xFF, 0x51, 0x07, 0xA1, 0x unsigned midi_processor::decode_xmi_delta( std::vector::const_iterator & it, std::vector::const_iterator end ) { unsigned delta = 0; + if ( it == end ) return 0; uint8_t byte = *it++; if ( !( byte & 0x80 ) ) { do { delta += byte; + if ( it == end ) break; byte = *it++; } - while ( !( byte & 0x80 ) && it < end ); + while ( !( byte & 0x80 ) && it != end ); } --it; return delta; @@ -101,9 +103,11 @@ struct iff_stream static bool read_iff_chunk( std::vector::const_iterator & it, std::vector::const_iterator end, iff_chunk & p_out, bool first_chunk ) { + if ( end - it < 8 ) return false; std::copy( it, it + 4, p_out.m_id ); it += 4; uint32_t chunk_size = ( it[ 0 ] << 24 ) | ( it[ 1 ] << 16 ) | ( it[ 2 ] << 8 ) | it[ 3 ]; + if ( (unsigned long)(end - it) < chunk_size ) return false; it += 4; bool is_cat_chunk = !memcmp( p_out.m_id, "CAT ", 4 ); bool is_form_chunk = !memcmp( p_out.m_id, "FORM", 4 ); @@ -111,6 +115,7 @@ static bool read_iff_chunk( std::vector::const_iterator & it, std::vect if ( chunk_size > chunk_size_limit ) chunk_size = (uint32_t) chunk_size_limit; if ( ( first_chunk && is_form_chunk ) || ( !first_chunk && is_cat_chunk ) ) { + if ( end - it < 4 ) return false; std::vector::const_iterator chunk_end = it + chunk_size; std::copy( it, it + 4, p_out.m_type ); it += 4; @@ -121,13 +126,13 @@ static bool read_iff_chunk( std::vector::const_iterator & it, std::vect p_out.m_sub_chunks.push_back( chunk ); } it = chunk_end; - if ( chunk_size & 1 && it < end ) ++it; + if ( chunk_size & 1 && it != end ) ++it; } else if ( !is_form_chunk && !is_cat_chunk ) { p_out.m_data.assign( it, it + chunk_size ); it += chunk_size; - if ( chunk_size & 1 && it < end ) ++it; + if ( chunk_size & 1 && it != end ) ++it; } else { @@ -142,7 +147,7 @@ static bool read_iff_stream( std::vector const& p_file, iff_stream & p_ { std::vector::const_iterator it = p_file.begin(), end = p_file.end(); bool first_chunk = true; - while ( it < end ) + while ( it != end ) { iff_chunk chunk; if ( !read_iff_chunk( it, end, chunk, first_chunk ) ) return false; @@ -189,7 +194,7 @@ bool midi_processor::process_xmi( std::vector const& p_file, midi_conta std::vector::const_iterator it = event_body.begin(), end = event_body.end(); - while ( it < end ) + while ( it != end ) { unsigned delta = decode_xmi_delta( it, end ); current_timestamp += delta; @@ -199,19 +204,22 @@ bool midi_processor::process_xmi( std::vector const& p_file, midi_conta last_event_timestamp = current_timestamp; } + if ( it == end ) return false; buffer[ 0 ] = *it++; if ( buffer[ 0 ] == 0xFF ) { + if ( it == end ) return false; buffer[ 1 ] = *it++; - int meta_count; + long meta_count; if ( buffer[ 1 ] == 0x2F ) { meta_count = 0; } else { - meta_count = decode_delta( it ); + meta_count = decode_delta( it, end ); if ( meta_count < 0 ) return false; /*throw exception_io_data( "Invalid XMI meta message" );*/ + if ( end - it < meta_count ) return false; buffer.resize( meta_count + 2 ); std::copy( it, it + meta_count, buffer.begin() + 2 ); it += meta_count; @@ -235,8 +243,9 @@ bool midi_processor::process_xmi( std::vector const& p_file, midi_conta } else if ( buffer[ 0 ] == 0xF0 ) { - int system_exclusive_count = decode_delta( it ); + long system_exclusive_count = decode_delta( it, end ); if ( system_exclusive_count < 0 ) return false; /*throw exception_io_data( "Invalid XMI System Exclusive message" );*/ + if ( end - it < system_exclusive_count ) return false; buffer.resize( system_exclusive_count + 1 ); std::copy( it, it + system_exclusive_count, buffer.begin() + 1 ); it += system_exclusive_count; @@ -245,11 +254,13 @@ bool midi_processor::process_xmi( std::vector const& p_file, midi_conta else if ( buffer[ 0 ] >= 0x80 && buffer[ 0 ] <= 0xEF ) { unsigned bytes_read = 1; + if ( it == end ) return false; buffer[ 1 ] = *it++; midi_event::event_type type = (midi_event::event_type)( ( buffer[ 0 ] >> 4 ) - 8 ); unsigned channel = buffer[ 0 ] & 0x0F; if ( type != midi_event::program_change && type != midi_event::channel_aftertouch ) { + if ( it == end ) return false; buffer[ 2 ] = *it++; bytes_read = 2; } @@ -257,7 +268,7 @@ bool midi_processor::process_xmi( std::vector const& p_file, midi_conta if ( type == midi_event::note_on ) { buffer[ 2 ] = 0x00; - int note_length = decode_delta( it ); + int note_length = decode_delta( it, end ); if ( note_length < 0 ) return false; /*throw exception_io_data( "Invalid XMI note message" );*/ unsigned note_end_timestamp = current_timestamp + note_length; if ( note_end_timestamp > last_event_timestamp ) last_event_timestamp = note_end_timestamp;