Tolerate clients keeping state across sysex message

This commit is contained in:
Alexandre Ratchov 2019-10-21 00:40:00 +02:00
parent 4fad29ecb6
commit fb8bf93f11
2 changed files with 15 additions and 2 deletions

View File

@ -93,6 +93,7 @@ midi_new(struct midiops *ops, void *arg, int mode)
ep->len = 0;
ep->idx = 0;
ep->st = 0;
ep->last_st = 0;
ep->txmask = 0;
ep->self = 1 << i;
ep->tickets = 0;
@ -306,7 +307,18 @@ midi_in(struct midi *iep, unsigned char *idata, int icount)
iep->msg[iep->idx++] = c;
iep->ops->imsg(iep->arg, iep->msg, iep->idx);
}
iep->st = 0;
/*
* There are bogus MIDI sources that keep
* state across sysex; Linux virmidi ports fed
* by the sequencer is an example. We
* workaround this by saving the current
* status and restoring it at the end of the
* sysex.
*/
iep->st = iep->last_st;
if (iep->st)
iep->len = voice_len[(iep->st >> 4) & 7];
iep->idx = 0;
} else if (c >= 0xf0) {
iep->msg[0] = c;
@ -316,7 +328,7 @@ midi_in(struct midi *iep, unsigned char *idata, int icount)
} else if (c >= 0x80) {
iep->msg[0] = c;
iep->len = voice_len[(c >> 4) & 7];
iep->st = c;
iep->last_st = iep->st = c;
iep->idx = 1;
} else if (iep->st) {
if (iep->idx == 0 && iep->st != SYSEX_START)

View File

@ -68,6 +68,7 @@ struct midi {
#define MIDI_MSGMAX 16 /* max size of MIDI msg */
unsigned char msg[MIDI_MSGMAX]; /* parsed input message */
unsigned int st; /* input MIDI running status */
unsigned int last_st; /* backup of st during sysex */
unsigned int used; /* bytes used in ``msg'' */
unsigned int idx; /* current ``msg'' size */
unsigned int len; /* expected ``msg'' length */