CVE-2017-11664: Out-of-bounds Read (CWE-125)
value: The _WM_SetupMidiEvent function in internal_midi.c:2122 in WildMIDI 0.4.2 can cause a denial of service (invalid memory read and application crash) via a crafted mid file.
CWE description: The product reads data past the end, or before the beginning, of the intended buffer.
CVSS v3 base score: 6.5
Published: 2017-08-17T16:29Z
Repository: https://github.com/Mindwerks/wildmidi
Language: C
Files changed: include/internal_midi.h, src/f_hmi.c, src/f_hmp.c, src/f_midi.c, src/f_mus.c, src/f_xmidi.c, src/internal_midi.c
Commit date: 2017-08-02 18:50:00 +0300
Commit message: Fix bug #175:

CVE-2017-11661, CVE-2017-11662, CVE-2017-11663, CVE-2017-11664:
Add a new size parameter to _WM_SetupMidiEvent() so that it
knows where to stop reading, and adjust its clients properly.

Diff: 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
@@ -189,11 +189,11 @@ extern int _WM_midi_setup_divisions(struct _mdi *mdi, uint32_t divisions);
  * All other declarations
  */
 
 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);
 /* extern void _WM_DynamicVolumeAdjust(struct _mdi *mdi, int32_t *tmp_buffer, uint32_t buffer_used);*/
 extern void _WM_AdjustChannelVolumes(struct _mdi *mdi, uint8_t ch);
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
@@ -40,14 +40,14 @@
  */
 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;
     uint32_t j = 0;
     uint8_t *hmi_addr = NULL;
@@ -72,12 +72,10 @@ _WM_ParseNewHmi(uint8_t *hmi_data, uint32_t hmi_size) {
     struct _note {
         uint32_t length;
         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);
         return NULL;
     }
@@ -214,25 +212,39 @@ _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.
                     if (hmi_data[1] == 0x10) {
                         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)) {
                         hmi_track_end[i] = 1;
                         hmi_tracks_ended++;
@@ -267,21 +279,29 @@ _WM_ParseNewHmi(uint8_t *hmi_data, uint32_t hmi_size) {
 
                         note[hmi_tmp].channel = hmi_running_event[i] & 0xf;
 
                         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) {
                             if ((!smallest_delta) || (smallest_delta > note[hmi_tmp].length)) {
                                 smallest_delta = note[hmi_tmp].length;
@@ -291,24 +311,32 @@ _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])) {
                 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
@@ -233,10 +233,11 @@ _WM_ParseNewHmp(uint8_t *hmp_data, uint32_t hmp_size) {
             smallest_delta = chunk_delta[i];
         }
 
         // 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;
     }
 
     subtract_delta = smallest_delta;
@@ -271,21 +272,23 @@ _WM_ParseNewHmp(uint8_t *hmp_data, uint32_t hmp_size) {
             do {
                 if (((hmp_chunk[i][0] & 0xf0) == 0xb0 ) && ((hmp_chunk[i][1] == 110) || (hmp_chunk[i][1] == 111)) && (hmp_chunk[i][2] > 0x7f)) {
                     // 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;
                     }
 
                     if ((hmp_chunk[i][0] == 0xff) && (hmp_chunk[i][1] == 0x2f) && (hmp_chunk[i][2] == 0x00)) {
                         /* 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)) {
                         /* Tempo */
                         tempo_f = (float)((hmp_chunk[i][3] << 16) + (hmp_chunk[i][4] << 8)+ hmp_chunk[i][5]);
@@ -294,22 +297,30 @@ _WM_ParseNewHmp(uint8_t *hmp_data, uint32_t hmp_size) {
 
                         // DEBUG
                         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])) {
                 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
@@ -41,12 +41,12 @@ struct _mdi *
 _WM_ParseNewMidi(uint8_t *midi_data, uint32_t midi_size) {
     struct _mdi *mdi;
 
     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;
     uint32_t divisions = 96;
     uint32_t tempo = 500000;
@@ -54,19 +54,15 @@ _WM_ParseNewMidi(uint8_t *midi_data, uint32_t midi_size) {
 
     uint32_t sample_count = 0;
     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;
 
     if (midi_size < 14) {
         _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_CORUPT, "(too short)", 0);
@@ -149,10 +145,11 @@ _WM_ParseNewMidi(uint8_t *midi_data, uint32_t midi_size) {
 
     mdi = _WM_initMDI();
     _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);
 
     smallest_delta = 0xffffffff;
@@ -166,42 +163,46 @@ _WM_ParseNewMidi(uint8_t *midi_data, uint32_t midi_size) {
             goto _end;
         }
         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;
 
         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) {
                 smallest_delta = track_delta[i];
             }
@@ -241,11 +242,11 @@ _WM_ParseNewMidi(uint8_t *midi_data, uint32_t midi_size) {
                         }
                         continue;
                     }
                 }
                 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;
                     }
                     if (tracks[i][0] > 0x7f) {
                         if (tracks[i][0] < 0xf0) {
@@ -257,10 +258,11 @@ _WM_ParseNewMidi(uint8_t *midi_data, uint32_t midi_size) {
                         } else if ((tracks[i][0] == 0xff) && (tracks[i][1] == 0x2f) && (tracks[i][2] == 0x00)) {
                             /* End of Track */
                             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 */
                             tempo = (tracks[i][3] << 16) + (tracks[i][4] << 8)+ tracks[i][5];
                             if (!tempo)
@@ -268,19 +270,27 @@ _WM_ParseNewMidi(uint8_t *midi_data, uint32_t midi_size) {
 
                             samples_per_delta_f = _WM_GetSamplesPerTick(divisions, tempo);
                         }
                     }
                     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];
                 }
             NEXT_TRACK: continue;
