craigsapp / midifile Goto Github PK
View Code? Open in Web Editor NEWC++ classes for reading/writing Standard MIDI Files
Home Page: http://midifile.sapp.org
License: BSD 2-Clause "Simplified" License
C++ classes for reading/writing Standard MIDI Files
Home Page: http://midifile.sapp.org
License: BSD 2-Clause "Simplified" License
when i want to read file context {0x00 0x00 .....}
MidiFile::read
int Binasc::writeToBinary
will while(1)
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.
Git pull is for getting the repository if you already have the repository. Git clone, on the other hand, fetches the repository from Github.
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?
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?
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);
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.
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.
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.
I found I could use two more boolean tests, one for key signature and one for time signature, and added following the layout of the others, and offer the code if it is useful (PR following in a moment).
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 to
MidiFile::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 to
MidiFile::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 to
MidiFile::~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)) ===|
Line 781 in d1c2139
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
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..
Hi,
Where I can find documentation to add and manage in file creation
bars, measures, repeats, tempos 4/3 3/4 and such ,
hello, When reading a midi file, if tempo changes, the absolute time of midi event will go wrong. How can I solve this problem?
I want to delete some events in a track!But I don't know how to do it lol.
Please Help! ;D
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?
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-
.
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!
I get errors running make library
this is the output:
http://pastebin.com/wHnu6P60
I saw no requirments for installing (like dependencies and other libraries it depends on)
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);
It looks like end-of-track events are ignored, and a final end-of-track is stuck on with no delta time before it.
Is that, in fact, how it works?
Currently the project doesn't install anything.
Hello,
The codes below are making error in destructor randomly in main() function.
MidiFile midifile("test.mid");
midifile.doTimeAnalysis();
return 0;
When I comment out the second line(doTimeAnalysis), there's no error.
Please refer to the attached project and screenshots for repro.
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!
First thanks the sample
midifile/src-programs/durations.cpp
Line 55 in 462f55a
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
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 :)
http://midifile.sapp.org/class/MidiEvent/
The .time
public variable doesn't seem to exist. but .tick
exists as under http://midifile.sapp.org/class/MidiFile/#addEvent
Perhaps a typo?
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...
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.
Hi Craig,
using MidiFile::read on the attached file, I'm getting an error message from extractMidiData :
"Error: running status not permitted with meta and sysex event."
I can't find any midi player unable to play this file.
Please check if there's any problem. Thanks in advance.
Regards,
Peter
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.
I try to set different TPQ with method setTPQ, but the actual ticks do not change accordingly. I want to keep the physical time and change the TPQ at the same time. How can I make it?
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
this is so that this library can be used in a real time audio context
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
midifile/src/Options.cpp:1127:25: warning: result of comparison of constant -1 with expression of type 'char' is always false [-Wtautological-constant-out-of-range-compare]
if (optionType == -1) { // suppressed --options option
~~~~~~~~~~ ^ ~~
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,
When I try to read a file with the midifile.read()
function ( in MidiFile.cpp ) there are three possible outcomes:
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.
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.
Midi events that have a key(pitch) of 10 aren't output correctly to binary midi files. This is because the fstream
isn't opened with the ios::binary
flag for output. The stream interprets decimal 10 as a line feed and converts it to CRLF.
I would like to send a PR that does the following:
include/*.h
into include/midifile/*.h
#include "midifile/MidiEvent.h"
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
oooooh Thank You
You are awesome!
โฅ
Rama
PS: Thank you!
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,
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
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
.
Lines 441 to 449 in d1c2139
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.
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"...
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;
}
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? :-)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.