2013/1/10 Johannes Kroll jkroll@lavabit.com
On Thu, 10 Jan 2013 01:05:28 +0100 Johannes Kroll jkroll@lavabit.com wrote:
On Thu, 10 Jan 2013 00:38:06 +0100 Christian Costa titan.costa@gmail.com wrote:
After a better look the changes seem correct. The condition i < lpMidioutHdr->dwBufferLength-1 is not necessary
tough.
Without the buffer length check, there would be a buffer overflow when an application tries to send a SysEx without an F7 byte.
I meant a read past the end of the buffer of course, not an overflow.
In your code you stop checking F7 just before the last byte (until position lpMidiOutHdr->dwBufferLength-2); You can check the last byte as well. This is also valid and simplify the condition. The missing F7 byte case is handled by the for loop.
Regarding the single MMDRV_Message call, I was thinking about something like below. This also enable printing a WARN when F7 is missing which can be useful for debug.
DWORD oldBufferLength = lpMidiOutHdr->dwBufferLength; DWORD ret;
for(i = 0; i < lpMidiOutHdr->dwBufferLength; i++)
/* SysEx messages are terminated by a 0xF7 byte. If the buffer contains additional bytes, send only the bytes up to the termination byte. */ if((unsigned char)lpMidiOutHdr->lpData[i] == 0xF7) { lpMidiOutHdr->dwBufferLength = i+1;
break;
}
if (i == lpMidiOutHdr->dwBufferLength)
WARN("SysEx termination byte 0xF7 missing\n")
ret = MMDRV_Message(wmld, MODM_LONGDATA, (DWORD_PTR)lpMidiOutHdr, uSize);
/* restore the midi header to its original state. */ lpMidiOutHdr->dwBufferLength = oldBufferLength;
return ret;