diff --git a/include/internal_midi.h b/include/internal_midi.h index afe6319..4e1782e 100644 --- a/include/internal_midi.h +++ b/include/internal_midi.h @@ -191,7 +191,7 @@ extern int _WM_midi_setup_divisions(struct _mdi *mdi, uint32_t divisions); extern struct _mdi * _WM_initMDI(void); extern void _WM_freeMDI(struct _mdi *mdi); -extern uint32_t _WM_SetupMidiEvent(struct _mdi *mdi, uint8_t * event_data, uint8_t running_event); +extern uint32_t _WM_SetupMidiEvent(struct _mdi *mdi, uint8_t * event_data, uint32_t siz, uint8_t running_event); extern void _WM_ResetToStart(struct _mdi *mdi); extern void _WM_do_pan_adjust(struct _mdi *mdi, uint8_t ch); extern void _WM_do_note_off_extra(struct _note *nte); diff --git a/src/f_mus.c b/src/f_mus.c index 23baed5..b606150 100644 --- a/src/f_mus.c +++ b/src/f_mus.c @@ -61,7 +61,8 @@ _WM_ParseNewMus(uint8_t *mus_data, uint32_t mus_size) { float tempo_f = 0.0; uint16_t mus_freq = 0; float samples_per_tick_f = 0.0; - uint8_t mus_event[] = { 0, 0, 0, 0 }; +#define MUS_SZ 4 + uint8_t mus_event[MUS_SZ] = { 0, 0, 0, 0 }; uint8_t mus_event_size = 0; uint8_t mus_prev_vol[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; uint32_t setup_ret = 0; @@ -314,7 +315,7 @@ _WM_ParseNewMus(uint8_t *mus_data, uint32_t mus_size) { break; } - setup_ret = _WM_SetupMidiEvent(mus_mdi, (uint8_t *)mus_event, 0); + setup_ret = _WM_SetupMidiEvent(mus_mdi, (uint8_t *)mus_event, MUS_SZ, 0); if (setup_ret == 0) { goto _mus_end; } diff --git a/src/f_xmidi.c b/src/f_xmidi.c index 62c7131..fb3c6d1 100644 --- a/src/f_xmidi.c +++ b/src/f_xmidi.c @@ -267,7 +267,7 @@ struct _mdi *_WM_ParseNewXmi(uint8_t *xmi_data, uint32_t xmi_size) { setup_ret = 6; goto _XMI_Next_Event; } - if ((setup_ret = _WM_SetupMidiEvent(xmi_mdi,xmi_data,0)) == 0) { + if ((setup_ret = _WM_SetupMidiEvent(xmi_mdi,xmi_data, xmi_size, 0)) == 0) { goto _xmi_end; } diff --git a/src/f_hmi.c b/src/f_hmi.c index 1a8808b..21d9363 100644 --- a/src/f_hmi.c +++ b/src/f_hmi.c @@ -42,10 +42,10 @@ struct _mdi * _WM_ParseNewHmi(uint8_t *hmi_data, uint32_t hmi_size) { uint32_t hmi_tmp = 0; uint8_t *hmi_base = hmi_data; + uint32_t data_siz; uint16_t hmi_bpm = 0; uint16_t hmi_division = 0; -// uint32_t hmi_duration_secs = 0; uint32_t hmi_track_cnt = 0; uint32_t *hmi_track_offset = NULL; uint32_t i = 0; @@ -74,8 +74,6 @@ _WM_ParseNewHmi(uint8_t *hmi_data, uint32_t hmi_size) { uint8_t channel; } *note; - //FIXME: This needs to be used for sanity check. - UNUSED(hmi_size); if (memcmp(hmi_data, "HMI-MIDISONG061595", 18)) { _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_NOT_HMI, NULL, 0); @@ -216,6 +214,11 @@ _WM_ParseNewHmi(uint8_t *hmi_data, uint32_t hmi_size) { do { hmi_data = hmi_base + hmi_track_offset[i]; hmi_delta[i] = 0; + if (hmi_track_offset[i] >= hmi_size) { + _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_NOT_HMI, "file too short", 0); + goto _hmi_end; + } + data_siz = hmi_size - hmi_track_offset[i]; if (hmi_data[0] == 0xfe) { // HMI only event of some sort. @@ -223,14 +226,23 @@ _WM_ParseNewHmi(uint8_t *hmi_data, uint32_t hmi_size) { hmi_tmp = (hmi_data[4] + 5); hmi_data += hmi_tmp; hmi_track_offset[i] += hmi_tmp; + hmi_tmp += 4; } else if (hmi_data[1] == 0x15) { hmi_data += 4; hmi_track_offset[i] += 4; + hmi_tmp = 8; + } else { + hmi_tmp = 4; } hmi_data += 4; hmi_track_offset[i] += 4; + if (hmi_tmp > data_siz) { + _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_NOT_HMI, "file too short", 0); + goto _hmi_end; + } + data_siz -= hmi_tmp; } else { - if ((setup_ret = _WM_SetupMidiEvent(hmi_mdi,hmi_data,hmi_running_event[i])) == 0) { + if ((setup_ret = _WM_SetupMidiEvent(hmi_mdi,hmi_data,data_siz,hmi_running_event[i])) == 0) { goto _hmi_end; } if ((hmi_data[0] == 0xff) && (hmi_data[1] == 0x2f) && (hmi_data[2] == 0x00)) { @@ -269,17 +281,25 @@ _WM_ParseNewHmi(uint8_t *hmi_data, uint32_t hmi_size) { hmi_data += setup_ret; hmi_track_offset[i] += setup_ret; + data_siz -= setup_ret; note[hmi_tmp].length = 0; - if (*hmi_data > 0x7f) { + if (data_siz && *hmi_data > 0x7f) { do { + if (!data_siz) break; note[hmi_tmp].length = (note[hmi_tmp].length << 7) | (*hmi_data & 0x7F); hmi_data++; + data_siz--; hmi_track_offset[i]++; } while (*hmi_data > 0x7F); } + if (!data_siz) { + _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_NOT_HMI, "file too short", 0); + goto _hmi_end; + } note[hmi_tmp].length = (note[hmi_tmp].length << 7) | (*hmi_data & 0x7F); hmi_data++; + data_siz--; hmi_track_offset[i]++; if (note[hmi_tmp].length) { @@ -293,20 +313,28 @@ _WM_ParseNewHmi(uint8_t *hmi_data, uint32_t hmi_size) { } else { hmi_data += setup_ret; hmi_track_offset[i] += setup_ret; + data_siz -= setup_ret; } } // get track delta // hmi_delta[i] = 0; // set at start of loop - if (*hmi_data > 0x7f) { + if (data_siz && *hmi_data > 0x7f) { do { + if (!data_siz) break; hmi_delta[i] = (hmi_delta[i] << 7) | (*hmi_data & 0x7F); hmi_data++; + data_siz--; hmi_track_offset[i]++; } while (*hmi_data > 0x7F); } + if (!data_siz) { + _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_NOT_HMI, "file too short", 0); + goto _hmi_end; + } hmi_delta[i] = (hmi_delta[i] << 7) | (*hmi_data & 0x7F); hmi_data++; + data_siz--; hmi_track_offset[i]++; } while (!hmi_delta[i]); if ((!smallest_delta) || (smallest_delta > hmi_delta[i])) { diff --git a/src/f_hmp.c b/src/f_hmp.c index 565d1fe..f0c64e4 100644 --- a/src/f_hmp.c +++ b/src/f_hmp.c @@ -235,6 +235,7 @@ _WM_ParseNewHmp(uint8_t *hmp_data, uint32_t hmp_size) { // goto start of next chunk hmp_data = hmp_chunk[i] + chunk_length[i]; + chunk_length[i] -= chunk_ofs[i]; hmp_chunk[i] += chunk_ofs[i]++; chunk_end[i] = 0; } @@ -273,10 +274,11 @@ _WM_ParseNewHmp(uint8_t *hmp_data, uint32_t hmp_size) { // Reserved for loop markers // TODO: still deciding what to do about these hmp_chunk[i] += 3; + chunk_length[i] -= 3; } else { uint32_t setup_ret = 0; - if ((setup_ret = _WM_SetupMidiEvent(hmp_mdi, hmp_chunk[i], 0)) == 0) { + if ((setup_ret = _WM_SetupMidiEvent(hmp_mdi, hmp_chunk[i], chunk_length[i], 0)) == 0) { goto _hmp_end; } @@ -284,6 +286,7 @@ _WM_ParseNewHmp(uint8_t *hmp_data, uint32_t hmp_size) { /* End of Chunk */ end_of_chunks++; chunk_end[i] = 1; + chunk_length[i] -= 3; hmp_chunk[i] += 3; goto NEXT_CHUNK; } else if ((hmp_chunk[i][0] == 0xff) && (hmp_chunk[i][1] == 0x51) && (hmp_chunk[i][2] == 0x03)) { @@ -296,18 +299,26 @@ _WM_ParseNewHmp(uint8_t *hmp_data, uint32_t hmp_size) { fprintf(stderr,"DEBUG: Tempo change %f\r\n", tempo_f); } hmp_chunk[i] += setup_ret; + chunk_length[i] -= setup_ret; } var_len_shift = 0; chunk_delta[i] = 0; - if (*hmp_chunk[i] < 0x80) { + if (chunk_length[i] && *hmp_chunk[i] < 0x80) { do { + if (! chunk_length[i]) break; chunk_delta[i] = chunk_delta[i] + ((*hmp_chunk[i] & 0x7F) << var_len_shift); var_len_shift += 7; hmp_chunk[i]++; + chunk_length[i]--; } while (*hmp_chunk[i] < 0x80); } + if (! chunk_length[i]) { + _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_NOT_HMP, "file too short", 0); + goto _hmp_end; + } chunk_delta[i] = chunk_delta[i] + ((*hmp_chunk[i] & 0x7F) << var_len_shift); hmp_chunk[i]++; + chunk_length[i]--; } while (!chunk_delta[i]); if ((!smallest_delta) || (smallest_delta > chunk_delta[i])) { diff --git a/src/f_midi.c b/src/f_midi.c index 6b52932..c8f278b 100644 --- a/src/f_midi.c +++ b/src/f_midi.c @@ -43,8 +43,8 @@ _WM_ParseNewMidi(uint8_t *midi_data, uint32_t midi_size) { uint32_t tmp_val; uint32_t midi_type; - uint32_t track_size; uint8_t **tracks; + uint32_t *track_size; uint32_t end_of_tracks = 0; uint32_t no_tracks; uint32_t i; @@ -56,15 +56,11 @@ _WM_ParseNewMidi(uint8_t *midi_data, uint32_t midi_size) { float sample_count_f = 0.0; float sample_remainder = 0.0; uint8_t *sysex_store = NULL; -// uint32_t sysex_store_len = 0; uint32_t *track_delta; uint8_t *track_end; uint32_t smallest_delta = 0; uint32_t subtract_delta = 0; -// uint32_t tmp_length = 0; -// uint8_t current_event = 0; -// uint8_t current_event_ch = 0; uint8_t *running_event; uint32_t setup_ret = 0; @@ -151,6 +147,7 @@ _WM_ParseNewMidi(uint8_t *midi_data, uint32_t midi_size) { _WM_midi_setup_divisions(mdi,divisions); tracks = malloc(sizeof(uint8_t *) * no_tracks); + track_size = malloc(sizeof(uint32_t) * no_tracks); track_delta = malloc(sizeof(uint32_t) * no_tracks); track_end = malloc(sizeof(uint8_t) * no_tracks); running_event = malloc(sizeof(uint8_t) * no_tracks); @@ -168,28 +165,30 @@ _WM_ParseNewMidi(uint8_t *midi_data, uint32_t midi_size) { midi_data += 4; midi_size -= 4; - track_size = *midi_data++ << 24; - track_size |= *midi_data++ << 16; - track_size |= *midi_data++ << 8; - track_size |= *midi_data++; + /* track size */ + tmp_val = *midi_data++ << 24; + tmp_val |= *midi_data++ << 16; + tmp_val |= *midi_data++ << 8; + tmp_val |= *midi_data++; midi_size -= 4; - if (midi_size < track_size) { + if (midi_size < tmp_val) { _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_CORUPT, "(too short)", 0); goto _end; } - if (track_size < 3) { + if (tmp_val < 3) { _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_CORUPT, "(bad track size)", 0); goto _end; } - if ((midi_data[track_size - 3] != 0xFF) - || (midi_data[track_size - 2] != 0x2F) - || (midi_data[track_size - 1] != 0x00)) { + if ((midi_data[tmp_val - 3] != 0xFF) + || (midi_data[tmp_val - 2] != 0x2F) + || (midi_data[tmp_val - 1] != 0x00)) { _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_CORUPT, "(missing EOT)", 0); goto _end; } tracks[i] = midi_data; - midi_data += track_size; - midi_size -= track_size; + track_size[i] = tmp_val; + midi_data += tmp_val; + midi_size -= tmp_val; track_end[i] = 0; running_event[i] = 0; track_delta[i] = 0; @@ -197,9 +196,11 @@ _WM_ParseNewMidi(uint8_t *midi_data, uint32_t midi_size) { while (*tracks[i] > 0x7F) { track_delta[i] = (track_delta[i] << 7) + (*tracks[i] & 0x7F); tracks[i]++; + track_size[i]--; } track_delta[i] = (track_delta[i] << 7) + (*tracks[i] & 0x7F); tracks[i]++; + track_size[i]--; if (midi_type == 1 ) { if (track_delta[i] < smallest_delta) { @@ -243,7 +244,7 @@ _WM_ParseNewMidi(uint8_t *midi_data, uint32_t midi_size) { } } do { - setup_ret = _WM_SetupMidiEvent(mdi, tracks[i], running_event[i]); + setup_ret = _WM_SetupMidiEvent(mdi, tracks[i], track_size[i], running_event[i]); if (setup_ret == 0) { goto _end; } @@ -259,6 +260,7 @@ _WM_ParseNewMidi(uint8_t *midi_data, uint32_t midi_size) { end_of_tracks++; track_end[i] = 1; tracks[i] += 3; + track_size[i] -= 3; goto NEXT_TRACK; } else if ((tracks[i][0] == 0xff) && (tracks[i][1] == 0x51) && (tracks[i][2] == 0x03)) { /* Tempo */ @@ -270,15 +272,23 @@ _WM_ParseNewMidi(uint8_t *midi_data, uint32_t midi_size) { } } tracks[i] += setup_ret; + track_size[i] -= setup_ret; if (*tracks[i] > 0x7f) { do { + if (!track_size[i]) break; track_delta[i] = (track_delta[i] << 7) + (*tracks[i] & 0x7F); tracks[i]++; + track_size[i]--; } while (*tracks[i] > 0x7f); } + if (!track_size[i]) { + _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_CORUPT, "(too short)", 0); + goto _end; + } track_delta[i] = (track_delta[i] << 7) + (*tracks[i] & 0x7F); tracks[i]++; + track_size[i]--; } while (!track_delta[i]); if ((!smallest_delta) || (smallest_delta > track_delta[i])) { smallest_delta = track_delta[i]; @@ -304,7 +314,7 @@ _WM_ParseNewMidi(uint8_t *midi_data, uint32_t midi_size) { for (i = 0; i < no_tracks; i++) { running_event[i] = 0; do { - setup_ret = _WM_SetupMidiEvent(mdi, tracks[i], running_event[i]); + setup_ret = _WM_SetupMidiEvent(mdi, tracks[i], track_size[i], running_event[i]); if (setup_ret == 0) { goto _end; } @@ -329,16 +339,24 @@ _WM_ParseNewMidi(uint8_t *midi_data, uint32_t midi_size) { } } tracks[i] += setup_ret; + track_size[i] -= setup_ret; track_delta[i] = 0; if (*tracks[i] > 0x7f) { do { + if (!track_size[i]) break; track_delta[i] = (track_delta[i] << 7) + (*tracks[i] & 0x7F); tracks[i]++; + track_size[i]--; } while (*tracks[i] > 0x7f); } + if (!track_size[i]) { + _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_CORUPT, "(too short)", 0); + goto _end; + } track_delta[i] = (track_delta[i] << 7) + (*tracks[i] & 0x7F); tracks[i]++; + track_size[i]--; sample_count_f = (((float) track_delta[i] * samples_per_delta_f) + sample_remainder); @@ -372,6 +390,7 @@ _end: free(sysex_store); free(track_delta); free(running_event); free(tracks); + free(track_size); if (mdi->reverb) return (mdi); _WM_freeMDI(mdi); return (NULL); diff --git a/src/internal_midi.c b/src/internal_midi.c index cb7301d..f67f71a 100644 --- a/src/internal_midi.c +++ b/src/internal_midi.c @@ -1962,7 +1962,7 @@ void _WM_freeMDI(struct _mdi *mdi) { free(mdi); } -uint32_t _WM_SetupMidiEvent(struct _mdi *mdi, uint8_t * event_data, uint8_t running_event) { +uint32_t _WM_SetupMidiEvent(struct _mdi *mdi, uint8_t * event_data, uint32_t siz, uint8_t running_event) { /* Only add standard MIDI and Sysex events in here. Non-standard events need to be handled by calling function @@ -1978,10 +1978,13 @@ uint32_t _WM_SetupMidiEvent(struct _mdi *mdi, uint8_t * event_data, uint8_t runn uint8_t data_2 = 0; char *text = NULL; + if (!siz) goto shortbuf; + if (event_data[0] >= 0x80) { command = *event_data & 0xf0; channel = *event_data++ & 0x0f; ret_cnt++; + if (--siz == 0) goto shortbuf; } else { command = running_event & 0xf0; channel = running_event & 0x0f; @@ -1990,6 +1993,7 @@ uint32_t _WM_SetupMidiEvent(struct _mdi *mdi, uint8_t * event_data, uint8_t runn switch(command) { case 0x80: _SETUP_NOTEOFF: + if (siz < 2) goto shortbuf; data_1 = *event_data++; data_2 = *event_data++; _WM_midi_setup_noteoff(mdi, channel, data_1, data_2); @@ -1997,18 +2001,21 @@ uint32_t _WM_SetupMidiEvent(struct _mdi *mdi, uint8_t * event_data, uint8_t runn break; case 0x90: if (event_data[1] == 0) goto _SETUP_NOTEOFF; /* A velocity of 0 in a note on is actually a note off */ + if (siz < 2) goto shortbuf; data_1 = *event_data++; data_2 = *event_data++; midi_setup_noteon(mdi, channel, data_1, data_2); ret_cnt += 2; break; case 0xa0: + if (siz < 2) goto shortbuf; data_1 = *event_data++; data_2 = *event_data++; midi_setup_aftertouch(mdi, channel, data_1, data_2); ret_cnt += 2; break; case 0xb0: + if (siz < 2) goto shortbuf; data_1 = *event_data++; data_2 = *event_data++; midi_setup_control(mdi, channel, data_1, data_2); @@ -2025,6 +2032,7 @@ uint32_t _WM_SetupMidiEvent(struct _mdi *mdi, uint8_t * event_data, uint8_t runn ret_cnt++; break; case 0xe0: + if (siz < 2) goto shortbuf; data_1 = *event_data++; data_2 = *event_data++; midi_setup_pitch(mdi, channel, ((data_2 << 7) | (data_1 & 0x7f))); @@ -2041,6 +2049,7 @@ uint32_t _WM_SetupMidiEvent(struct _mdi *mdi, uint8_t * event_data, uint8_t runn Sequence Number We only setting this up here for WM_Event2Midi function */ + if (siz < 4) goto shortbuf; midi_setup_sequenceno(mdi, ((event_data[2] << 8) + event_data[3])); ret_cnt += 4; } else if (event_data[0] == 0x01) { @@ -2048,16 +2057,21 @@ uint32_t _WM_SetupMidiEvent(struct _mdi *mdi, uint8_t * event_data, uint8_t runn /* Get Length */ event_data++; ret_cnt++; - if (*event_data > 0x7f) { + if (--siz && *event_data > 0x7f) { do { + if (!siz) break; tmp_length = (tmp_length << 7) + (*event_data & 0x7f); event_data++; + siz--; ret_cnt++; } while (*event_data > 0x7f); } + if (!siz) goto shortbuf; tmp_length = (tmp_length << 7) + (*event_data & 0x7f); event_data++; ret_cnt++; + if (--siz < tmp_length) goto shortbuf; + if (!tmp_length) break; /* bad file? */ text = malloc(tmp_length + 1); memcpy(text, event_data, tmp_length); @@ -2071,16 +2085,21 @@ uint32_t _WM_SetupMidiEvent(struct _mdi *mdi, uint8_t * event_data, uint8_t runn /* Get Length */ event_data++; ret_cnt++; - if (*event_data > 0x7f) { + if (--siz && *event_data > 0x7f) { do { + if (!siz) break; tmp_length = (tmp_length << 7) + (*event_data & 0x7f); event_data++; + siz--; ret_cnt++; } while (*event_data > 0x7f); } + if (!siz) goto shortbuf; tmp_length = (tmp_length << 7) + (*event_data & 0x7f); event_data++; ret_cnt++; + if (--siz < tmp_length) goto shortbuf; + if (!tmp_length) break; /* bad file? */ /* Copy copyright info in the getinfo struct */ if (mdi->extra_info.copyright) { @@ -2107,16 +2126,21 @@ uint32_t _WM_SetupMidiEvent(struct _mdi *mdi, uint8_t * event_data, uint8_t runn /* Get Length */ event_data++; ret_cnt++; - if (*event_data > 0x7f) { + if (--siz && *event_data > 0x7f) { do { + if (!siz) break; tmp_length = (tmp_length << 7) + (*event_data & 0x7f); event_data++; + siz--; ret_cnt++; } while (*event_data > 0x7f); } + if (!siz) goto shortbuf; tmp_length = (tmp_length << 7) + (*event_data & 0x7f); event_data++; ret_cnt++; + if (--siz < tmp_length) goto shortbuf; + if (!tmp_length) break; /* bad file? */ text = malloc(tmp_length + 1); memcpy(text, event_data, tmp_length); @@ -2130,16 +2154,21 @@ uint32_t _WM_SetupMidiEvent(struct _mdi *mdi, uint8_t * event_data, uint8_t runn /* Get Length */ event_data++; ret_cnt++; - if (*event_data > 0x7f) { + if (--siz && *event_data > 0x7f) { do { + if (!siz) break; tmp_length = (tmp_length << 7) + (*event_data & 0x7f); event_data++; + siz--; ret_cnt++; } while (*event_data > 0x7f); } + if (!siz) goto shortbuf; tmp_length = (tmp_length << 7) + (*event_data & 0x7f); event_data++; ret_cnt++; + if (--siz < tmp_length) goto shortbuf; + if (!tmp_length) break; /* bad file? */ text = malloc(tmp_length + 1); memcpy(text, event_data, tmp_length); @@ -2153,16 +2182,21 @@ uint32_t _WM_SetupMidiEvent(struct _mdi *mdi, uint8_t * event_data, uint8_t runn /* Get Length */ event_data++; ret_cnt++; - if (*event_data > 0x7f) { + if (--siz && *event_data > 0x7f) { do { + if (!siz) break; tmp_length = (tmp_length << 7) + (*event_data & 0x7f); event_data++; + siz--; ret_cnt++; } while (*event_data > 0x7f); } + if (!siz) goto shortbuf; tmp_length = (tmp_length << 7) + (*event_data & 0x7f); event_data++; ret_cnt++; + if (--siz < tmp_length) goto shortbuf; + if (!tmp_length) break; /* bad file? */ text = malloc(tmp_length + 1); memcpy(text, event_data, tmp_length); @@ -2176,16 +2210,21 @@ uint32_t _WM_SetupMidiEvent(struct _mdi *mdi, uint8_t * event_data, uint8_t runn /* Get Length */ event_data++; ret_cnt++; - if (*event_data > 0x7f) { + if (--siz && *event_data > 0x7f) { do { + if (!siz) break; tmp_length = (tmp_length << 7) + (*event_data & 0x7f); event_data++; + siz--; ret_cnt++; } while (*event_data > 0x7f); } + if (!siz) goto shortbuf; tmp_length = (tmp_length << 7) + (*event_data & 0x7f); event_data++; ret_cnt++; + if (--siz < tmp_length) goto shortbuf; + if (!tmp_length) break; /* bad file? */ text = malloc(tmp_length + 1); memcpy(text, event_data, tmp_length); @@ -2199,16 +2238,21 @@ uint32_t _WM_SetupMidiEvent(struct _mdi *mdi, uint8_t * event_data, uint8_t runn /* Get Length */ event_data++; ret_cnt++; - if (*event_data > 0x7f) { + if (--siz && *event_data > 0x7f) { do { + if (!siz) break; tmp_length = (tmp_length << 7) + (*event_data & 0x7f); event_data++; + siz--; ret_cnt++; } while (*event_data > 0x7f); } + if (!siz) goto shortbuf; tmp_length = (tmp_length << 7) + (*event_data & 0x7f); event_data++; ret_cnt++; + if (--siz < tmp_length) goto shortbuf; + if (!tmp_length) break; /* bad file? */ text = malloc(tmp_length + 1); memcpy(text, event_data, tmp_length); @@ -2222,6 +2266,7 @@ uint32_t _WM_SetupMidiEvent(struct _mdi *mdi, uint8_t * event_data, uint8_t runn Channel Prefix We only setting this up here for WM_Event2Midi function */ + if (siz < 3) goto shortbuf; midi_setup_channelprefix(mdi, event_data[2]); ret_cnt += 3; } else if ((event_data[0] == 0x21) && (event_data[1] == 0x01)) { @@ -2229,6 +2274,7 @@ uint32_t _WM_SetupMidiEvent(struct _mdi *mdi, uint8_t * event_data, uint8_t runn Port Prefix We only setting this up here for WM_Event2Midi function */ + if (siz < 3) goto shortbuf; midi_setup_portprefix(mdi, event_data[2]); ret_cnt += 3; } else if ((event_data[0] == 0x2F) && (event_data[1] == 0x00)) { @@ -2237,6 +2283,7 @@ uint32_t _WM_SetupMidiEvent(struct _mdi *mdi, uint8_t * event_data, uint8_t runn Deal with this inside calling function We only setting this up here for _WM_Event2Midi function */ + if (siz < 2) goto shortbuf; _WM_midi_setup_endoftrack(mdi); ret_cnt += 2; } else if ((event_data[0] == 0x51) && (event_data[1] == 0x03)) { @@ -2245,9 +2292,11 @@ uint32_t _WM_SetupMidiEvent(struct _mdi *mdi, uint8_t * event_data, uint8_t runn Deal with this inside calling function. We only setting this up here for _WM_Event2Midi function */ + if (siz < 5) goto shortbuf; _WM_midi_setup_tempo(mdi, ((event_data[2] << 16) + (event_data[3] << 8) + event_data[4])); ret_cnt += 5; } else if ((event_data[0] == 0x54) && (event_data[1] == 0x05)) { + if (siz < 7) goto shortbuf; /* SMPTE Offset We only setting this up here for WM_Event2Midi function @@ -2265,6 +2314,7 @@ uint32_t _WM_SetupMidiEvent(struct _mdi *mdi, uint8_t * event_data, uint8_t runn Time Signature We only setting this up here for WM_Event2Midi function */ + if (siz < 6) goto shortbuf; midi_setup_timesignature(mdi, ((event_data[2] << 24) + (event_data[3] << 16) + (event_data[4] << 8) + event_data[5])); ret_cnt += 6; } else if ((event_data[0] == 0x59) && (event_data[1] == 0x02)) { @@ -2272,6 +2322,7 @@ uint32_t _WM_SetupMidiEvent(struct _mdi *mdi, uint8_t * event_data, uint8_t runn Key Signature We only setting this up here for WM_Event2Midi function */ + if (siz < 4) goto shortbuf; midi_setup_keysignature(mdi, ((event_data[2] << 8) + event_data[3])); ret_cnt += 4; } else { @@ -2280,16 +2331,20 @@ uint32_t _WM_SetupMidiEvent(struct _mdi *mdi, uint8_t * event_data, uint8_t runn */ event_data++; ret_cnt++; - if (*event_data > 0x7f) { + if (--siz && *event_data > 0x7f) { do { + if (!siz) break; tmp_length = (tmp_length << 7) + (*event_data & 0x7f); event_data++; + siz--; ret_cnt++; } while (*event_data > 0x7f); } + if (!siz) goto shortbuf; tmp_length = (tmp_length << 7) + (*event_data & 0x7f); ret_cnt++; ret_cnt += tmp_length; + if (--siz < tmp_length) goto shortbuf; } } else if ((channel == 0) || (channel == 7)) { @@ -2301,15 +2356,19 @@ uint32_t _WM_SetupMidiEvent(struct _mdi *mdi, uint8_t * event_data, uint8_t runn if (*event_data > 0x7f) { do { + if (!siz) break; sysex_len = (sysex_len << 7) + (*event_data & 0x7F); event_data++; + siz--; ret_cnt++; } while (*event_data > 0x7f); } + if (!siz) goto shortbuf; sysex_len = (sysex_len << 7) + (*event_data & 0x7F); event_data++; - if (!sysex_len) break; ret_cnt++; + if (--siz < sysex_len) goto shortbuf; + if (!sysex_len) break; /* bad file? */ sysex_store = malloc(sizeof(uint8_t) * sysex_len); memcpy(sysex_store, event_data, sysex_len); @@ -2381,5 +2440,9 @@ uint32_t _WM_SetupMidiEvent(struct _mdi *mdi, uint8_t * event_data, uint8_t runn if (ret_cnt == 0) _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_CORUPT, "(missing event)", 0); return ret_cnt; + +shortbuf: + _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_CORUPT, "(too short)", 0); + return 0; }