X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fevoral%2Fsrc%2Flibsmf%2Fsmf_load.c;h=1db09a7a458ecda1ca0a3b88084d4f79d0fa1ba9;hb=dd07428c48bb4df60b9d0c6c3cd524279ab4e524;hp=d8168d0e6ada0edfea142a8471b9f14ed824e646;hpb=6fc1f270137a06115a79c6089004174c5cab5ed7;p=ardour.git diff --git a/libs/evoral/src/libsmf/smf_load.c b/libs/evoral/src/libsmf/smf_load.c index d8168d0e6a..1db09a7a45 100644 --- a/libs/evoral/src/libsmf/smf_load.c +++ b/libs/evoral/src/libsmf/smf_load.c @@ -83,7 +83,6 @@ next_chunk(smf_t *smf) if (smf->next_chunk_offset > smf->file_buffer_length) { g_critical("SMF error: malformed chunk; truncated file?"); - return (NULL); } return (chunk); @@ -396,7 +395,10 @@ extract_sysex_event(const unsigned char *buf, const size_t buffer_length, smf_ev status = *buf; - assert(is_sysex_byte(status)); + if (!(is_sysex_byte(status))) { + g_critical("Corrupt sysex status byte in extract_sysex_event()."); + return (-6); + } c++; @@ -439,7 +441,10 @@ extract_escaped_event(const unsigned char *buf, const size_t buffer_length, smf_ status = *buf; - assert(is_escape_byte(status)); + if (!(is_escape_byte(status))) { + g_critical("Corrupt escape status byte in extract_escaped_event()."); + return (-6); + } c++; @@ -565,11 +570,17 @@ parse_next_event(smf_track_t *track) assert(track->next_event_offset > 0); buffer_length = track->file_buffer_length - track->next_event_offset; - assert(buffer_length > 0); - + /* if there was no meta-EOT event, buffer_length can be zero. This is + an error in the SMF file, but it shouldn't be treated as fatal. + */ + if (buffer_length == 0) { + g_warning ("SMF warning: expected EOT at end of track, but none found"); + goto error; + } /* First, extract time offset from previous event. */ - if (smf_extract_vlq(c, buffer_length, &etime, &len)) + if (smf_extract_vlq(c, buffer_length, &etime, &len)) { goto error; + } c += len; buffer_length -= len; @@ -578,8 +589,9 @@ parse_next_event(smf_track_t *track) goto error; /* Now, extract the actual event. */ - if (extract_midi_event(c, buffer_length, event, &len, track->last_status)) + if (extract_midi_event(c, buffer_length, event, &len, track->last_status)) { goto error; + } c += len; buffer_length -= len; @@ -780,6 +792,7 @@ static int parse_mtrk_chunk(smf_track_t *track) { smf_event_t *event; + int ret = 0; if (parse_mtrk_header(track)) return (-1); @@ -788,10 +801,10 @@ parse_mtrk_chunk(smf_track_t *track) event = parse_next_event(track); /* Couldn't parse an event? */ - if (event == NULL) - return (-1); - - assert(smf_event_is_valid(event)); + if (event == NULL || !smf_event_is_valid(event)) { + ret = -1; + break; + } if (event_is_end_of_track(event)) break; @@ -801,7 +814,7 @@ parse_mtrk_chunk(smf_track_t *track) track->file_buffer_length = 0; track->next_event_offset = -1; - return (0); + return (ret); } /** @@ -863,6 +876,7 @@ smf_t * smf_load_from_memory(const void *buffer, const size_t buffer_length) { int i; + int ret; smf_t *smf = smf_new(); @@ -880,16 +894,16 @@ smf_load_from_memory(const void *buffer, const size_t buffer_length) smf_add_track(smf, track); - /* Skip unparseable chunks. */ - if (parse_mtrk_chunk(track)) { - g_warning("SMF warning: Cannot load track."); - smf_track_delete(track); - continue; - } + ret = parse_mtrk_chunk(track); track->file_buffer = NULL; track->file_buffer_length = 0; track->next_event_offset = -1; + + if (ret) { + g_warning("SMF warning: Error parsing track, continuing with data loaded so far."); + break; + } } if (smf->expected_number_of_tracks != smf->number_of_tracks) {