Giter VIP home page Giter VIP logo

midifile's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

midifile's Issues

while(1)

when i want to read file context {0x00 0x00 .....}
MidiFile::read
int Binasc::writeToBinary
will while(1)

Meta event parse error

The structure of Meta event is:
0xFF <type byte> <var len> data ...
and in MidiFile.cpp line 2599:

metai = MidiFile::readByte(input); // meta type
array.push_back(metai);
for (uchar j=0; j<metai; j++) {
    byte = MidiFile::readByte(input); // meta type
    array.push_back(byte);
}

use 1 byte metai as the var len.

If a mid file contains a meta event which is larger than 127 bytes
etc: I will save a custom text event to track who play this song in my app.
This file will read failed.

Documentation source code links to the wrong lines

The links to the source code from the documentation don't match with the source code of the current version of Midifile. I'm up for taking care of this, but might I also recommend something like Doxygen to help with documentation generation?

How to copy tracks?

for example, I want to copy Track 1 twice and add the new tracks in the end of the midi

        int tb = A.getNumTracks();
	A.addTracks(times);

	for (int i = tb; i < tb + times; ++i)
		A[i] = A[channel];
	A.sortTracks();
	A.write(filepath);

But however, the output file is the same as the origin midi
How can I fix?

Binasc.h missing two required headers for it to compile with MinGW

Unless these includes are added to Binasc.h:

#include <cstdlib>
#include <stdlib.h>

Then you get compile errors like this:

src-library/Binasc.cpp:1273:53: error: 'atof' was not declared in this scope
       double doubleOutput = atof(&word[quoteIndex+1]);

src-library/Binasc.cpp:1307:52: error: 'atoi' was not declared in this scope
          long tempLong = atoi(&word[quoteIndex + 1]);

src-library/Binasc.cpp:1445:61: error: 'strtol' was not declared in this scope
    outputByte = (uchar)strtol(word.c_str(), (char**)NULL, 16);

src-library/Binasc.cpp:1677:40: error: 'strtod' was not declared in this scope
    double value = strtod(&word[1], NULL);

2 Indexing Errors, already fixed them.

I found two indexing errors in joinTracks(); and splitTracks();, both errors involved going out of bounds on the vector, I already fixed the errors after some reading up on the documentation for vectors, and will leave the updated MidiFile.cpp attached to this ticket. Note the commenting for info.

MidiFile.cpp.zip

variable length values must not be >4 bytes

Why are you writing up to 5 bytes in MidiFile::writeVLValue? I don't think this is correct according to Midi 1.1 spec:

The largest number which is allowed is 0FFFFFFF so that the variable-length representations must fit in 32 bits in a routine to write variable-length numbers.

I.e. that aValue == 0x0FFFFFFF gives VLValue of 0x7FFFFFFF. Fluidsynth's midi parser actually complains when reading midi files written with this library.

Multiple bugs

the MidiEvent::linkEvent function in src-library/MidiEvent.cpp in midifile through 2017-03-16 can cause a denial of service(invalid memory read and application crash) via a crafted mid file.

./mid2mtb midifile_invalid_memory_read_1.mid

----debug info:----
Program received signal SIGSEGV, Segmentation fault.
0x0000000000405e57 in MidiEvent::linkEvent (this=0x21, mev=0x643610)
    at src-library/MidiEvent.cpp:184
184	   if (eventlink != NULL) {
(gdb) bt
#0  0x0000000000405e57 in MidiEvent::linkEvent (this=0x21, mev=0x643610)
    at src-library/MidiEvent.cpp:184
#1  0x0000000000407555 in MidiEventList::linkNotePairs (this=0x641e30)
    at src-library/MidiEventList.cpp:316
#2  0x00000000004135b2 in MidiFile::linkNotePairs (this=0x7fffffffde60)
    at src-library/MidiFile.cpp:2232
#3  0x0000000000402f4c in convertMidiFile (midifile=..., 
    matlab=std::vector of length 0, capacity 100000)
    at src-programs/mid2mtb.cpp:65
#4  0x0000000000402eca in main (argc=2, argv=0x7fffffffdfc8)
    at src-programs/mid2mtb.cpp:49
(gdb) disassemble 
Dump of assembler code for function MidiEvent::linkEvent(MidiEvent*):
   0x0000000000405e2a <+0>:	push   %rbp
   0x0000000000405e2b <+1>:	mov    %rsp,%rbp
   0x0000000000405e2e <+4>:	sub    $0x10,%rsp
   0x0000000000405e32 <+8>:	mov    %rdi,-0x8(%rbp)
   0x0000000000405e36 <+12>:	mov    %rsi,-0x10(%rbp)
   0x0000000000405e3a <+16>:	mov    -0x10(%rbp),%rax
   0x0000000000405e3e <+20>:	mov    0x30(%rax),%rax
   0x0000000000405e42 <+24>:	test   %rax,%rax
   0x0000000000405e45 <+27>:	je     0x405e53 <MidiEvent::linkEvent(MidiEvent*)+41>
   0x0000000000405e47 <+29>:	mov    -0x10(%rbp),%rax
   0x0000000000405e4b <+33>:	mov    %rax,%rdi
   0x0000000000405e4e <+36>:	callq  0x405de8 <MidiEvent::unlinkEvent()>
   0x0000000000405e53 <+41>:	mov    -0x8(%rbp),%rax
=> 0x0000000000405e57 <+45>:	mov    0x30(%rax),%rax
   0x0000000000405e5b <+49>:	test   %rax,%rax
   0x0000000000405e5e <+52>:	je     0x405e70 <MidiEvent::linkEvent(MidiEvent*)+70>
   0x0000000000405e60 <+54>:	mov    -0x8(%rbp),%rax
   0x0000000000405e64 <+58>:	mov    0x30(%rax),%rax
   0x0000000000405e68 <+62>:	mov    %rax,%rdi
   0x0000000000405e6b <+65>:	callq  0x405de8 <MidiEvent::unlinkEvent()>
---Type <return> to continue, or q <return> to quit---q
Quit
(gdb) i r
rax            0x21	33
rbx            0x42	66
rcx            0x644dc0	6573504
rdx            0x643610	6567440
rsi            0x643610	6567440
rdi            0x21	33
rbp            0x7fffffffdc60	0x7fffffffdc60
rsp            0x7fffffffdc50	0x7fffffffdc50
r8             0x0	0
r9             0x2	2
r10            0x7ffff78b97b8	140737346508728
r11            0x7ffff78b9701	140737346508545
r12            0x402d60	4205920
r13            0x7fffffffdfc0	140737488347072
r14            0x0	0
r15            0x0	0
rip            0x405e57	0x405e57 <MidiEvent::linkEvent(MidiEvent*)+45>
eflags         0x10246	[ PF ZF IF RF ]
cs             0x33	51
ss             0x2b	43
ds             0x0	0
es             0x0	0
fs             0x0	0
---Type <return> to continue, or q <return> to quit---
gs             0x0	0
(gdb)

=================================================================
==7038== ERROR: AddressSanitizer: heap-use-after-free on address 0x605a000123d0 at pc 0x40b51d bp 0x7ffc56c2b7a0 sp 0x7ffc56c2b798
READ of size 8 at 0x605a000123d0 thread T0
    #0 0x40b51c in std::vector<MidiEvent*, std::allocator<MidiEvent*> >::push_back(MidiEvent* const&) /usr/include/c++/4.8/bits/stl_vector.h:903
    #1 0x40a391 in MidiEventList::linkNotePairs() /home/a/Downloads/midifile-master/src-library/MidiEventList.cpp:309
    #2 0x41e632 in MidiFile::linkNotePairs() /home/a/Downloads/midifile-master/src-library/MidiFile.cpp:2232
    #3 0x403545 in convertMidiFile(MidiFile&, std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > >&) /home/a/Downloads/midifile-master/src-programs/mid2mtb.cpp:65
    #4 0x403476 in main /home/a/Downloads/midifile-master/src-programs/mid2mtb.cpp:49
    #5 0x7fa7aabe4ec4 (/lib/x86_64-linux-gnu/libc.so.6+0x21ec4)
    #6 0x4032f8 in _start (/home/a/Downloads/midifile-master/bin/mid2mtb+0x4032f8)
0x605a000123d0 is located 1360 bytes inside of 3072-byte region [0x605a00011e80,0x605a00012a80)
freed by thread T0 here:
    #0 0x7fa7ab4b39da (/usr/lib/x86_64-linux-gnu/libasan.so.0+0x119da)
    #1 0x410889 in __gnu_cxx::new_allocator<std::vector<MidiEvent*, std::allocator<MidiEvent*> > >::deallocate(std::vector<MidiEvent*, std::allocator<MidiEvent*> >*, unsigned long) /usr/include/c++/4.8/ext/new_allocator.h:110
    #2 0x40f741 in std::_Vector_base<std::vector<MidiEvent*, std::allocator<MidiEvent*> >, std::allocator<std::vector<MidiEvent*, std::allocator<MidiEvent*> > > >::_M_deallocate(std::vector<MidiEvent*, std::allocator<MidiEvent*> >*, unsigned long) /usr/include/c++/4.8/bits/stl_vector.h:174
    #3 0x40e061 in std::_Vector_base<std::vector<MidiEvent*, std::allocator<MidiEvent*> >, std::allocator<std::vector<MidiEvent*, std::allocator<MidiEvent*> > > >::~_Vector_base() /usr/include/c++/4.8/bits/stl_vector.h:160
    #4 0x40bb5d in std::vector<std::vector<MidiEvent*, std::allocator<MidiEvent*> >, std::allocator<std::vector<MidiEvent*, std::allocator<MidiEvent*> > > >::~vector() /usr/include/c++/4.8/bits/stl_vector.h:416
    #5 0x4111d1 in void std::_Destroy<std::vector<std::vector<MidiEvent*, std::allocator<MidiEvent*> >, std::allocator<std::vector<MidiEvent*, std::allocator<MidiEvent*> > > > >(std::vector<std::vector<MidiEvent*, std::allocator<MidiEvent*> >, std::allocator<std::vector<MidiEvent*, std::allocator<MidiEvent*> > > >*) /usr/include/c++/4.8/bits/stl_construct.h:93
    #6 0x41067d in void std::_Destroy_aux<false>::__destroy<std::vector<std::vector<MidiEvent*, std::allocator<MidiEvent*> >, std::allocator<std::vector<MidiEvent*, std::allocator<MidiEvent*> > > >*>(std::vector<std::vector<MidiEvent*, std::allocator<MidiEvent*> >, std::allocator<std::vector<MidiEvent*, std::allocator<MidiEvent*> > > >*, std::vector<std::vector<MidiEvent*, std::allocator<MidiEvent*> >, std::allocator<std::vector<MidiEvent*, std::allocator<MidiEvent*> > > >*) /usr/include/c++/4.8/bits/stl_construct.h:103
    #7 0x40f3d2 in void std::_Destroy<std::vector<std::vector<MidiEvent*, std::allocator<MidiEvent*> >, std::allocator<std::vector<MidiEvent*, std::allocator<MidiEvent*> > > >*>(std::vector<std::vector<MidiEvent*, std::allocator<MidiEvent*> >, std::allocator<std::vector<MidiEvent*, std::allocator<MidiEvent*> > > >*, std::vector<std::vector<MidiEvent*, std::allocator<MidiEvent*> >, std::allocator<std::vector<MidiEvent*, std::allocator<MidiEvent*> > > >*) /usr/include/c++/4.8/bits/stl_construct.h:126
    #8 0x40ced4 in void std::_Destroy<std::vector<std::vector<MidiEvent*, std::allocator<MidiEvent*> >, std::allocator<std::vector<MidiEvent*, std::allocator<MidiEvent*> > > >*, std::vector<std::vector<MidiEvent*, std::allocator<MidiEvent*> >, std::allocator<std::vector<MidiEvent*, std::allocator<MidiEvent*> > > > >(std::vector<std::vector<MidiEvent*, std::allocator<MidiEvent*> >, std::allocator<std::vector<MidiEvent*, std::allocator<MidiEvent*> > > >*, std::vector<std::vector<MidiEvent*, std::allocator<MidiEvent*> >, std::allocator<std::vector<MidiEvent*, std::allocator<MidiEvent*> > > >*, std::allocator<std::vector<std::vector<MidiEvent*, std::allocator<MidiEvent*> >, std::allocator<std::vector<MidiEvent*, std::allocator<MidiEvent*> > > > >&) /usr/include/c++/4.8/bits/stl_construct.h:151
    #9 0x40b657 in std::vector<std::vector<std::vector<MidiEvent*, std::allocator<MidiEvent*> >, std::allocator<std::vector<MidiEvent*, std::allocator<MidiEvent*> > > >, std::allocator<std::vector<std::vector<MidiEvent*, std::allocator<MidiEvent*> >, std::allocator<std::vector<MidiEvent*, std::allocator<MidiEvent*> > > > > >::~vector() /usr/include/c++/4.8/bits/stl_vector.h:415
    #10 0x40ab52 in MidiEventList::linkNotePairs() /home/a/Downloads/midifile-master/src-library/MidiEventList.cpp:348
    #11 0x41e632 in MidiFile::linkNotePairs() /home/a/Downloads/midifile-master/src-library/MidiFile.cpp:2232
    #12 0x403545 in convertMidiFile(MidiFile&, std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > >&) /home/a/Downloads/midifile-master/src-programs/mid2mtb.cpp:65
    #13 0x403476 in main /home/a/Downloads/midifile-master/src-programs/mid2mtb.cpp:49
    #14 0x7fa7aabe4ec4 (/lib/x86_64-linux-gnu/libc.so.6+0x21ec4)
