Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bf8c1382 authored by Clemens Ladisch's avatar Clemens Ladisch Committed by Jaroslav Kysela
Browse files

[ALSA] seq_midi_event: fix parsing of missing data bytes



Reorganize the encoder logic to prevent status bytes that appear where
data bytes are expected from being interpreted as data bytes.

Signed-off-by: default avatarClemens Ladisch <clemens@ladisch.de>
Signed-off-by: default avatarJaroslav Kysela <perex@suse.cz>
parent 0b664f72
Loading
Loading
Loading
Loading
+41 −39
Original line number Diff line number Diff line
@@ -73,22 +73,22 @@ static struct status_event_list {
	{SNDRV_SEQ_EVENT_CHANPRESS,	 1, one_param_ctrl_event, one_param_decode},
	{SNDRV_SEQ_EVENT_PITCHBEND,	 2, pitchbend_ctrl_event, pitchbend_decode},
	/* invalid */
	{SNDRV_SEQ_EVENT_NONE,		0, NULL, NULL},
	{SNDRV_SEQ_EVENT_NONE,		-1, NULL, NULL},
	/* 0xf0 - 0xff */
	{SNDRV_SEQ_EVENT_SYSEX,		 1, NULL, NULL}, /* sysex: 0xf0 */
	{SNDRV_SEQ_EVENT_QFRAME,	 1, one_param_event, one_param_decode}, /* 0xf1 */
	{SNDRV_SEQ_EVENT_SONGPOS,	 2, songpos_event, songpos_decode}, /* 0xf2 */
	{SNDRV_SEQ_EVENT_SONGSEL,	 1, one_param_event, one_param_decode}, /* 0xf3 */
	{SNDRV_SEQ_EVENT_NONE,		0, NULL, NULL}, /* 0xf4 */
	{SNDRV_SEQ_EVENT_NONE,		0, NULL, NULL}, /* 0xf5 */
	{SNDRV_SEQ_EVENT_NONE,		-1, NULL, NULL}, /* 0xf4 */
	{SNDRV_SEQ_EVENT_NONE,		-1, NULL, NULL}, /* 0xf5 */
	{SNDRV_SEQ_EVENT_TUNE_REQUEST,	 0, NULL, NULL}, /* 0xf6 */
	{SNDRV_SEQ_EVENT_NONE,		0, NULL, NULL}, /* 0xf7 */
	{SNDRV_SEQ_EVENT_NONE,		-1, NULL, NULL}, /* 0xf7 */
	{SNDRV_SEQ_EVENT_CLOCK,		 0, NULL, NULL}, /* 0xf8 */
	{SNDRV_SEQ_EVENT_NONE,		0, NULL, NULL}, /* 0xf9 */
	{SNDRV_SEQ_EVENT_NONE,		-1, NULL, NULL}, /* 0xf9 */
	{SNDRV_SEQ_EVENT_START,		 0, NULL, NULL}, /* 0xfa */
	{SNDRV_SEQ_EVENT_CONTINUE,	 0, NULL, NULL}, /* 0xfb */
	{SNDRV_SEQ_EVENT_STOP, 		 0, NULL, NULL}, /* 0xfc */
	{SNDRV_SEQ_EVENT_NONE, 		0, NULL, NULL}, /* 0xfd */
	{SNDRV_SEQ_EVENT_NONE, 		-1, NULL, NULL}, /* 0xfd */
	{SNDRV_SEQ_EVENT_SENSING, 	 0, NULL, NULL}, /* 0xfe */
	{SNDRV_SEQ_EVENT_RESET, 	 0, NULL, NULL}, /* 0xff */
};
@@ -256,25 +256,27 @@ int snd_midi_event_encode_byte(struct snd_midi_event *dev, int c,
	}

	spin_lock_irqsave(&dev->lock, flags);
	if (dev->qlen > 0) {
		/* rest of command */
		dev->buf[dev->read++] = c;
		if (dev->type != ST_SYSEX)
			dev->qlen--;
	} else {
	if ((c & 0x80) &&
	    (c != MIDI_CMD_COMMON_SYSEX_END || dev->type != ST_SYSEX)) {
		/* new command */
		dev->read = 1;
		if (c & 0x80) {
		dev->buf[0] = c;
			if ((c & 0xf0) == 0xf0) /* special events */
		if ((c & 0xf0) == 0xf0) /* system messages */
			dev->type = (c & 0x0f) + ST_SPECIAL;
		else
			dev->type = (c >> 4) & 0x07;
		dev->read = 1;
		dev->qlen = status_event[dev->type].qlen;
	} else {
			/* process this byte as argument */
		if (dev->qlen > 0) {
			/* rest of command */
			dev->buf[dev->read++] = c;
			if (dev->type != ST_SYSEX)
				dev->qlen--;
		} else {
			/* running status */
			dev->buf[1] = c;
			dev->qlen = status_event[dev->type].qlen - 1;
			dev->read = 2;
		}
	}
	if (dev->qlen == 0) {