diff options
author | Robin Gareus <robin@gareus.org> | 2017-02-28 16:24:07 +0100 |
---|---|---|
committer | Robin Gareus <robin@gareus.org> | 2017-02-28 16:29:10 +0100 |
commit | 29fcca147b064bbbbb3f93d312b42c5a7dc1f103 (patch) | |
tree | 7912d9ef032e4302109e612fe24c84e473a3c8d9 /libs/evoral | |
parent | 38b5d887950e72a65341d616bf40195657228271 (diff) |
Fix loading SMF meta-data > 127 bytes (no more g_critical abort)
Diffstat (limited to 'libs/evoral')
-rw-r--r-- | libs/evoral/src/libsmf/smf_load.c | 18 |
1 files changed, 15 insertions, 3 deletions
diff --git a/libs/evoral/src/libsmf/smf_load.c b/libs/evoral/src/libsmf/smf_load.c index 6bcf14980e..61a40baf24 100644 --- a/libs/evoral/src/libsmf/smf_load.c +++ b/libs/evoral/src/libsmf/smf_load.c @@ -339,10 +339,22 @@ expected_message_length(unsigned char status, const unsigned char *second_byte, } /* - * Format of this kind of messages is like this: 0xFF 0xwhatever 0xlength and then "length" bytes. - * Second byte points to this: ^^^^^^^^^^ + * Format of this kind of messages is like this: 0xFF 0xTYPE 0xlength and then "length" bytes. + * TYPE is < 127, length may be 0 + * + * "lenght" is a 7bit value, the 8th bit is used to extend the length. + * eg. ff02 8266 <0x166 byte (C) message follows> */ - return (*(second_byte + 1) + 3); + int32_t mlen = 0; + for (int32_t off = 1; off < 4; ++off) { + uint8_t val = *(second_byte + off); + mlen = mlen << 7 | (val & 0x7f); + if (0 == (val & 0x80)) { + mlen += 2 + off; // 2 byte "header" 0xff <type> + <length of length> + break; + } + } + return mlen; } if ((status & 0xF0) == 0xF0) { |