previously allocated by thread T0 here:
    #0 0x7fa7ab4b381a (/usr/lib/x86_64-linux-gnu/libasan.so.0+0x1181a)
    #1 0x410811 in __gnu_cxx::new_allocator<std::vector<MidiEvent*, std::allocator<MidiEvent*> > >::allocate(unsigned long, void const*) /usr/include/c++/4.8/ext/new_allocator.h:104
    #2 0x40f6b8 in std::_Vector_base<std::vector<MidiEvent*, std::allocator<MidiEvent*> >, std::allocator<std::vector<MidiEvent*, std::allocator<MidiEvent*> > > >::_M_allocate(unsigned long) /usr/include/c++/4.8/bits/stl_vector.h:168
    #3 0x40d596 in std::vector<std::vector<MidiEvent*, std::allocator<MidiEvent*> >, std::allocator<std::vector<MidiEvent*, std::allocator<MidiEvent*> > > >::_M_default_append(unsigned long) /usr/include/c++/4.8/bits/vector.tcc:549
    #4 0x40b82e in std::vector<std::vector<MidiEvent*, std::allocator<MidiEvent*> >, std::allocator<std::vector<MidiEvent*, std::allocator<MidiEvent*> > > >::resize(unsigned long) /usr/include/c++/4.8/bits/stl_vector.h:667
    #5 0x40945a in MidiEventList::linkNotePairs() /home/a/Downloads/midifile-master/src-library/MidiEventList.cpp:228
    #6 0x41e632 in MidiFile::linkNotePairs() /home/a/Downloads/midifile-master/src-library/MidiFile.cpp:2232
    #7 0x403545 in convertMidiFile(MidiFile&, std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > >&) /home/a/Downloads/midifile-master/src-programs/mid2mtb.cpp:65
    #8 0x403476 in main /home/a/Downloads/midifile-master/src-programs/mid2mtb.cpp:49
    #9 0x7fa7aabe4ec4 (/lib/x86_64-linux-gnu/libc.so.6+0x21ec4)
SUMMARY: AddressSanitizer: heap-use-after-free /usr/include/c++/4.8/bits/stl_vector.h:903 std::vector<MidiEvent*, std::allocator<MidiEvent*> >::push_back(MidiEvent* const&)
Shadow bytes around the buggy address:
  0x0c0bbfffa420: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c0bbfffa430: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c0bbfffa440: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c0bbfffa450: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c0bbfffa460: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
=>0x0c0bbfffa470: fd fd fd fd fd fd fd fd fd fd[fd]fd fd fd fd fd
  0x0c0bbfffa480: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c0bbfffa490: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c0bbfffa4a0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c0bbfffa4b0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c0bbfffa4c0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:     fa
  Heap righ redzone:     fb
  Freed Heap region:     fd
  Stack left redzone:    f1
  Stack mid redzone:     f2
  Stack right redzone:   f3
  Stack partial redzone: f4
  Stack after return:    f5
  Stack use after scope: f8
  Global redzone:        f9
  Global init order:     f6
  Poisoned by user:      f7
  ASan internal:         fe
==7038== ABORTING

POC:midifile_invalid_memory_read_1.mid
This vulnerability has been assigned as CVE-2017-12656.
the MidiEventList::reserve function in src-library/MidiEventList.cpp:157 in midifile through 2017-03-16 can cause a denial of service(memory allocation error and application crash) via a crafted mid file.

./mid2mtb midifile_memory_allcation_error_1.mid

----debug info:----
terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc

Program received signal SIGABRT, Aborted.
0x00007ffff7531cc9 in __GI_raise (sig=sig@entry=6)
    at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
56	../nptl/sysdeps/unix/sysv/linux/raise.c: No such file or directory.
(gdb) bt
#0  0x00007ffff7531cc9 in __GI_raise (sig=sig@entry=6)
    at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
#1  0x00007ffff75350d8 in __GI_abort () at abort.c:89
#2  0x00007ffff7b36535 in __gnu_cxx::__verbose_terminate_handler() ()
   from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#3  0x00007ffff7b346d6 in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#4  0x00007ffff7b34703 in std::terminate() ()
   from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#5  0x00007ffff7b34922 in __cxa_throw ()
   from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#6  0x00007ffff7b34e0d in operator new(unsigned long) ()
   from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#7  0x000000000040b1a2 in __gnu_cxx::new_allocator<MidiEvent*>::allocate (
    this=0x641e50, __n=959807488)
    at /usr/include/c++/4.8/ext/new_allocator.h:104
#8  0x000000000040a2cd in std::_Vector_base<MidiEvent*, std::allocator<MidiEvent*> >::_M_allocate (this=0x641e50, __n=959807488)
    at /usr/include/c++/4.8/bits/stl_vector.h:168
#9  0x0000000000408868 in std::vector<MidiEvent*, std::allocator<MidiEvent*> >::_M_allocate_and_copy<std::move_iterator<MidiEvent**> > (this=0x641e50, 
    __n=959807488, __first=..., __last=...)
    at /usr/include/c++/4.8/bits/stl_vector.h:1138
#10 0x0000000000407c39 in std::vector<MidiEvent*, std::allocator<MidiEvent*> >::---Type <return> to continue, or q <return> to quit---
reserve (this=0x641e50, __n=959807488)
    at /usr/include/c++/4.8/bits/vector.tcc:75
#11 0x0000000000406cb8 in MidiEventList::reserve (this=0x641e50, 
    rsize=959807488) at src-library/MidiEventList.cpp:157
#12 0x000000000040f28c in MidiFile::read (this=0x7fffffffde60, input=...)
    at src-library/MidiFile.cpp:471
#13 0x000000000040e1d4 in MidiFile::read (this=0x7fffffffde60, 
    filename="/home/a/Documents/file.mid")
    at src-library/MidiFile.cpp:230
#14 0x000000000040d95b in MidiFile::MidiFile (this=0x7fffffffde60, 
    filename="/home/a/Documents/file.mid")
    at src-library/MidiFile.cpp:90
#15 0x0000000000402eb9 in main (argc=2, argv=0x7fffffffdfc8)
    at src-programs/mid2mtb.cpp:48
(gdb) disassemble 
Dump of assembler code for function __GI_raise:
   0x00007ffff7531c90 <+0>:	mov    %fs:0x2d4,%eax
   0x00007ffff7531c98 <+8>:	mov    %eax,%ecx
   0x00007ffff7531c9a <+10>:	mov    %fs:0x2d0,%esi
   0x00007ffff7531ca2 <+18>:	test   %esi,%esi
   0x00007ffff7531ca4 <+20>:	jne    0x7ffff7531cd8 <__GI_raise+72>
   0x00007ffff7531ca6 <+22>:	mov    $0xba,%eax
   0x00007ffff7531cab <+27>:	syscall 
   0x00007ffff7531cad <+29>:	mov    %eax,%ecx
   0x00007ffff7531caf <+31>:	mov    %eax,%fs:0x2d0
   0x00007ffff7531cb7 <+39>:	mov    %eax,%esi
   0x00007ffff7531cb9 <+41>:	movslq %edi,%rdx
   0x00007ffff7531cbc <+44>:	movslq %esi,%rsi
   0x00007ffff7531cbf <+47>:	movslq %ecx,%rdi
   0x00007ffff7531cc2 <+50>:	mov    $0xea,%eax
   0x00007ffff7531cc7 <+55>:	syscall 
=> 0x00007ffff7531cc9 <+57>:	cmp    $0xfffffffffffff000,%rax
   0x00007ffff7531ccf <+63>:	ja     0x7ffff7531cea <__GI_raise+90>
   0x00007ffff7531cd1 <+65>:	repz retq 
   0x00007ffff7531cd3 <+67>:	nopl   0x0(%rax,%rax,1)
   0x00007ffff7531cd8 <+72>:	test   %eax,%eax
   0x00007ffff7531cda <+74>:	jg     0x7ffff7531cb9 <__GI_raise+41>
   0x00007ffff7531cdc <+76>:	mov    %eax,%ecx
---Type <return> to continue, or q <return> to quit---q
Quit
(gdb) i r
rax            0x0	0
rbx            0x7ffff78ba868	140737346513000
rcx            0x7ffff7531cc9	140737342807241
rdx            0x6	6
rsi            0xc106	49414
rdi            0xc106	49414
rbp            0x7ffff7b948a2	0x7ffff7b948a2
rsp            0x7fffffffd6f8	0x7fffffffd6f8
r8             0xa	10
r9             0x7ffff7fda780	140737353983872
r10            0x8	8
r11            0x246	582
r12            0x7ffff0000950	140737219922256
r13            0x7fffffffdfc0	140737488347072
r14            0x0	0
r15            0x0	0
rip            0x7ffff7531cc9	0x7ffff7531cc9 <__GI_raise+57>
eflags         0x246	[ PF ZF IF ]
cs             0x33	51
ss             0x2b	43
ds             0x0	0
es             0x0	0
fs             0x0	0
---Type <return> to continue, or q <return> to quit---
gs             0x0	0
(gdb) 