@@ -302,11 +312,11 @@ _WM_ParseNewMidi(uint8_t *midi_data, uint32_t midi_size) {
         }
         sample_remainder = 0.0;
         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;
                 }
                 if (tracks[i][0] > 0x7f) {
                     if (tracks[i][0] < 0xf0) {
@@ -327,20 +337,28 @@ _WM_ParseNewMidi(uint8_t *midi_data, uint32_t midi_size) {
 
                         samples_per_delta_f = _WM_GetSamplesPerTick(divisions, tempo);
                     }
                 }
                 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);
                 sample_count = (uint32_t) sample_count_f;
                 sample_remainder = sample_count_f - (float) sample_count;
@@ -370,10 +388,11 @@ _WM_ParseNewMidi(uint8_t *midi_data, uint32_t midi_size) {
 _end:   free(sysex_store);
     free(track_end);
     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/f_mus.c b/src/f_mus.c
index 23baed5..b606150 100644
--- a/src/f_mus.c
+++ b/src/f_mus.c
@@ -59,11 +59,12 @@ _WM_ParseNewMus(uint8_t *mus_data, uint32_t mus_size) {
     struct _mdi *mus_mdi;
     uint32_t mus_divisions = 60;
     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;
     uint32_t mus_ticks = 0;
     uint32_t sample_count = 0;
@@ -312,11 +313,11 @@ _WM_ParseNewMus(uint8_t *mus_data, uint32_t mus_size) {
                 mus_event_size = 1;
                 goto _mus_next_data;
                 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;
         }
 
     _mus_next_data:
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
@@ -265,11 +265,11 @@ struct _mdi *_WM_ParseNewXmi(uint8_t *xmi_data, uint32_t xmi_size) {
                         if ((xmi_data[0] == 0xff) && (xmi_data[1] == 0x51) && (xmi_data[2] == 0x03)) {
                             // Ignore tempo events
                             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;
                         }
 
                         if ((*xmi_data & 0xf0) == 0x90) {
                             // Note on has extra data stating note length
diff --git a/src/internal_midi.c b/src/internal_midi.c
index cb7301d..5f86e05 100644
--- a/src/internal_midi.c
+++ b/src/internal_midi.c
@@ -1960,11 +1960,11 @@ void _WM_freeMDI(struct _mdi *mdi) {
     _WM_free_reverb(mdi->reverb);
     free(mdi->mix_buffer);
     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
      to avoid compatibility issues.
 
@@ -1976,41 +1976,48 @@ uint32_t _WM_SetupMidiEvent(struct _mdi *mdi, uint8_t * event_data, uint8_t runn
     uint8_t channel = 0;
     uint8_t data_1 = 0;
     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;
     }
 
     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);
             ret_cnt += 2;
             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);
             ret_cnt += 2;
             break;
@@ -2023,10 +2030,11 @@ uint32_t _WM_SetupMidiEvent(struct _mdi *mdi, uint8_t * event_data, uint8_t runn
             data_1 = *event_data++;
             midi_setup_channel_pressure(mdi, channel, data_1);
             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)));
             ret_cnt += 2;
             break;
@@ -2039,27 +2047,33 @@ uint32_t _WM_SetupMidiEvent(struct _mdi *mdi, uint8_t * event_data, uint8_t runn
                 if ((event_data[0] == 0x00) && (event_data[1] == 0x02)) {
                     /*
                      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) {
                     /* Text Event */
                     /* 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);
                     text[tmp_length] = '\0';
                     midi_setup_text(mdi, text);
@@ -2069,20 +2083,25 @@ uint32_t _WM_SetupMidiEvent(struct _mdi *mdi, uint8_t * event_data, uint8_t runn
                 } else if (event_data[0] == 0x02) {
                     /* Copyright Event */
                     /* 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) {
                         mdi->extra_info.copyright = realloc(mdi->extra_info.copyright,(strlen(mdi->extra_info.copyright) + 1 + tmp_length + 1));
                         memcpy(&mdi->extra_info.copyright[strlen(mdi->extra_info.copyright) + 1], event_data, tmp_length);
@@ -2105,20 +2124,25 @@ uint32_t _WM_SetupMidiEvent(struct _mdi *mdi, uint8_t * event_data, uint8_t runn
                 } else if (event_data[0] == 0x03) {
                     /* Track Name Event */
                     /* 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);
                     text[tmp_length] = '\0';
                     midi_setup_trackname(mdi, text);
@@ -2128,20 +2152,25 @@ uint32_t _WM_SetupMidiEvent(struct _mdi *mdi, uint8_t * event_data, uint8_t runn
                 } else if (event_data[0] == 0x04) {
                     /* Instrument Name Event */
                     /* 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);
                     text[tmp_length] = '\0';
                     midi_setup_instrumentname(mdi, text);
@@ -2151,20 +2180,25 @@ uint32_t _WM_SetupMidiEvent(struct _mdi *mdi, uint8_t * event_data, uint8_t runn
                 } else if (event_data[0] == 0x05) {
                     /* Lyric Event */
                     /* 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);
                     text[tmp_length] = '\0';
                     midi_setup_lyric(mdi, text);
@@ -2174,20 +2208,25 @@ uint32_t _WM_SetupMidiEvent(struct _mdi *mdi, uint8_t * event_data, uint8_t runn
                 } else if (event_data[0] == 0x06) {
                     /* Marker Event */
                     /* 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);
                     text[tmp_length] = '\0';
                     midi_setup_marker(mdi, text);
@@ -2197,20 +2236,25 @@ uint32_t _WM_SetupMidiEvent(struct _mdi *mdi, uint8_t * event_data, uint8_t runn
                 } else if (event_data[0] == 0x07) {
                     /* Cue Point Event */
                     /* 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);
                     text[tmp_length] = '\0';
                     midi_setup_cuepoint(mdi, text);
@@ -2220,36 +2264,41 @@ uint32_t _WM_SetupMidiEvent(struct _mdi *mdi, uint8_t * event_data, uint8_t runn
                 } else if ((event_data[0] == 0x20) && (event_data[1] == 0x01)) {
                     /*
                      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)) {
                     /*
                      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)) {
                     /*
                      End of Track
                      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)) {
                     /*
                      Tempo
                      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
                      */
                     midi_setup_smpteoffset(mdi, ((event_data[3] << 24) + (event_data[4] << 16) + (event_data[5] << 8) + event_data[6]));
@@ -2263,35 +2312,41 @@ uint32_t _WM_SetupMidiEvent(struct _mdi *mdi, uint8_t * event_data, uint8_t runn
                 } else if ((event_data[0] == 0x58) && (event_data[1] == 0x04)) {
                     /*
                      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)) {
                     /*
                      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 {
                     /*
                      Unsupported Meta Event
                      */
                     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)) {
                 /*
                  Sysex Events
@@ -2299,19 +2354,23 @@ uint32_t _WM_SetupMidiEvent(struct _mdi *mdi, uint8_t * event_data, uint8_t runn
                 uint32_t sysex_len = 0;
                 uint8_t *sysex_store = NULL;
 
                 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);
 
                 if (sysex_store[sysex_len - 1] == 0xF7) {
@@ -2379,7 +2438,11 @@ uint32_t _WM_SetupMidiEvent(struct _mdi *mdi, uint8_t * event_data, uint8_t runn
             break;
     }
     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, "(input too short)", 0);
+    return 0;
 }
 

Vulnerable code: extern uint32_t _WM_SetupMidiEvent(struct _mdi *mdi, uint8_t * event_data, uint8_t running_event);
//  uint32_t hmi_duration_secs = 0;
    //FIXME: This needs to be used for sanity check.
    UNUSED(hmi_size);
                    if ((setup_ret = _WM_SetupMidiEvent(hmi_mdi,hmi_data,hmi_running_event[i])) == 0) {
                        if (*hmi_data > 0x7f) {
                if (*hmi_data > 0x7f) {
                    if ((setup_ret = _WM_SetupMidiEvent(hmp_mdi, hmp_chunk[i], 0)) == 0) {
                if (*hmp_chunk[i] < 0x80) {
    uint32_t track_size;
//  uint32_t sysex_store_len = 0;
//  uint32_t tmp_length = 0;
//  uint8_t current_event = 0;
//  uint8_t current_event_ch = 0;
        track_size = *midi_data++ << 24;
        track_size |= *midi_data++ << 16;
        track_size |= *midi_data++ << 8;
        track_size |= *midi_data++;
        if (midi_size < track_size) {
        if (track_size < 3) {
        if ((midi_data[track_size - 3] != 0xFF)
                || (midi_data[track_size - 2] != 0x2F)
                || (midi_data[track_size - 1] != 0x00)) {
        midi_data += track_size;
        midi_size -= track_size;
                    setup_ret = _WM_SetupMidiEvent(mdi, tracks[i], running_event[i]);
                setup_ret = _WM_SetupMidiEvent(mdi, tracks[i], running_event[i]);
    uint8_t mus_event[] = { 0, 0, 0, 0 };
        setup_ret = _WM_SetupMidiEvent(mus_mdi, (uint8_t *)mus_event, 0);
                        if ((setup_ret = _WM_SetupMidiEvent(xmi_mdi,xmi_data,0)) == 0) {
uint32_t _WM_SetupMidiEvent(struct _mdi *mdi, uint8_t * event_data, uint8_t running_event) {
                    if (*event_data > 0x7f) {
                    if (*event_data > 0x7f) {
                    if (*event_data > 0x7f) {
                    if (*event_data > 0x7f) {
                    if (*event_data > 0x7f) {
                    if (*event_data > 0x7f) {
                    if (*event_data > 0x7f) {
                    if (*event_data > 0x7f) {
                if (!sysex_len) break;
Fixed code: extern uint32_t _WM_SetupMidiEvent(struct _mdi *mdi, uint8_t * event_data, uint32_t siz, uint8_t running_event);
    uint32_t data_siz;
                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];
                        hmi_tmp += 4;
                        hmi_tmp = 8;
                    } else {
                        hmi_tmp = 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;
                    if ((setup_ret = _WM_SetupMidiEvent(hmi_mdi,hmi_data,data_siz,hmi_running_event[i])) == 0) {
                        data_siz -= setup_ret;
                        if (data_siz && *hmi_data > 0x7f) {
                                if (!data_siz) break;
                                data_siz--;
                        if (!data_siz) {
                            _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_NOT_HMI, "file too short", 0);
                            goto _hmi_end;
                        }
                        data_siz--;
                        data_siz -= setup_ret;
                if (data_siz && *hmi_data > 0x7f) {
                        if (!data_siz) break;
                        data_siz--;
                if (!data_siz) {
                    _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_NOT_HMI, "file too short", 0);
                    goto _hmi_end;
                }
                data_siz--;
        chunk_length[i] -= chunk_ofs[i];
                    chunk_length[i] -= 3;
                    if ((setup_ret = _WM_SetupMidiEvent(hmp_mdi, hmp_chunk[i], chunk_length[i], 0)) == 0) {
                        chunk_length[i] -= 3;
                    chunk_length[i] -= setup_ret;
                if (chunk_length[i] && *hmp_chunk[i] < 0x80) {
                        if (! chunk_length[i]) break;
                        chunk_length[i]--;
                if (! chunk_length[i]) {
                    _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_NOT_HMP, "file too short", 0);
                    goto _hmp_end;
                }
                chunk_length[i]--;
    uint32_t *track_size;
    track_size = malloc(sizeof(uint32_t) * no_tracks);
        /* track size */
        tmp_val = *midi_data++ << 24;
        tmp_val |= *midi_data++ << 16;
        tmp_val |= *midi_data++ << 8;
        tmp_val |= *midi_data++;
        if (midi_size < tmp_val) {
        if (tmp_val < 3) {
        if ((midi_data[tmp_val - 3] != 0xFF)
                || (midi_data[tmp_val - 2] != 0x2F)
                || (midi_data[tmp_val - 1] != 0x00)) {
        track_size[i] = tmp_val;
        midi_data += tmp_val;
        midi_size -= tmp_val;
            track_size[i]--;
        track_size[i]--;
                    setup_ret = _WM_SetupMidiEvent(mdi, tracks[i], track_size[i], running_event[i]);
                            track_size[i] -= 3;
                    track_size[i] -= setup_ret;
                            if (!track_size[i]) break;
                            track_size[i]--;
                    if (!track_size[i]) {
                        _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_CORUPT, "(too short)", 0);
                        goto _end;
                    }
                    track_size[i]--;
                setup_ret = _WM_SetupMidiEvent(mdi, tracks[i], track_size[i], running_event[i]);
                track_size[i] -= setup_ret;
                        if (!track_size[i]) break;
                        track_size[i]--;
                if (!track_size[i]) {
                    _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_CORUPT, "(too short)", 0);
                    goto _end;
                }
                track_size[i]--;
    free(track_size);
#define MUS_SZ 4
    uint8_t mus_event[MUS_SZ] = { 0, 0, 0, 0 };
        setup_ret = _WM_SetupMidiEvent(mus_mdi, (uint8_t *)mus_event, MUS_SZ, 0);
                        if ((setup_ret = _WM_SetupMidiEvent(xmi_mdi,xmi_data, xmi_size, 0)) == 0) {
uint32_t _WM_SetupMidiEvent(struct _mdi *mdi, uint8_t * event_data, uint32_t siz, uint8_t running_event) {
    if (!siz) goto shortbuf;

        if (--siz == 0) goto shortbuf;
            if (siz < 2) goto shortbuf;
            if (siz < 2) goto shortbuf;
            if (siz < 2) goto shortbuf;
            if (siz < 2) goto shortbuf;
            if (siz < 2) goto shortbuf;
                    if (siz < 4) goto shortbuf;
                    if (--siz && *event_data > 0x7f) {
                            if (!siz) break;
                            siz--;
                    if (!siz) goto shortbuf;
                    if (--siz < tmp_length) goto shortbuf;
                    if (!tmp_length) break; /* bad file? */
                    if (--siz && *event_data > 0x7f) {
                            if (!siz) break;
                            siz--;
                    if (!siz) goto shortbuf;
                    if (--siz < tmp_length) goto shortbuf;
                    if (!tmp_length) break; /* bad file? */
                    if (--siz && *event_data > 0x7f) {
                            if (!siz) break;
                            siz--;
                    if (!siz) goto shortbuf;
                    if (--siz < tmp_length) goto shortbuf;
                    if (!tmp_length) break; /* bad file? */
                    if (--siz && *event_data > 0x7f) {
                            if (!siz) break;
                            siz--;
                    if (!siz) goto shortbuf;
                    if (--siz < tmp_length) goto shortbuf;
                    if (!tmp_length) break; /* bad file? */
                    if (--siz && *event_data > 0x7f) {
                            if (!siz) break;
                            siz--;
                    if (!siz) goto shortbuf;
                    if (--siz < tmp_length) goto shortbuf;
                    if (!tmp_length) break; /* bad file? */
                    if (--siz && *event_data > 0x7f) {
                            if (!siz) break;
                            siz--;
                    if (!siz) goto shortbuf;
                    if (--siz < tmp_length) goto shortbuf;
                    if (!tmp_length) break; /* bad file? */
                    if (--siz && *event_data > 0x7f) {
                            if (!siz) break;
                            siz--;
                    if (!siz) goto shortbuf;
                    if (--siz < tmp_length) goto shortbuf;
                    if (!tmp_length) break; /* bad file? */
                    if (siz < 3) goto shortbuf;
                    if (siz < 3) goto shortbuf;
                    if (siz < 2) goto shortbuf;
                    if (siz < 5) goto shortbuf;
                    if (siz < 7) goto shortbuf;
                    if (siz < 6) goto shortbuf;
                    if (siz < 4) goto shortbuf;
                    if (--siz && *event_data > 0x7f) {
                            if (!siz) break;
                            siz--;
                    if (!siz) goto shortbuf;
                    if (--siz < tmp_length) goto shortbuf;
                        if (!siz) break;
                        siz--;
                if (!siz) goto shortbuf;
                if (--siz < sysex_len) goto shortbuf;
                if (!sysex_len) break; /* bad file? */

shortbuf:
    _WM_GLOBAL_ERROR(__FUNCTION__, __LINE__, WM_ERR_CORUPT, "(input too short)", 0);
    return 0;