==7041== ERROR: AddressSanitizer failed to allocate 0x1c9ac2000 (7678468096) bytes of LargeMmapAllocator: Cannot allocate memory
==7041== Process memory map follows:
	0x000000400000-0x000000461000	/home/a/Downloads/midifile-master/bin/mid2mtb
	0x000000660000-0x000000661000	/home/a/Downloads/midifile-master/bin/mid2mtb
	0x000000661000-0x000000665000	/home/a/Downloads/midifile-master/bin/mid2mtb
	0x00007fff7000-0x00008fff7000	
	0x00008fff7000-0x02008fff7000	
	0x02008fff7000-0x10007fff8000	
	0x600000000000-0x600400000000	
	0x600400000000-0x600400010000	
	0x600400010000-0x600600000000	
	0x600600000000-0x600600010000	
	0x600600010000-0x600800000000	
	0x600800000000-0x600800010000	
	0x600800010000-0x600c00000000	
	0x600c00000000-0x600c00010000	
	0x600c00010000-0x600e00000000	
	0x600e00000000-0x600e00010000	
	0x600e00010000-0x603600000000	
	0x603600000000-0x603600020000	
	0x603600020000-0x603e00000000	
	0x603e00000000-0x603e00020000	
	0x603e00020000-0x605200000000	
	0x605200000000-0x605200020000	
	0x605200020000-0x607200000000	
	0x607200000000-0x607200030000	
	0x607200030000-0x60a600000000	
	0x60a600000000-0x60a600090000	
	0x60a600090000-0x610000000000	
	0x610000000000-0x610000005000	
	0x7f3d8aee9000-0x7f3d8b135000	
	0x7f3d8b135000-0x7f3d8b23a000	/lib/x86_64-linux-gnu/libm-2.19.so
	0x7f3d8b23a000-0x7f3d8b439000	/lib/x86_64-linux-gnu/libm-2.19.so
	0x7f3d8b439000-0x7f3d8b43a000	/lib/x86_64-linux-gnu/libm-2.19.so
	0x7f3d8b43a000-0x7f3d8b43b000	/lib/x86_64-linux-gnu/libm-2.19.so
	0x7f3d8b43b000-0x7f3d8b43e000	/lib/x86_64-linux-gnu/libdl-2.19.so
	0x7f3d8b43e000-0x7f3d8b63d000	/lib/x86_64-linux-gnu/libdl-2.19.so
	0x7f3d8b63d000-0x7f3d8b63e000	/lib/x86_64-linux-gnu/libdl-2.19.so
	0x7f3d8b63e000-0x7f3d8b63f000	/lib/x86_64-linux-gnu/libdl-2.19.so
	0x7f3d8b63f000-0x7f3d8b658000	/lib/x86_64-linux-gnu/libpthread-2.19.so
	0x7f3d8b658000-0x7f3d8b857000	/lib/x86_64-linux-gnu/libpthread-2.19.so
	0x7f3d8b857000-0x7f3d8b858000	/lib/x86_64-linux-gnu/libpthread-2.19.so
	0x7f3d8b858000-0x7f3d8b859000	/lib/x86_64-linux-gnu/libpthread-2.19.so
	0x7f3d8b859000-0x7f3d8b85d000	
	0x7f3d8b85d000-0x7f3d8ba18000	/lib/x86_64-linux-gnu/libc-2.19.so
	0x7f3d8ba18000-0x7f3d8bc17000	/lib/x86_64-linux-gnu/libc-2.19.so
	0x7f3d8bc17000-0x7f3d8bc1b000	/lib/x86_64-linux-gnu/libc-2.19.so
	0x7f3d8bc1b000-0x7f3d8bc1d000	/lib/x86_64-linux-gnu/libc-2.19.so
	0x7f3d8bc1d000-0x7f3d8bc22000	
	0x7f3d8bc22000-0x7f3d8bc38000	/lib/x86_64-linux-gnu/libgcc_s.so.1
	0x7f3d8bc38000-0x7f3d8be37000	/lib/x86_64-linux-gnu/libgcc_s.so.1
	0x7f3d8be37000-0x7f3d8be38000	/lib/x86_64-linux-gnu/libgcc_s.so.1
	0x7f3d8be38000-0x7f3d8bf1e000	/usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19
	0x7f3d8bf1e000-0x7f3d8c11d000	/usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19
	0x7f3d8c11d000-0x7f3d8c125000	/usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19
	0x7f3d8c125000-0x7f3d8c127000	/usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19
	0x7f3d8c127000-0x7f3d8c13c000	
	0x7f3d8c13c000-0x7f3d8c164000	/usr/lib/x86_64-linux-gnu/libasan.so.0.0.0
	0x7f3d8c164000-0x7f3d8c364000	/usr/lib/x86_64-linux-gnu/libasan.so.0.0.0
	0x7f3d8c364000-0x7f3d8c365000	/usr/lib/x86_64-linux-gnu/libasan.so.0.0.0
	0x7f3d8c365000-0x7f3d8c366000	/usr/lib/x86_64-linux-gnu/libasan.so.0.0.0
	0x7f3d8c366000-0x7f3d8f0cb000	
	0x7f3d8f0cb000-0x7f3d8f0ee000	/lib/x86_64-linux-gnu/ld-2.19.so
	0x7f3d8f2bc000-0x7f3d8f2d3000	
	0x7f3d8f2d8000-0x7f3d8f2e1000	
	0x7f3d8f2e3000-0x7f3d8f2ed000	
	0x7f3d8f2ed000-0x7f3d8f2ee000	/lib/x86_64-linux-gnu/ld-2.19.so
	0x7f3d8f2ee000-0x7f3d8f2ef000	/lib/x86_64-linux-gnu/ld-2.19.so
	0x7f3d8f2ef000-0x7f3d8f2f0000	
	0x7ffd996dc000-0x7ffd996fd000	[stack]
	0x7ffd99712000-0x7ffd99714000	[vvar]
	0x7ffd99714000-0x7ffd99716000	[vdso]
	0xffffffffff600000-0xffffffffff601000	[vsyscall]
==7041== End of process memory map.
==7041== AddressSanitizer CHECK failed: ../../../../src/libsanitizer/sanitizer_common/sanitizer_posix.cc:70 "(("unable to mmap" && 0)) != (0)" (0x0, 0x0)
    #0 0x7f3d8c14e31d (/usr/lib/x86_64-linux-gnu/libasan.so.0+0x1231d)
    #1 0x7f3d8c155133 (/usr/lib/x86_64-linux-gnu/libasan.so.0+0x19133)
    #2 0x7f3d8c1576d3 (/usr/lib/x86_64-linux-gnu/libasan.so.0+0x1b6d3)
    #3 0x7f3d8c145078 (/usr/lib/x86_64-linux-gnu/libasan.so.0+0x9078)
    #4 0x7f3d8c14d849 (/usr/lib/x86_64-linux-gnu/libasan.so.0+0x11849)
    #5 0x41039a in __gnu_cxx::new_allocator<MidiEvent*>::allocate(unsigned long, void const*) /usr/include/c++/4.8/ext/new_allocator.h:104
    #6 0x40f00e in std::_Vector_base<MidiEvent*, std::allocator<MidiEvent*> >::_M_allocate(unsigned long) /usr/include/c++/4.8/bits/stl_vector.h:168
    #7 0x40c1fd in MidiEvent** std::vector<MidiEvent*, std::allocator<MidiEvent*> >::_M_allocate_and_copy<std::move_iterator<MidiEvent**> >(unsigned long, std::move_iterator<MidiEvent**>, std::move_iterator<MidiEvent**>) /usr/include/c++/4.8/bits/stl_vector.h:1138
    #8 0x40b003 in std::vector<MidiEvent*, std::allocator<MidiEvent*> >::reserve(unsigned long) /usr/include/c++/4.8/bits/vector.tcc:75
    #9 0x40921f in MidiEventList::reserve(int) /home/a/Downloads/midifile-master/src-library/MidiEventList.cpp:157
    #10 0x41698d in MidiFile::read(std::istream&) /home/a/Downloads/midifile-master/src-library/MidiFile.cpp:471
    #11 0x41513c in MidiFile::read(std::string const&) /home/a/Downloads/midifile-master/src-library/MidiFile.cpp:230
    #12 0x413d21 in MidiFile::MidiFile(std::string const&) /home/a/Downloads/midifile-master/src-library/MidiFile.cpp:90
    #13 0x403462 in main /home/a/Downloads/midifile-master/src-programs/mid2mtb.cpp:48
    #14 0x7f3d8b87eec4 (/lib/x86_64-linux-gnu/libc.so.6+0x21ec4)
    #15 0x4032f8 in _start (/home/a/Downloads/midifile-master/bin/mid2mtb+0x4032f8)

POC:midifile_memory_allcation_error_1.mid
This vulnerability has been assigned as CVE-2017-12661.
the MidiEventList::linkNotePairs function in src-library/MidiEventList.cpp in midifile through 2017-03-16 can cause a denial of service(invalid free and application crash) via a crafted mid file.

./mid2mtb midifile_invalid_free.mid

----debug info:----
Expecting 'M' at first byte in track, but found nothing.
*** Error in `/home/a/Downloads/midifile-master/bin/mid2mtb': free(): invalid pointer: 0x00000000006abf08 ***

Program received signal SIGABRT, Aborted.
0x00007ffff7531cc9 in __GI_raise (sig=sig@entry=6)
    at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
56	../nptl/sysdeps/unix/sysv/linux/raise.c: No such file or directory.
(gdb) bt
#0  0x00007ffff7531cc9 in __GI_raise (sig=sig@entry=6)
    at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
#1  0x00007ffff75350d8 in __GI_abort () at abort.c:89
#2  0x00007ffff756e394 in __libc_message (do_abort=do_abort@entry=1, 
    fmt=fmt@entry=0x7ffff767cb28 "*** Error in `%s': %s: 0x%s ***\n")
    at ../sysdeps/posix/libc_fatal.c:175
#3  0x00007ffff757a66e in malloc_printerr (ptr=<optimized out>, 
    str=0x7ffff7678c19 "free(): invalid pointer", action=1) at malloc.c:4996
#4  _int_free (av=<optimized out>, p=<optimized out>, have_lock=0)
    at malloc.c:3840
#5  0x000000000040a328 in __gnu_cxx::new_allocator<MidiEvent*>::deallocate (
    this=0x6456f0, __p=0x6abf08)
    at /usr/include/c++/4.8/ext/new_allocator.h:110
#6  0x0000000000408906 in std::_Vector_base<MidiEvent*, std::allocator<MidiEvent*> >::_M_deallocate (this=0x6456f0, __p=0x6abf08, __n=18446744073708677151)
    at /usr/include/c++/4.8/bits/stl_vector.h:174
#7  0x0000000000408787 in std::_Vector_base<MidiEvent*, std::allocator<MidiEvent*> >::~_Vector_base (this=0x6456f0, __in_chrg=<optimized out>)
    at /usr/include/c++/4.8/bits/stl_vector.h:160
#8  0x0000000000407b7b in std::vector<MidiEvent*, std::allocator<MidiEvent*> >::~vector (this=0x6456f0, __in_chrg=<optimized out>)
    at /usr/include/c++/4.8/bits/stl_vector.h:416
#9  0x000000000040c038 in std::_Destroy<std::vector<MidiEvent*, std::allocator<M---Type <return> to continue, or q <return> to quit---
idiEvent*> > > (__pointer=0x6456f0)
    at /usr/include/c++/4.8/bits/stl_construct.h:93
#10 0x000000000040b73e in std::_Destroy_aux<false>::__destroy<std::vector<MidiEvent*, std::allocator<MidiEvent*> >*> (__first=0x6456f0, __last=0x6459c0)
    at /usr/include/c++/4.8/bits/stl_construct.h:103
#11 0x000000000040ac1b in std::_Destroy<std::vector<MidiEvent*, std::allocator<MidiEvent*> >*> (__first=0x644dc0, __last=0x6459c0)
    at /usr/include/c++/4.8/bits/stl_construct.h:126
#12 0x0000000000409a3b in std::_Destroy<std::vector<MidiEvent*, std::allocator<MidiEvent*> >*, std::vector<MidiEvent*, std::allocator<MidiEvent*> > > (
    __first=0x644dc0, __last=0x6459c0)
    at /usr/include/c++/4.8/bits/stl_construct.h:151
#13 0x0000000000408363 in std::vector<std::vector<MidiEvent*, std::allocator<MidiEvent*> >, std::allocator<std::vector<MidiEvent*, std::allocator<MidiEvent*> > > >::~vector (this=0x644038, __in_chrg=<optimized out>)
    at /usr/include/c++/4.8/bits/stl_vector.h:415
#14 0x000000000040bd3c in std::_Destroy<std::vector<std::vector<MidiEvent*, std::allocator<MidiEvent*> >, std::allocator<std::vector<MidiEvent*, std::allocator<MidiEvent*> > > > > (__pointer=0x644038)
    at /usr/include/c++/4.8/bits/stl_construct.h:93
#15 0x000000000040b3ae in std::_Destroy_aux<false>::__destroy<std::vector<std::vector<MidiEvent*, std::allocator<MidiEvent*> >, std::allocator<std::vector<MidiEvent*, std::allocator<MidiEvent*> > > >*> (__first=0x644038, __last=0x6441a0)
---Type <return> to continue, or q <return> to quit---
    at /usr/include/c++/4.8/bits/stl_construct.h:103
#16 0x000000000040a603 in std::_Destroy<std::vector<std::vector<MidiEvent*, std::allocator<MidiEvent*> >, std::allocator<std::vector<MidiEvent*, std::allocator<MidiEvent*> > > >*> (__first=0x644020, __last=0x6441a0)
    at /usr/include/c++/4.8/bits/stl_construct.h:126
#17 0x0000000000409043 in std::_Destroy<std::vector<std::vector<MidiEvent*, std::allocator<MidiEvent*> >, std::allocator<std::vector<MidiEvent*, std::allocator<MidiEvent*> > > >*, std::vector<std::vector<MidiEvent*, std::allocator<MidiEvent*> >, std::allocator<std::vector<MidiEvent*, std::allocator<MidiEvent*> > > > >
    (__first=0x644020, __last=0x6441a0)
    at /usr/include/c++/4.8/bits/stl_construct.h:151
#18 0x0000000000407fe9 in std::vector<std::vector<std::vector<MidiEvent*, std::allocator<MidiEvent*> >, std::allocator<std::vector<MidiEvent*, std::allocator<MidiEvent*> > > >, std::allocator<std::vector<std::vector<MidiEvent*, std::allocator<MidiEvent*> >, std::allocator<std::vector<MidiEvent*, std::allocator<MidiEvent*> > > > > >::~vector (this=0x7fffffffdcd0, __in_chrg=<optimized out>)
    at /usr/include/c++/4.8/bits/stl_vector.h:415
#19 0x0000000000407926 in MidiEventList::linkNotePairs (this=0x641e30)
    at src-library/MidiEventList.cpp:348
#20 0x00000000004135b2 in MidiFile::linkNotePairs (this=0x7fffffffde60)
    at src-library/MidiFile.cpp:2232
#21 0x0000000000402f4c in convertMidiFile (midifile=..., 
    matlab=std::vector of length 0, capacity 100000)
---Type <return> to continue, or q <return> to quit---
    at src-programs/mid2mtb.cpp:65
#22 0x0000000000402eca in main (argc=2, argv=0x7fffffffdfc8)
    at src-programs/mid2mtb.cpp:49
(gdb) disassemble 
Dump of assembler code for function __GI_raise:
   0x00007ffff7531c90 <+0>:	mov    %fs:0x2d4,%eax
   0x00007ffff7531c98 <+8>:	mov    %eax,%ecx
   0x00007ffff7531c9a <+10>:	mov    %fs:0x2d0,%esi
   0x00007ffff7531ca2 <+18>:	test   %esi,%esi
   0x00007ffff7531ca4 <+20>:	jne    0x7ffff7531cd8 <__GI_raise+72>
   0x00007ffff7531ca6 <+22>:	mov    $0xba,%eax
   0x00007ffff7531cab <+27>:	syscall 
   0x00007ffff7531cad <+29>:	mov    %eax,%ecx
   0x00007ffff7531caf <+31>:	mov    %eax,%fs:0x2d0
   0x00007ffff7531cb7 <+39>:	mov    %eax,%esi
   0x00007ffff7531cb9 <+41>:	movslq %edi,%rdx
   0x00007ffff7531cbc <+44>:	movslq %esi,%rsi
   0x00007ffff7531cbf <+47>:	movslq %ecx,%rdi
   0x00007ffff7531cc2 <+50>:	mov    $0xea,%eax
   0x00007ffff7531cc7 <+55>:	syscall 
=> 0x00007ffff7531cc9 <+57>:	cmp    $0xfffffffffffff000,%rax
   0x00007ffff7531ccf <+63>:	ja     0x7ffff7531cea <__GI_raise+90>
   0x00007ffff7531cd1 <+65>:	repz retq 
   0x00007ffff7531cd3 <+67>:	nopl   0x0(%rax,%rax,1)
   0x00007ffff7531cd8 <+72>:	test   %eax,%eax
   0x00007ffff7531cda <+74>:	jg     0x7ffff7531cb9 <__GI_raise+41>
   0x00007ffff7531cdc <+76>:	mov    %eax,%ecx
---Type <return> to continue, or q <return> to quit---q
Quit
(gdb) i r
rax            0x0	0
rbx            0x6e	110
rcx            0x7ffff7531cc9	140737342807241
rdx            0x6	6
rsi            0xc3c9	50121
rdi            0xc3c9	50121
rbp            0x7fffffffd9d0	0x7fffffffd9d0
rsp            0x7fffffffd638	0x7fffffffd638
r8             0x3830666261363030	4048848637729845296
r9             0x69666964696d2f73	7594873701593329523
r10            0x8	8
r11            0x246	582
r12            0x7fffffffd7e0	140737488345056
r13            0x7	7
r14            0x6e	110
r15            0x7	7
rip            0x7ffff7531cc9	0x7ffff7531cc9 <__GI_raise+57>
eflags         0x246	[ PF ZF IF ]
cs             0x33	51
ss             0x2b	43
ds             0x0	0
es             0x0	0
fs             0x0	0
---Type <return> to continue, or q <return> to quit---
gs             0x0	0
(gdb) 

=================================================================
==7044== ERROR: AddressSanitizer: heap-use-after-free on address 0x605a000126b8 at pc 0x40b51d bp 0x7ffeac076a70 sp 0x7ffeac076a68
READ of size 8 at 0x605a000126b8 thread T0
    #0 0x40b51c in std::vector<MidiEvent*, std::allocator<MidiEvent*> >::push_back(MidiEvent* const&) /usr/include/c++/4.8/bits/stl_vector.h:903
    #1 0x40a391 in MidiEventList::linkNotePairs() /home/a/Downloads/midifile-master/src-library/MidiEventList.cpp:309
    #2 0x41e632 in MidiFile::linkNotePairs() /home/a/Downloads/midifile-master/src-library/MidiFile.cpp:2232
    #3 0x403545 in convertMidiFile(MidiFile&, std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > >&) /home/a/Downloads/midifile-master/src-programs/mid2mtb.cpp:65
    #4 0x403476 in main /home/a/Downloads/midifile-master/src-programs/mid2mtb.cpp:49
    #5 0x7f67d7af2ec4 (/lib/x86_64-linux-gnu/libc.so.6+0x21ec4)
    #6 0x4032f8 in _start (/home/a/Downloads/midifile-master/bin/mid2mtb+0x4032f8)
0x605a000126b8 is located 2104 bytes inside of 3072-byte region [0x605a00011e80,0x605a00012a80)
freed by thread T0 here:
    #0 0x7f67d83c19da (/usr/lib/x86_64-linux-gnu/libasan.so.0+0x119da)
    #1 0x410889 in __gnu_cxx::new_allocator<std::vector<MidiEvent*, std::allocator<MidiEvent*> > >::deallocate(std::vector<MidiEvent*, std::allocator<MidiEvent*> >*, unsigned long) /usr/include/c++/4.8/ext/new_allocator.h:110
    #2 0x40f741 in std::_Vector_base<std::vector<MidiEvent*, std::allocator<MidiEvent*> >, std::allocator<std::vector<MidiEvent*, std::allocator<MidiEvent*> > > >::_M_deallocate(std::vector<MidiEvent*, std::allocator<MidiEvent*> >*, unsigned long) /usr/include/c++/4.8/bits/stl_vector.h:174
    #3 0x40e061 in std::_Vector_base<std::vector<MidiEvent*, std::allocator<MidiEvent*> >, std::allocator<std::vector<MidiEvent*, std::allocator<MidiEvent*> > > >::~_Vector_base() /usr/include/c++/4.8/bits/stl_vector.h:160
    #4 0x40bb5d in std::vector<std::vector<MidiEvent*, std::allocator<MidiEvent*> >, std::allocator<std::vector<MidiEvent*, std::allocator<MidiEvent*> > > >::~vector() /usr/include/c++/4.8/bits/stl_vector.h:416
    #5 0x4111d1 in void std::_Destroy<std::vector<std::vector<MidiEvent*, std::allocator<MidiEvent*> >, std::allocator<std::vector<MidiEvent*, std::allocator<MidiEvent*> > > > >(std::vector<std::vector<MidiEvent*, std::allocator<MidiEvent*> >, std::allocator<std::vector<MidiEvent*, std::allocator<MidiEvent*> > > >*) /usr/include/c++/4.8/bits/stl_construct.h:93
    #6 0x41067d in void std::_Destroy_aux<false>::__destroy<std::vector<std::vector<MidiEvent*, std::allocator<MidiEvent*> >, std::allocator<std::vector<MidiEvent*, std::allocator<MidiEvent*> > > >*>(std::vector<std::vector<MidiEvent*, std::allocator<MidiEvent*> >, std::allocator<std::vector<MidiEvent*, std::allocator<MidiEvent*> > > >*, std::vector<std::vector<MidiEvent*, std::allocator<MidiEvent*> >, std::allocator<std::vector<MidiEvent*, std::allocator<MidiEvent*> > > >*) /usr/include/c++/4.8/bits/stl_construct.h:103
    #7 0x40f3d2 in void std::_Destroy<std::vector<std::vector<MidiEvent*, std::allocator<MidiEvent*> >, std::allocator<std::vector<MidiEvent*, std::allocator<MidiEvent*> > > >*>(std::vector<std::vector<MidiEvent*, std::allocator<MidiEvent*> >, std::allocator<std::vector<MidiEvent*, std::allocator<MidiEvent*> > > >*, std::vector<std::vector<MidiEvent*, std::allocator<MidiEvent*> >, std::allocator<std::vector<MidiEvent*, std::allocator<MidiEvent*> > > >*) /usr/include/c++/4.8/bits/stl_construct.h:126
    #8 0x40ced4 in void std::_Destroy<std::vector<std::vector<MidiEvent*, std::allocator<MidiEvent*> >, std::allocator<std::vector<MidiEvent*, std::allocator<MidiEvent*> > > >*, std::vector<std::vector<MidiEvent*, std::allocator<MidiEvent*> >, std::allocator<std::vector<MidiEvent*, std::allocator<MidiEvent*> > > > >(std::vector<std::vector<MidiEvent*, std::allocator<MidiEvent*> >, std::allocator<std::vector<MidiEvent*, std::allocator<MidiEvent*> > > >*, std::vector<std::vector<MidiEvent*, std::allocator<MidiEvent*> >, std::allocator<std::vector<MidiEvent*, std::allocator<MidiEvent*> > > >*, std::allocator<std::vector<std::vector<MidiEvent*, std::allocator<MidiEvent*> >, std::allocator<std::vector<MidiEvent*, std::allocator<MidiEvent*> > > > >&) /usr/include/c++/4.8/bits/stl_construct.h:151
    #9 0x40b657 in std::vector<std::vector<std::vector<MidiEvent*, std::allocator<MidiEvent*> >, std::allocator<std::vector<MidiEvent*, std::allocator<MidiEvent*> > > >, std::allocator<std::vector<std::vector<MidiEvent*, std::allocator<MidiEvent*> >, std::allocator<std::vector<MidiEvent*, std::allocator<MidiEvent*> > > > > >::~vector() /usr/include/c++/4.8/bits/stl_vector.h:415
    #10 0x40ab52 in MidiEventList::linkNotePairs() /home/a/Downloads/midifile-master/src-library/MidiEventList.cpp:348
    #11 0x41e632 in MidiFile::linkNotePairs() /home/a/Downloads/midifile-master/src-library/MidiFile.cpp:2232
    #12 0x403545 in convertMidiFile(MidiFile&, std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > >&) /home/a/Downloads/midifile-master/src-programs/mid2mtb.cpp:65
    #13 0x403476 in main /home/a/Downloads/midifile-master/src-programs/mid2mtb.cpp:49
    #14 0x7f67d7af2ec4 (/lib/x86_64-linux-gnu/libc.so.6+0x21ec4)
previously allocated by thread T0 here:
    #0 0x7f67d83c181a (/usr/lib/x86_64-linux-gnu/libasan.so.0+0x1181a)
    #1 0x410811 in __gnu_cxx::new_allocator<std::vector<MidiEvent*, std::allocator<MidiEvent*> > >::allocate(unsigned long, void const*) /usr/include/c++/4.8/ext/new_allocator.h:104
    #2 0x40f6b8 in std::_Vector_base<std::vector<MidiEvent*, std::allocator<MidiEvent*> >, std::allocator<std::vector<MidiEvent*, std::allocator<MidiEvent*> > > >::_M_allocate(unsigned long) /usr/include/c++/4.8/bits/stl_vector.h:168
    #3 0x40d596 in std::vector<std::vector<MidiEvent*, std::allocator<MidiEvent*> >, std::allocator<std::vector<MidiEvent*, std::allocator<MidiEvent*> > > >::_M_default_append(unsigned long) /usr/include/c++/4.8/bits/vector.tcc:549
    #4 0x40b82e in std::vector<std::vector<MidiEvent*, std::allocator<MidiEvent*> >, std::allocator<std::vector<MidiEvent*, std::allocator<MidiEvent*> > > >::resize(unsigned long) /usr/include/c++/4.8/bits/stl_vector.h:667
    #5 0x40945a in MidiEventList::linkNotePairs() /home/a/Downloads/midifile-master/src-library/MidiEventList.cpp:228
    #6 0x41e632 in MidiFile::linkNotePairs() /home/a/Downloads/midifile-master/src-library/MidiFile.cpp:2232
    #7 0x403545 in convertMidiFile(MidiFile&, std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > >&) /home/a/Downloads/midifile-master/src-programs/mid2mtb.cpp:65
    #8 0x403476 in main /home/a/Downloads/midifile-master/src-programs/mid2mtb.cpp:49
    #9 0x7f67d7af2ec4 (/lib/x86_64-linux-gnu/libc.so.6+0x21ec4)
SUMMARY: AddressSanitizer: heap-use-after-free /usr/include/c++/4.8/bits/stl_vector.h:903 std::vector<MidiEvent*, std::allocator<MidiEvent*> >::push_back(MidiEvent* const&)
Shadow bytes around the buggy address:
  0x0c0bbfffa480: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c0bbfffa490: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c0bbfffa4a0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c0bbfffa4b0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c0bbfffa4c0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
=>0x0c0bbfffa4d0: fd fd fd fd fd fd fd[fd]fd fd fd fd fd fd fd fd
  0x0c0bbfffa4e0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c0bbfffa4f0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c0bbfffa500: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c0bbfffa510: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c0bbfffa520: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:     fa
  Heap righ redzone:     fb
  Freed Heap region:     fd
  Stack left redzone:    f1
  Stack mid redzone:     f2
  Stack right redzone:   f3
  Stack partial redzone: f4
  Stack after return:    f5
  Stack use after scope: f8
  Global redzone:        f9
  Global init order:     f6
  Poisoned by user:      f7
  ASan internal:         fe
==7044== ABORTING

POC:midifile_invalid_free.mid
This vulnerability has been assigned as CVE-2017-12660.
the MidiEventList::linkNotePairs in src-library/MidiEventList.cpp:314 in midifile through 2017-03-16 can cause a denial of service(invalid memory read and application crash) via a crafted mid file.

./mid2mtb midifile_invalid_memory_read_2.mid

----debug info:----
Program received signal SIGSEGV, Segmentation fault.
0x00000000004074fb in MidiEventList::linkNotePairs (this=0x641e30)
    at src-library/MidiEventList.cpp:314
314	            noteon = noteons[channel][key].back();
(gdb) bt
#0  0x00000000004074fb in MidiEventList::linkNotePairs (this=0x641e30)
    at src-library/MidiEventList.cpp:314
#1  0x00000000004135b2 in MidiFile::linkNotePairs (this=0x7fffffffde50)
    at src-library/MidiFile.cpp:2232
#2  0x0000000000402f4c in convertMidiFile (midifile=..., 
    matlab=std::vector of length 0, capacity 100000)
    at src-programs/mid2mtb.cpp:65
#3  0x0000000000402eca in main (argc=2, argv=0x7fffffffdfb8)
    at src-programs/mid2mtb.cpp:49
(gdb) disassemble 0x00000000004074e8,0x000000000040750e
Dump of assembler code from 0x4074e8 to 0x40750e:
   0x00000000004074e8 <MidiEventList::linkNotePairs()+1822>:	mov    %rbx,%rsi
   0x00000000004074eb <MidiEventList::linkNotePairs()+1825>:	mov    %rax,%rdi
   0x00000000004074ee <MidiEventList::linkNotePairs()+1828>:	callq  0x408460 <std::vector<std::vector<MidiEvent*, std::allocator<MidiEvent*> >, std::allocator<std::vector<MidiEvent*, std::allocator<MidiEvent*> > > >::operator[](unsigned long)>
   0x00000000004074f3 <MidiEventList::linkNotePairs()+1833>:	mov    %rax,%rdi
   0x00000000004074f6 <MidiEventList::linkNotePairs()+1836>:	callq  0x407e2e <std::vector<MidiEvent*, std::allocator<MidiEvent*> >::back()>
=> 0x00000000004074fb <MidiEventList::linkNotePairs()+1841>:	mov    (%rax),%rax
   0x00000000004074fe <MidiEventList::linkNotePairs()+1844>:	mov    %rax,-0xa0(%rbp)
   0x0000000000407505 <MidiEventList::linkNotePairs()+1851>:	mov    -0xc8(%rbp),%eax
   0x000000000040750b <MidiEventList::linkNotePairs()+1857>:	movslq %eax,%rbx
End of assembler dump.
(gdb) i r
rax            0x3fffffff9	17179869177
rbx            0x97	151
rcx            0x644de0	6573536
rdx            0x3fffffff9	17179869177
rsi            0x7fffffffdc08	140737488346120
rdi            0x7fffffffdc40	140737488346176
rbp            0x7fffffffdd50	0x7fffffffdd50
rsp            0x7fffffffdc60	0x7fffffffdc60
r8             0x0	0
r9             0x2	2
r10            0x7ffff78b97b8	140737346508728
r11            0x7ffff7682c01	140737344187393
r12            0x402d60	4205920
r13            0x7fffffffdfb0	140737488347056
r14            0x0	0
r15            0x0	0
rip            0x4074fb	0x4074fb <MidiEventList::linkNotePairs()+1841>
eflags         0x10207	[ CF PF IF RF ]
cs             0x33	51
ss             0x2b	43
ds             0x0	0
es             0x0	0
fs             0x0	0
---Type <return> to continue, or q <return> to quit---
gs             0x0	0
(gdb) x/20x 0x3fffffff9
0x3fffffff9:	Cannot access memory at address 0x3fffffff9
(gdb) 

POC:midifile_invalid_memory_read_2.mid
This vulnerability has been assigned as CVE-2017-12658.
the MidiEventList::linkNotePairs function in src-library/MidiEventList.cpp:309 in midifile through 2017-03-16 can cause a denial of service(memory allocation error and application crash) via a crafted mid file.

./mid2mtb midifile_memory_allcation_error_2.mid

----debug info:----
Program received signal SIGSEGV, Segmentation fault.
0x000000000040b338 in __gnu_cxx::new_allocator<MidiEvent*>::construct<MidiEvent*<MidiEvent* const&> > (this=0x6b28a0, __p=0xc11)
    at /usr/include/c++/4.8/ext/new_allocator.h:120
120		{ ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
(gdb) bt
#0  0x000000000040b338 in __gnu_cxx::new_allocator<MidiEvent*>::construct<MidiEvent*<MidiEvent* const&> > (this=0x6b28a0, __p=0xc11)
    at /usr/include/c++/4.8/ext/new_allocator.h:120
#1  0x000000000040a551 in std::allocator_traits<std::allocator<MidiEvent*> >::_S_construct<MidiEvent*<MidiEvent* const&> >(std::allocator<MidiEvent*>&, std::allocator_traits<std::allocator<MidiEvent*> >::__construct_helper*, (MidiEvent*<MidiEvent* const&>&&)...) (__a=..., __p=0xc11)
    at /usr/include/c++/4.8/bits/alloc_traits.h:254
#2  0x0000000000408d8e in std::allocator_traits<std::allocator<MidiEvent*> >::construct<MidiEvent*<MidiEvent* const&> >(std::allocator<MidiEvent*>&, MidiEvent*<MidiEvent* const&>*, (MidiEvent*<MidiEvent* const&>&&)...) (__a=..., __p=0xc11)
    at /usr/include/c++/4.8/bits/alloc_traits.h:393
#3  0x0000000000407f6e in std::vector<MidiEvent*, std::allocator<MidiEvent*> >::push_back (this=0x6b28a0, __x=@0x7fffffffdcb8: 0x643c30)
    at /usr/include/c++/4.8/bits/stl_vector.h:905
#4  0x0000000000407434 in MidiEventList::linkNotePairs (this=0x641e30)
    at src-library/MidiEventList.cpp:309
#5  0x00000000004135b2 in MidiFile::linkNotePairs (this=0x7fffffffde50)
    at src-library/MidiFile.cpp:2232
#6  0x0000000000402f4c in convertMidiFile (midifile=..., 
    matlab=std::vector of length 0, capacity 100000)
    at src-programs/mid2mtb.cpp:65
#7  0x0000000000402eca in main (argc=2, argv=0x7fffffffdfb8)
---Type <return> to continue, or q <return> to quit---
    at src-programs/mid2mtb.cpp:49
(gdb) disassemble 
Dump of assembler code for function _ZN9__gnu_cxx13new_allocatorIP9MidiEventE9constructIS2_IRKS2_EEEvPT_DpOT0_:
   0x000000000040b2fe <+0>:	push   %rbp
   0x000000000040b2ff <+1>:	mov    %rsp,%rbp
   0x000000000040b302 <+4>:	push   %rbx
   0x000000000040b303 <+5>:	sub    $0x28,%rsp
   0x000000000040b307 <+9>:	mov    %rdi,-0x18(%rbp)
   0x000000000040b30b <+13>:	mov    %rsi,-0x20(%rbp)
   0x000000000040b30f <+17>:	mov    %rdx,-0x28(%rbp)
   0x000000000040b313 <+21>:	mov    -0x28(%rbp),%rax
   0x000000000040b317 <+25>:	mov    %rax,%rdi
   0x000000000040b31a <+28>:	callq  0x407f20 <std::forward<MidiEvent* const&>(std::remove_reference<MidiEvent* const&>::type&)>
   0x000000000040b31f <+33>:	mov    (%rax),%rbx
   0x000000000040b322 <+36>:	mov    -0x20(%rbp),%rax
   0x000000000040b326 <+40>:	mov    %rax,%rsi
   0x000000000040b329 <+43>:	mov    $0x8,%edi
   0x000000000040b32e <+48>:	callq  0x403f2f <operator new(unsigned long, void*)>
   0x000000000040b333 <+53>:	test   %rax,%rax
   0x000000000040b336 <+56>:	je     0x40b33b <_ZN9__gnu_cxx13new_allocatorIP9MidiEventE9constructIS2_IRKS2_EEEvPT_DpOT0_+61>
=> 0x000000000040b338 <+58>:	mov    %rbx,(%rax)
---Type <return> to continue, or q <return> to quit---
   0x000000000040b33b <+61>:	add    $0x28,%rsp
   0x000000000040b33f <+65>:	pop    %rbx
   0x000000000040b340 <+66>:	pop    %rbp
   0x000000000040b341 <+67>:	retq   
End of assembler dump.
(gdb) i r 
rax            0xc11	3089
rbx            0x643c30	6569008
rcx            0xc11	3089
rdx            0x7fffffffdcb8	140737488346296
rsi            0xc11	3089
rdi            0x8	8
rbp            0x7fffffffdbd0	0x7fffffffdbd0
rsp            0x7fffffffdba0	0x7fffffffdba0
r8             0x0	0
r9             0x2	2
r10            0x7ffff78b97b8	140737346508728
r11            0x7ffff78b9701	140737346508545
r12            0x402d60	4205920
r13            0x7fffffffdfb0	140737488347056
r14            0x0	0
r15            0x0	0
rip            0x40b338	0x40b338 <_ZN9__gnu_cxx13new_allocatorIP9MidiEventE9constructIS2_IRKS2_EEEvPT_DpOT0_+58>
eflags         0x10206	[ PF IF RF ]
cs             0x33	51
ss             0x2b	43
ds             0x0	0
es             0x0	0
---Type <return> to continue, or q <return> to quit---
fs             0x0	0
gs             0x0	0
(gdb)

=================================================================
==7030== ERROR: AddressSanitizer: heap-buffer-overflow on address 0x605a00009b88 at pc 0x40b51d bp 0x7fff6f0f91f0 sp 0x7fff6f0f91e8
READ of size 8 at 0x605a00009b88 thread T0
    #0 0x40b51c in std::vector<MidiEvent*, std::allocator<MidiEvent*> >::push_back(MidiEvent* const&) /usr/include/c++/4.8/bits/stl_vector.h:903
    #1 0x40a391 in MidiEventList::linkNotePairs() /home/a/Downloads/midifile-master/src-library/MidiEventList.cpp:309
    #2 0x41e632 in MidiFile::linkNotePairs() /home/a/Downloads/midifile-master/src-library/MidiFile.cpp:2232
    #3 0x403545 in convertMidiFile(MidiFile&, std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > >&) /home/a/Downloads/midifile-master/src-programs/mid2mtb.cpp:65
    #4 0x403476 in main /home/a/Downloads/midifile-master/src-programs/mid2mtb.cpp:49
    #5 0x7f0bc8a7cec4 (/lib/x86_64-linux-gnu/libc.so.6+0x21ec4)
    #6 0x4032f8 in _start (/home/a/Downloads/midifile-master/bin/mid2mtb+0x4032f8)
0x605a00009b88 is located 8 bytes to the right of 3072-byte region [0x605a00008f80,0x605a00009b80)
allocated by thread T0 here:
    #0 0x7f0bc934b81a (/usr/lib/x86_64-linux-gnu/libasan.so.0+0x1181a)
    #1 0x410811 in __gnu_cxx::new_allocator<std::vector<MidiEvent*, std::allocator<MidiEvent*> > >::allocate(unsigned long, void const*) /usr/include/c++/4.8/ext/new_allocator.h:104
    #2 0x40f6b8 in std::_Vector_base<std::vector<MidiEvent*, std::allocator<MidiEvent*> >, std::allocator<std::vector<MidiEvent*, std::allocator<MidiEvent*> > > >::_M_allocate(unsigned long) /usr/include/c++/4.8/bits/stl_vector.h:168
    #3 0x40d596 in std::vector<std::vector<MidiEvent*, std::allocator<MidiEvent*> >, std::allocator<std::vector<MidiEvent*, std::allocator<MidiEvent*> > > >::_M_default_append(unsigned long) /usr/include/c++/4.8/bits/vector.tcc:549
    #4 0x40b82e in std::vector<std::vector<MidiEvent*, std::allocator<MidiEvent*> >, std::allocator<std::vector<MidiEvent*, std::allocator<MidiEvent*> > > >::resize(unsigned long) /usr/include/c++/4.8/bits/stl_vector.h:667
    #5 0x40945a in MidiEventList::linkNotePairs() /home/a/Downloads/midifile-master/src-library/MidiEventList.cpp:228
    #6 0x41e632 in MidiFile::linkNotePairs() /home/a/Downloads/midifile-master/src-library/MidiFile.cpp:2232
    #7 0x403545 in convertMidiFile(MidiFile&, std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > >&) /home/a/Downloads/midifile-master/src-programs/mid2mtb.cpp:65
    #8 0x403476 in main /home/a/Downloads/midifile-master/src-programs/mid2mtb.cpp:49
    #9 0x7f0bc8a7cec4 (/lib/x86_64-linux-gnu/libc.so.6+0x21ec4)
SUMMARY: AddressSanitizer: heap-buffer-overflow /usr/include/c++/4.8/bits/stl_vector.h:903 std::vector<MidiEvent*, std::allocator<MidiEvent*> >::push_back(MidiEvent* const&)
Shadow bytes around the buggy address:
  0x0c0bbfff9320: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c0bbfff9330: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c0bbfff9340: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c0bbfff9350: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c0bbfff9360: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c0bbfff9370: fa[fa]fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0bbfff9380: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0bbfff9390: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c0bbfff93a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c0bbfff93b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c0bbfff93c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:     fa
  Heap righ redzone:     fb
  Freed Heap region:     fd
  Stack left redzone:    f1
  Stack mid redzone:     f2
  Stack right redzone:   f3
  Stack partial redzone: f4
  Stack after return:    f5
  Stack use after scope: f8
  Global redzone:        f9
  Global init order:     f6
  Poisoned by user:      f7
  ASan internal:         fe
==7030== ABORTING

POC:midifile_memory_allcation_error_2.mid
This vulnerability has been assigned as CVE-2017-12659.
the MidiEvent::unlinkEvent function in src-library/MidiEvent.cpp in midifile through 2017-03-16 can cause a denial of service(invalid memory read and application crash) via a crafted mid file.

./mid2mtb midifile_invalid_memory_read_3.mid

----debug info:----
Program received signal SIGSEGV, Segmentation fault.
0x0000000000405df8 in MidiEvent::unlinkEvent (this=0x21)
    at src-library/MidiEvent.cpp:162
162	   if (eventlink == NULL) {
(gdb) bt
#0  0x0000000000405df8 in MidiEvent::unlinkEvent (this=0x21)
    at src-library/MidiEvent.cpp:162
#1  0x0000000000405e27 in MidiEvent::unlinkEvent (this=0x642778)
    at src-library/MidiEvent.cpp:167
#2  0x00000000004073b1 in MidiEventList::linkNotePairs (this=0x641840)
    at src-library/MidiEventList.cpp:304
#3  0x00000000004135b2 in MidiFile::linkNotePairs (this=0x7fffffffde60)
    at src-library/MidiFile.cpp:2232
#4  0x0000000000402f4c in convertMidiFile (midifile=..., 
    matlab=std::vector of length 0, capacity 100000)
    at src-programs/mid2mtb.cpp:65
#5  0x0000000000402eca in main (argc=2, argv=0x7fffffffdfc8)
    at src-programs/mid2mtb.cpp:49
(gdb) disassemble 
Dump of assembler code for function MidiEvent::unlinkEvent():
   0x0000000000405de8 <+0>:	push   %rbp
   0x0000000000405de9 <+1>:	mov    %rsp,%rbp
   0x0000000000405dec <+4>:	sub    $0x20,%rsp
   0x0000000000405df0 <+8>:	mov    %rdi,-0x18(%rbp)
   0x0000000000405df4 <+12>:	mov    -0x18(%rbp),%rax
=> 0x0000000000405df8 <+16>:	mov    0x30(%rax),%rax
   0x0000000000405dfc <+20>:	test   %rax,%rax
   0x0000000000405dff <+23>:	jne    0x405e03 <MidiEvent::unlinkEvent()+27>
   0x0000000000405e01 <+25>:	jmp    0x405e27 <MidiEvent::unlinkEvent()+63>
   0x0000000000405e03 <+27>:	mov    -0x18(%rbp),%rax
   0x0000000000405e07 <+31>:	mov    0x30(%rax),%rax
   0x0000000000405e0b <+35>:	mov    %rax,-0x8(%rbp)
   0x0000000000405e0f <+39>:	mov    -0x18(%rbp),%rax
   0x0000000000405e13 <+43>:	movq   $0x0,0x30(%rax)
   0x0000000000405e1b <+51>:	mov    -0x8(%rbp),%rax
   0x0000000000405e1f <+55>:	mov    %rax,%rdi
   0x0000000000405e22 <+58>:	callq  0x405de8 <MidiEvent::unlinkEvent()>
   0x0000000000405e27 <+63>:	leaveq 
   0x0000000000405e28 <+64>:	retq   
End of assembler dump.
(gdb) i r
rax            0x21	33
rbx            0x0	0
rcx            0x0	0
rdx            0x88	136
rsi            0x11	17
rdi            0x21	33
rbp            0x7fffffffdc30	0x7fffffffdc30
rsp            0x7fffffffdc10	0x7fffffffdc10
r8             0x0	0
r9             0x6b4ee0	7032544
r10            0x7ffff78b97b8	140737346508728
r11            0x7ffff7682c70	140737344187504
r12            0x402d60	4205920
r13            0x7fffffffdfc0	140737488347072
r14            0x0	0
r15            0x0	0
rip            0x405df8	0x405df8 <MidiEvent::unlinkEvent()+16>
eflags         0x10202	[ IF RF ]
cs             0x33	51
ss             0x2b	43
ds             0x0	0
es             0x0	0
fs             0x0	0
---Type <return> to continue, or q <return> to quit---
gs             0x0	0
(gdb)

=================================================================
==7035== ERROR: AddressSanitizer: attempting free on address which was not malloc()-ed: 0x60040000cb78
    #0 0x7fa5838ca9da (/usr/lib/x86_64-linux-gnu/libasan.so.0+0x119da)
    #1 0x40f069 in __gnu_cxx::new_allocator<MidiEvent*>::deallocate(MidiEvent**, unsigned long) /usr/include/c++/4.8/ext/new_allocator.h:110
    #2 0x40c29f in std::_Vector_base<MidiEvent*, std::allocator<MidiEvent*> >::_M_deallocate(MidiEvent**, unsigned long) /usr/include/c++/4.8/bits/stl_vector.h:174
    #3 0x40c0d2 in std::_Vector_base<MidiEvent*, std::allocator<MidiEvent*> >::~_Vector_base() /usr/include/c++/4.8/bits/stl_vector.h:160
    #4 0x40aeb1 in std::vector<MidiEvent*, std::allocator<MidiEvent*> >::~vector() /usr/include/c++/4.8/bits/stl_vector.h:416
    #5 0x411549 in void std::_Destroy<std::vector<MidiEvent*, std::allocator<MidiEvent*> > >(std::vector<MidiEvent*, std::allocator<MidiEvent*> >*) /usr/include/c++/4.8/bits/stl_construct.h:93
    #6 0x410a1d in void std::_Destroy_aux<false>::__destroy<std::vector<MidiEvent*, std::allocator<MidiEvent*> >*>(std::vector<MidiEvent*, std::allocator<MidiEvent*> >*, std::vector<MidiEvent*, std::allocator<MidiEvent*> >*) /usr/include/c++/4.8/bits/stl_construct.h:103
    #7 0x40fc34 in void std::_Destroy<std::vector<MidiEvent*, std::allocator<MidiEvent*> >*>(std::vector<MidiEvent*, std::allocator<MidiEvent*> >*, std::vector<MidiEvent*, std::allocator<MidiEvent*> >*) /usr/include/c++/4.8/bits/stl_construct.h:126
    #8 0x40e0a4 in void std::_Destroy<std::vector<MidiEvent*, std::allocator<MidiEvent*> >*, std::vector<MidiEvent*, std::allocator<MidiEvent*> > >(std::vector<MidiEvent*, std::allocator<MidiEvent*> >*, std::vector<MidiEvent*, std::allocator<MidiEvent*> >*, std::allocator<std::vector<MidiEvent*, std::allocator<MidiEvent*> > >&) /usr/include/c++/4.8/bits/stl_construct.h:151
    #9 0x40bb51 in std::vector<std::vector<MidiEvent*, std::allocator<MidiEvent*> >, std::allocator<std::vector<MidiEvent*, std::allocator<MidiEvent*> > > >::~vector() /usr/include/c++/4.8/bits/stl_vector.h:415
    #10 0x4111d1 in void std::_Destroy<std::vector<std::vector<MidiEvent*, std::allocator<MidiEvent*> >, std::allocator<std::vector<MidiEvent*, std::allocator<MidiEvent*> > > > >(std::vector<std::vector<MidiEvent*, std::allocator<MidiEvent*> >, std::allocator<std::vector<MidiEvent*, std::allocator<MidiEvent*> > > >*) /usr/include/c++/4.8/bits/stl_construct.h:93
    #11 0x41067d in void std::_Destroy_aux<false>::__destroy<std::vector<std::vector<MidiEvent*, std::allocator<MidiEvent*> >, std::allocator<std::vector<MidiEvent*, std::allocator<MidiEvent*> > > >*>(std::vector<std::vector<MidiEvent*, std::allocator<MidiEvent*> >, std::allocator<std::vector<MidiEvent*, std::allocator<MidiEvent*> > > >*, std::vector<std::vector<MidiEvent*, std::allocator<MidiEvent*> >, std::allocator<std::vector<MidiEvent*, std::allocator<MidiEvent*> > > >*) /usr/include/c++/4.8/bits/stl_construct.h:103
    #12 0x40f3d2 in void std::_Destroy<std::vector<std::vector<MidiEvent*, std::allocator<MidiEvent*> >, std::allocator<std::vector<MidiEvent*, std::allocator<MidiEvent*> > > >*>(std::vector<std::vector<MidiEvent*, std::allocator<MidiEvent*> >, std::allocator<std::vector<MidiEvent*, std::allocator<MidiEvent*> > > >*, std::vector<std::vector<MidiEvent*, std::allocator<MidiEvent*> >, std::allocator<std::vector<MidiEvent*, std::allocator<MidiEvent*> > > >*) /usr/include/c++/4.8/bits/stl_construct.h:126
    #13 0x40ced4 in void std::_Destroy<std::vector<std::vector<MidiEvent*, std::allocator<MidiEvent*> >, std::allocator<std::vector<MidiEvent*, std::allocator<MidiEvent*> > > >*, std::vector<std::vector<MidiEvent*, std::allocator<MidiEvent*> >, std::allocator<std::vector<MidiEvent*, std::allocator<MidiEvent*> > > > >(std::vector<std::vector<MidiEvent*, std::allocator<MidiEvent*> >, std::allocator<std::vector<MidiEvent*, std::allocator<MidiEvent*> > > >*, std::vector<std::vector<MidiEvent*, std::allocator<MidiEvent*> >, std::allocator<std::vector<MidiEvent*, std::allocator<MidiEvent*> > > >*, std::allocator<std::vector<std::vector<MidiEvent*, std::allocator<MidiEvent*> >, std::allocator<std::vector<MidiEvent*, std::allocator<MidiEvent*> > > > >&) /usr/include/c++/4.8/bits/stl_construct.h:151
    #14 0x40b657 in std::vector<std::vector<std::vector<MidiEvent*, std::allocator<MidiEvent*> >, std::allocator<std::vector<MidiEvent*, std::allocator<MidiEvent*> > > >, std::allocator<std::vector<std::vector<MidiEvent*, std::allocator<MidiEvent*> >, std::allocator<std::vector<MidiEvent*, std::allocator<MidiEvent*> > > > > >::~vector() /usr/include/c++/4.8/bits/stl_vector.h:415
    #15 0x40ab52 in MidiEventList::linkNotePairs() /home/a/Downloads/midifile-master/src-library/MidiEventList.cpp:348
    #16 0x41e632 in MidiFile::linkNotePairs() /home/a/Downloads/midifile-master/src-library/MidiFile.cpp:2232
    #17 0x403545 in convertMidiFile(MidiFile&, std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > >&) /home/a/Downloads/midifile-master/src-programs/mid2mtb.cpp:65
    #18 0x403476 in main /home/a/Downloads/midifile-master/src-programs/mid2mtb.cpp:49
    #19 0x7fa582ffbec4 (/lib/x86_64-linux-gnu/libc.so.6+0x21ec4)
0x60040000cb78 is located 5 bytes to the right of 3-byte region [0x60040000cb70,0x60040000cb73)
allocated by thread T0 here:
    #0 0x7fa5838ca81a (/usr/lib/x86_64-linux-gnu/libasan.so.0+0x1181a)
    #1 0x41039a in __gnu_cxx::new_allocator<MidiEvent*>::allocate(unsigned long, void const*) /usr/include/c++/4.8/ext/new_allocator.h:104
    #2 0x40f00e in std::_Vector_base<MidiEvent*, std::allocator<MidiEvent*> >::_M_allocate(unsigned long) /usr/include/c++/4.8/bits/stl_vector.h:168
    #3 0x40cad5 in void std::vector<MidiEvent*, std::allocator<MidiEvent*> >::_M_emplace_back_aux<MidiEvent* const&>(MidiEvent* const&) /usr/include/c++/4.8/bits/vector.tcc:404
    #4 0x40b5bf in std::vector<MidiEvent*, std::allocator<MidiEvent*> >::push_back(MidiEvent* const&) /usr/include/c++/4.8/bits/stl_vector.h:911
    #5 0x40a391 in MidiEventList::linkNotePairs() /home/a/Downloads/midifile-master/src-library/MidiEventList.cpp:309
    #6 0x41e632 in MidiFile::linkNotePairs() /home/a/Downloads/midifile-master/src-library/MidiFile.cpp:2232
    #7 0x403545 in convertMidiFile(MidiFile&, std::vector<std::vector<double, std::allocator<double> >, std::allocator<std::vector<double, std::allocator<double> > > >&) /home/a/Downloads/midifile-master/src-programs/mid2mtb.cpp:65
    #8 0x403476 in main /home/a/Downloads/midifile-master/src-programs/mid2mtb.cpp:49
    #9 0x7fa582ffbec4 (/lib/x86_64-linux-gnu/libc.so.6+0x21ec4)
SUMMARY: AddressSanitizer: bad-free ??:0 ??
==7035== ABORTING

POC:midifile_invalid_memory_read_3.mid
This vulnerability has been assigned as CVE-2017-12657.

poc.zip

Compiling in windows

Just a heads up. When compiling in Windows using the "visual-studio" fix, the process fails. MidiMessage.cpp is missing "#include ". It has to be added manually in order to generate the library file.

p.s. - this library is awesome

EDIT: I'm getting undefined refrence errors with MidiFile inclusion

Code:

#include "MidiFile.h"
#include "Options.h"
#include <iostream>

using namespace std;

int main(int argc, char** argv)
{
    MidiFile outTrack; //Declares a midi obj named seed track

    //Controls
    int totalTracks = 60; //sets desired number of output tracks

    outTrack.read("orig.mid"); //Assigns file to outTrack obj. Contents of file is transfered to obj. File must be named "orig".

    int eventsTot = outTrack.getEventCount(0); //Gets the total number of events from original midi file

    for(int a = 1; a <= totalTracks ; a++){ //Main Track Loop. Loops through the desired number of tracks

        outTrack.addTrack();


        for(int i=0;i<=eventsTot;i++){ //Main Event Loop. Loops through each event of the orig track


        }

    }

    cout << "Hello world!" << endl;
    return 0;
}

Errors:

||=== Build: Debug in midiii (compiler: GNU GCC Compiler) ===|
obj\Debug\main.o||In function main':| C:\Users\Desktop\New folder\midiii\main.cpp|9|undefined reference toMidiFile::MidiFile()'|
C:\Users\Desktop\New folder\midiii\main.cpp|14|undefined reference to MidiFile::read(char const*)'| C:\Users\Desktop\New folder\midiii\main.cpp|16|undefined reference toMidiFile::getEventCount(int)'|
C:\Users\Desktop\New folder\midiii\main.cpp|20|undefined reference to MidiFile::addTrack()'| C:\Users\Desktop\New folder\midiii\main.cpp|31|undefined reference toMidiFile::~MidiFile()'|
C:\Users\Desktop\New folder\midiii\main.cpp|31|undefined reference to `MidiFile::~MidiFile()'|
||error: ld returned 1 exit status|
||=== Build failed: 7 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|

Receiving `reset` message > 1 byte

When reading in midi files (tested with various midi files from various different sources) and then looking at the individual messages from the MidiEvent object there always seems to be a few messages such as:

ff 51 03 07 a1 20

in particular at the start of the file, but my understanding is that a 0xff status byte means "reset" and should not be followed by any other bytes in the message (and sure enough, when I send the midi event to a softsynth it complains that it can't parse it). Is this a problem with the midifile library? Thanks

Unresolved external references when including midifile with my progam..

Hi, maybe a rookie question but i want to use the midifile source code and include it in a project but i'm having difficulties with 8 unresolved external references, similar to this one:

Severity    Code    Description Project File    Line
Error   LNK2019 unresolved external symbol "public: int __thiscall MidiFile::addEvent(int,int,class std::vector<unsigned char,class std::allocator<unsigned char> > &)" (?addEvent@MidiFile@@QAEHHHAAV?$vector@EV?$allocator@E@std@@@std@@@Z) referenced in function "void __cdecl CREATE_MIDI(void)" (?CREATE_MIDI@@YAXXZ) SPMA - Assignment 1 - 4591930 EPM   C:\Users\Paul\Desktop\Uni Stuff - YEAR 2\SOFTWARE PROGRAMMING\Assignments\Assignment 1\SPMA - Assignment 1 - 4591930 EPM\Main.obj   1

I want my midifile to be a subfolder in my project so i have #include "midifile/include/MidiFile.h" in my code and the following code i adapted a bit from the create midi files section of the midifile app on here: https://github.com/craigsapp/midifile/blob/master/src-programs/createmidifile.cpp

// FUNCTION: CREATE MIDI DATA..
void CREATE_MIDI()
{
    MidiFile outputfile;        // CREATE AN EMPTY MIDI FILE WITH ONE TRACK..
    outputfile.absoluteTicks();  // TIME INFO STORED AS ABSOLUTE TIME..
    outputfile.addTrack(number_of_melodies -1);     // ADD ALL CURRENT MELODIES (-1 AS WE ALREADY HAVE ONE TRACK)..
    vector<uchar> midievent;     // TEMP STORAGE FOR MIDI EVENTS..
    midievent.resize(3);        // SET THE ARRAY SIZE TO 3 BYTES..
    int tpq = 120;              // default value in MIDI file is 48
    outputfile.setTicksPerQuarterNote(tpq);

    // store a melody line in track 1 (track 0 left empty for conductor info)
    int i = 0;
    double actiontime = 0;      // temporary storage for MIDI event time
    midievent[2] = 64;       // store attack/release velocity for note command..

    // FOR: LOOP AROUND NUMBER OF MELODIES..
    for (counter i = 0; i < number_of_melodies; ++i)
    {
        // FOR: LOOP ROUND NUMBER OF NOTES IN EACH MELODY..
        for (counter j = 0; j < noteOUT.note_value[i].size(); ++j)
        {
            midievent[i] = 0x90;     // STORE 'NOTE-ON' COMMAND (ON MIDI CHANNEL 1)..
            midievent[i+1] = noteOUT.midi_number[i][j]; // ADD MELODY MIDI NUMBER INFO..
            outputfile.addEvent(1, actiontime, midievent);  // APPEND THE MIDI EVENT TO THE FILE..
            actiontime += tpq * noteOUT.note_length_MS[i][j];       // CALCULATE TIMINGS AND APPEND FOR EACH NOTE..     
            midievent[i] = 0x80;     // STORE 'NOTE-OFF' COMMAND (ON MIDI CHANNEL 1)..
            outputfile.addEvent(1, actiontime, midievent);  // APPEND THE MIDI EVENT TO THE FILE..
            actiontime = 0; //RESET ACTIONTIME..
        }
        // END FOR..
    }
    // END FOR..

    outputfile.sortTracks();         // ORGANISE DATA INTO CORRECT ORDER..
    outputfile.write(fileX.full_path_midi); // WRITE STANDARD MIDI FILE..
}
// END FUNCTION..

My program won't compile, I can't interperet the error messages other than they seem to mention spme of the midifile functions, like they're undefined or something, so something is amiss in my folder structures or implemenation into my program.

Any ideas what could be causing this? And how am i supposed to properly include and be able to use the midifile stuff?

Thanks,

Paul..

documentation question

Hi,
Where I can find documentation to add and manage in file creation
bars, measures, repeats, tempos 4/3 3/4 and such ,

Error parsing MIDI file

I'm having trouble loading the attached MIDI:
Good Bye.zip
The error is "Expecting 'M' at first byte in track but got '133'"
The MIDI plays fine in Foobar2000.
I checked in a HEX editor and found that in one case the command "FF 2F 00" (End of track) isn't followed directly by "MTrk" - I think that causes the error. I wonder what commands are there between the end of track and the start of the next one? Is this a normal situation or is it invalid syntax?

The 'midicat' program conflicts with sndio

Installing midifile-g20200602...
pkg-static: midifile-g20200602 conflicts with sndio-1.7.0.20201210 (installs files into the same place).  Problematic file: /usr/local/bin/midicat
*** Error code 1

Please consider renaming it, or better rename all programs by adding the prefix midifile-.

Can't compile the visual-studio project

Hi! I have VS2015, and in the developer prompt when i type

set "PLATFORM=" and "msbuild" I get the following:

C:\Users\Joel\Downloads\craigsapp-midifile-55a68db>cd visual-studio

C:\Users\Joel\Downloads\craigsapp-midifile-55a68db\visual-studio>set "PLATFORM="

C:\Users\Joel\Downloads\craigsapp-midifile-55a68db\visual-studio>msbuild
Microsoft (R) Build Engine version 14.0.23107.0
Copyright (C) Microsoft Corporation. All rights reserved.

Build started 2016-03-07 13:15:43.
The target "AfterGenerateAppxManifest" listed in an AfterTargets attribute at "C:\Program Files (x8 6)\MSBuild\Microsoft.NetNative\Microsoft.Net.CoreRuntime.targets (68,11)" does not exist in the pr oject, and will be ignored.
The target "_GeneratePrisForPortableLibraries" listed in a BeforeTargets attribute at "C:\Program F iles (x86)\MSBuild\Microsoft.NetNative\Microsoft.Net.CoreRuntime.targets (177,11)" does not exist
in the project, and will be ignored.
The target "AfterGenerateAppxManifest" listed in an AfterTargets attribute at "C:\Program Files (x8 6)\MSBuild\Microsoft.NetNative\Microsoft.NetNative.targets (126,11)" does not exist in the project , and will be ignored.
The target "AfterGenerateAppxManifest" listed in an AfterTargets attribute at "C:\Program Files (x8 6)\MSBuild\Microsoft.NetNative\Microsoft.NetNative.targets (174,11)" does not exist in the project , and will be ignored.
The target "BeforeGenerateProjectPriFile" listed in a BeforeTargets attribute at "C:\Program Files
(x86)\MSBuild\Microsoft\NuGet\Microsoft.NuGet.targets (149,61)" does not exist in the project, and
will be ignored.
Project "C:\Users\Joel\Downloads\craigsapp-midifile-55a68db\visual-studio\midifile.vcxproj" on node 1 (default targets).
InitializeBuildStatus:
Creating "Debug\midifile.tlog\unsuccessfulbuild" because "AlwaysCreate" was specified.
FinalizeBuildStatus:
Deleting file "Debug\midifile.tlog\unsuccessfulbuild".
Touching "Debug\midifile.tlog\midifile.lastbuildstate".
Done Building Project "C:\Users\Joel\Downloads\craigsapp-midifile-55a68db\visual-studio\midifile.vc xproj" (default targets).

Build succeeded.
0 Warning(s)
0 Error(s)

I'm not getting anything useful out of it :( Thanks!

Writing past the end of a vector in MidiFile::mergeTracks

In the function MidiFile::mergeTracks there are two lines near the bottom that read:

m_events[length] = NULL;
m_events.resize(length-1);

Since length is the number of tracks the first line writes past the end of the m_events vector and corrupts memory. This should be:

m_events[length-1] = NULL;
m_events.resize(length-1);

makeNoteOff wrong value (addNoteOff)

I was playing with the library and I noticed that the value for the note off was wrong.

It was previously on 90 but the correct value is 0x80 as following

void MidiMessage::makeNoteOff(int channel, int key) {
   resize(3);
   (*this)[0] = 0x80 | (0x0f & channel);    // was previously 0x90
   (*this)[1] = key & 0x7f;
   (*this)[2] = 0x00;
}

Same for

void MidiMessage::makeNoteOff(void) {
   if (!isNoteOn()) {
      resize(3);
      (*this)[0] = 0x80;                // was  previously 0x90
      (*this)[1] = 0;
      (*this)[2] = 0;
   } else {
      (*this)[2] = 0;
   }
}

In any case the library is a very good wrapper to work with MIDI. Thanks!

doTimeAnalysis not correct(durations.cpp )

First thanks the sample

double duration;

I am trying to get MIDIEvent's start time and duration
the twinkle twinkle little star mid I try to parse is from
https://www.8notes.com/scores/2904.asp?ftype=midi

below is the result
QTRS DUR TRACK NOTE

0 0.6 1 60
0 1.2 1 48
0.6 0.6 1 60
1.2 0.6 1 67
1.2 1.2 1 52
1.8 0.6 1 67
2.4 0.6 1 69
2.4 1.2 1 53
3 0.6 1 69
3.6 1.2 1 67
3.6 1.2 1 52
4.8 0.6 1 65
4.8 1.2 1 50
5.4 0.6 1 65
6 0.6 1 64
6 1.2 1 48
6.6 0.6 1 64
7.2 0.6 1 62
7.2 0.6 1 53
7.8 0.6 1 62
7.8 0.6 1 55
8.4 1.2 1 60
8.4 0.6 1 52
9 0.6 1 48
9.6 0.6 1 67
9.6 1.2 1 52
10.2 0.6 1 67
10.8 0.6 1 65
10.8 1.2 1 53
11.4 0.6 1 65
12 0.6 1 64
12 1.2 1 55
12.6 0.6 1 64
13.2 1.2 1 62
13.2 1.2 1 55
14.4 0.6 1 67
14.4 1.2 1 52
15 0.6 1 67
15.6 0.6 1 65
15.6 1.2 1 53
16.2 0.6 1 65
16.8 0.6 1 64
16.8 1.2 1 55
17.4 0.6 1 64
18 1.2 1 62
18 1.2 1 55
19.2 0.6 1 60
19.2 1.2 1 48
19.8 0.6 1 60
20.4 0.6 1 67
20.4 1.2 1 52
21 0.6 1 67
21.6 0.6 1 69
21.6 1.2 1 53
22.2 0.6 1 69
22.8 1.2 1 67
22.8 1.2 1 52
24 0.6 1 65
24 1.2 1 50
24.6 0.6 1 65
25.2 0.6 1 64
25.2 1.2 1 48
25.8 0.6 1 64
26.4 0.6 1 62
26.4 0.6 1 53
27 0.6 1 62
27 0.6 1 55
27.6 1.2 1 60
27.6 1.2 1 48

some event's start time seems wrong,could you please check this or give some advice for somewhere I can check to fix this

thx :)

How to copy tempo track,key track,and meter track from one midifile to an empty midifile?

1
I use MUSICSTD to check midifiles ,from it i can see three tracks that store tempo,key,and meter. However i'm not sure whether there were 3 tracks that actually exist in midifile or it was just one track that contains all 3 kinds of data.I tried to use the following code to do the function but it failed.

	MidiFile midifile_changed;
	midifile_changed.addTrack();
	for (int j = 0; j<midifile[0].getEventCount(); j++)
		midifile_changed.addEvent(midifile[0][j]);
	midifile_changed.addTrack();
	for (int j = 0; j<midifile[1].getEventCount(); j++)
		midifile_changed.addEvent(midifile[1][j]);

When I only copy track[0],the tempo track dosen't exist in MUSICSTD .
And when I copy both these two tracks,the tempo track exist,but sometimes it copys the sound track of the original midifile.
Not sure how to do now...

getSpelling missing case?

When I first tried using this, I got a dump and tracked it back to this:

In MidiMessage.cpp at approximately line 1089, the case 4 for base12pc, there is no case 0 contained in it. Each other has a case 1, 0/2, 3. This one omits the 0. In music output from Musescore with more or less default settings, I had a note 76 at velocity 80, which causes on exit accidental to be set to 123456.

I think all that is needed is to add case 0, e.g.

    case 2: base7pc = 2; accidental =  0; break;  // E

becomes

    case 0:   case 2: base7pc = 2; accidental =  0; break;  // E

I did not dig deeply to see if there is some underlying reason that case 4 should never have a velocity low order bits of 0, but Musescore certainly output it, so I believe it is more likely just an omission in this code.

I'm going to give a shot at submitting a PR but am rather a beginner at git, so apologies if I cannot get that to happen properly.

MidiFile::mergeTracks needs to fix track field in all events that are moved

As mergeTracks moves the event lists upward to get rid of aTrack2 it doesn't update the track field of the events being moved. The loop is

for (int i=aTrack2; i<length-1; i++) {
	m_events[i] = m_events[i+1];
}

After this loop all the events in m_events[aTrack2] on up will have track fields with their old track indices instead of their new ones.

Events are not linked

In the latest version, duration is always zero. I have tried doing time analysis first.

smf::MidiFile midi_parser(in);
midi_parser.linkNotePairs();
midi_parser.doTimeAnalysis();

In the loop:

if (event.isNoteOn()) {
  double duration = event.getDurationInSeconds();
  double start = event.seconds;
  int pitch = event.getKeyNumber();
  log("NOTE ON %i, %f, %f", pitch, start, duration);
} else if (event.isNoteOff()) {
  log("NOTE OFF %i, %f", event.getKeyNumber(), event.seconds);
}

Sample output:
NOTE ON 49, 272.571792, 0.000000
NOTE ON 53, 272.571792, 0.000000
NOTE ON 56, 272.571792, 0.000000
NOTE OFF 49, 275.013760
NOTE OFF 53, 275.013760
NOTE OFF 56, 275.013760

[Suggestion] Additional condition(s) on sortTrack...

Hello,

In 'eventcompare', we have some extra condition for sorting midi messages when there're noteon and pitchbend at the same time(tick). I think it needs to be applied to program change message too, as below:

   else if (((aevent[0] & 0xf0) == 0xe0) && ((bevent[0] & 0xf0) == 0x90)) {
      // pitch bend placed before note on messages
      return -1;
   } else if (((aevent[0] & 0xf0) == 0x90) && ((bevent[0] & 0xf0) == 0xe0)) {
      // pitch bend placed before note on messages
      return +1;
   } else if (((aevent[0] & 0xf0) == 0xc0) && ((bevent[0] & 0xf0) == 0x90)) {
       // program change placed before note on messages
       return -1;
   } else if (((aevent[0] & 0xf0) == 0x90) && ((bevent[0] & 0xf0) == 0xc0)) {
       // program change placed before note on messages
       return +1;
   } 

I have same idea about placing tempo change and signature change midi messages before any noteon message which is at the same tick, but they aren't channel specific so I'm not sure if that also should be considered or not.

Please check this and thanks in advance.

Kind regards,
Peter

Bad Midi file when velocity==10

Hello,
Thank you for this very useful library.
There is a weird issue when trying to export a Midi file if one value==10, for example the velocity.
Only with a value of 10 .... The rest works as expected from what I tested.
I attach you the Midi files. They contain a single note.
The one with the velocity==12 is fine, the one with the velocity==10 has an extra Hex value and then gets corrupted.

I had a lot of variables in my code but it looks as simple as that :

   MidiMessage midiMsg;
    midiMsg.makeNoteOn(60, 10, 0);
    outputFile.addEvent(0, 0, midiMsg);
    midiMsg.makeNoteOff(60, 10, 0);
    outputFile.addEvent(0, 2, midiMsg);

Cheers,

files.zip

Status when reading a file

When I try to read a file with the midifile.read() function ( in MidiFile.cpp ) there are three possible outcomes:

  1. File exists and is a valid MIDI file
  2. File exists and is not a valid MIDI file
  3. File doesn't exist

Cases 1 & 2 work fine but for case 3 the variable rwstatus is not set so the subsequent midifile.status() call returns the incorrect value. Was this the intention?

I can work round this by checking the return value from the read call rather than explicitly checking the status afterwards.

writeHex doesn't write to the output stream

Instead it calls printf directly, causing the output to go to the console instead of being written inside the file you pass.

My fix was to do something like this:

 // save default formatting (in the beginning of the function)
 ios init(0);
 init.copyfmt(out);

 out << hex << setw(2) << setfill('0') << right << value;

 // restore default formatting (at the end of the function)
 out.copyfmt(init);

Such a great library! Thank you very much for sharing it, and the Options class is the best I've used.

Move headers so that project is submodule-friendly

I would like to send a PR that does the following:

  1. Move the headers from include/*.h into include/midifile/*.h
  2. Change code to include as e.g. #include "midifile/MidiEvent.h"
  3. Change CMakeLists.txt file to to use target_include_directories in accordance with modern CMake style.

This will make the project more modular and friendly when used as a submodule in a larger project and is in accordance with standard procedure. Do you have any issues with this? If not then let me know and I will send a pull request. Thanks

[Suggestion] linking 'sustain on(127)' and 'sustain off(0)' midievents in a function

Hi Craig,

Currently we can get a note-off event of specific note-on event by using linkNotePairs() and getLinkedEvent(). They're very useful.
How about having similar utility function for linking a sustain-on(127) event and a sustain-off(0) event which is placed at the closest next position after the sustain-on event on the same channel, and vice versa.
In that case, some exceptional situations need to be considered. For example,

  1. In a channel which doesn't use any sustain-on event except a initial sustain-off event, we can't get linked sustain-on event of initial sustain-off event.
  2. In a channel which ends without sustain-off event(if that's possible), we can't get linked sustain-off event of the last sustain-on event.

Sustain midi messages are very important articulation especially in keyboard instruments and they logically can be considered as on-and-off pairs if they're used properly.
Perhaps you could find more midi messages can be treated as pairs.

Thanks in advance.

Kind regards,

Peter

Infinite loop

While reading a particular type of files, the library enters the infinite loop. The problem can be reproduced with a file consisting of 1025 or more null symbols. In order to get the minimal example, call python -c "with open('data.mid', 'wb') as f: f.write('\x00' * 1025)" and then open it with main.cpp as Midifile("data.mid").

It happens in the following loop:
https://github.com/craigsapp/midifile/blob/master/src/Binasc.cpp#L270
The problem occurs when getline reads an empty string. The file cursor does not move, and eof never gets reached.

I am not sure what behavior is supposed in the midi-format but it seems that one could just include && inputLine[0] != '\0' into the condition of the cycle.

My main problem now is that I can't validate input file because the infinite loop occurs before I have any ability to check status.

Allow static and shared builds

Will a shared library also be supported?

If you remove the STATIC argument from add_library() in CMakeLists.txt then the user can decide to build either a static or shared library bu supplying cmake parameter -DBUILD_SHARED_LIBS:BOOL=OFF or -DBUILD_SHARED_LIBS:BOOL=ON respectively.

Note that to support building a shared library (DLL) on Windows you will need to add the necessary __declspec(dllexport) and __declspec(dllimport) stuff for exported classes.

meta message length inconsistency

There are two ways to create meta messages using either MidiFile or MidiMessage.
The latter however does not use a VLV for the data length and the generated meta messages differ.

Furthermore MidiFile::write already adds the VLV length automatically for some messages, so it can be omitted when creating specific messages.

I think this would be useful for meta messages as well. The VLV length is really only needed for reading / writing MIDI files. When working with the data vector<uchar> contains all the information needed.

One more thing (not worth a separate issue): There is a typo in "until"...

How to get MIDI Type

Hi!

How can MIDI Type be detected (0, 1, 2)?
Like midifile.GetMIDIType()

I see that it is loaded in MidiFile::read, but seems that it is not stored as class member variable. Possible solution is to convert type variable to a member variable.

// Header parameter #1: format type
int type;
shortdata = readLittleEndian2Bytes(input);
switch (shortdata) {
	case 0:
		type = 0;
		break;
	case 1:
		type = 1;
		break;
	case 2:
		// Type-2 MIDI files should probably be allowed as well,
		// but I have never seen one in the wild to test with.
	default:
		est.Format("Error: cannot handle a type-%hu MIDI file.", shortdata);
		m_rwstatus = false; return m_rwstatus;
}

// Header parameter #2: track count
int tracks;
shortdata = readLittleEndian2Bytes(input);
if (type == 0 && shortdata != 1) {
	est.Format("Error: Type 0 MIDI file can only contain one track. Instead track count is: %hu", shortdata);
	m_rwstatus = false; return m_rwstatus;
} else {
	tracks = shortdata;
}

Memory leak in MidiFile::operator=

Hello, I am running the midifile library under ASAN (Address Sanitizer) and it is telling me that there are some memory leaks.

One of them appears to be caused by using MidiFile move assignment operator under certain circumstances. On the first line of that function there appears to be a problem:

m_events = std::move(other.m_events);

but the problem is, the pointers stored in m_events (before the move) won't be freed, and you have a leak. The vector's destructor will be called, but it won't free raw pointers. It appears that the issue goes away when I insert these lines at the top of the function:

    clear();
    if (m_events[0] != NULL) {
        delete m_events[0];
        m_events[0] = NULL;
    }
    ...

Could you please fix this? By the way, I also had a look in the MidiFile copy assignment operator and it also looks dubious, in particular you are reserving space in the m_events array and then adding new events onto the end of it, when you should probably be freeing the events in that vector, then resizing it to zero, then reserving, then finally adding new elements (note that calling reserve will not change the size of the vector).

Overall, I would really recommend avoiding to use raw pointers that own memory; the fact that you are using naked new and delete statements throughout is a red flag... I am thus honestly not surprised to find these memory leaks. If you have a pointer that owns memory the default choice is std::unique_ptr which will handle memory management for you so that you never have to worry about calling delete at the right time.

Thanks
David
P.S. I have a pull request pending about restructuring the include folders in this repository, can you please respond? :-)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.