summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien Zammit <damien@zamaudio.com>2014-04-29 06:44:40 +1000
committerDamien Zammit <damien@zamaudio.com>2014-04-29 06:48:29 +1000
commit2f6065b32c26dba0f7ea5da5c980d0406c36cc55 (patch)
tree32e72f96535480bbb6ae346e69866c03a61a6b3a
parentf5276a104c2d544cf537db9e9b8de9022de7ad56 (diff)
Fixed problem where importing invalid midi files caused crash.3.5.380
-rw-r--r--gtk2_ardour/sfdb_ui.cc8
-rw-r--r--libs/ardour/ardour/smf_source.h1
-rw-r--r--libs/ardour/smf_source.cc11
-rw-r--r--libs/evoral/evoral/SMF.hpp1
-rw-r--r--libs/evoral/src/SMF.cpp22
5 files changed, 39 insertions, 4 deletions
diff --git a/gtk2_ardour/sfdb_ui.cc b/gtk2_ardour/sfdb_ui.cc
index 4b89cd51fe..6e08617af2 100644
--- a/gtk2_ardour/sfdb_ui.cc
+++ b/gtk2_ardour/sfdb_ui.cc
@@ -279,7 +279,7 @@ SoundFileBox::setup_labels (const string& filename)
string error_msg;
- if (SMFSource::safe_midi_file_extension (path)) {
+ if (SMFSource::valid_midi_file (path)) {
boost::shared_ptr<SMFSource> ms =
boost::dynamic_pointer_cast<SMFSource> (
@@ -404,7 +404,7 @@ SoundFileBox::audition ()
boost::shared_ptr<Region> r;
- if (SMFSource::safe_midi_file_extension (path)) {
+ if (SMFSource::valid_midi_file (path)) {
boost::shared_ptr<SMFSource> ms =
boost::dynamic_pointer_cast<SMFSource> (
@@ -1307,7 +1307,7 @@ SoundFileOmega::reset_options ()
/* See if we are thinking about importing any MIDI files */
vector<string>::iterator i = paths.begin ();
- while (i != paths.end() && SMFSource::safe_midi_file_extension (*i) == false) {
+ while (i != paths.end() && SMFSource::valid_midi_file (*i) == false) {
++i;
}
bool const have_a_midi_file = (i != paths.end ());
@@ -1535,7 +1535,7 @@ SoundFileOmega::check_info (const vector<string>& paths, bool& same_size, bool&
src_needed = true;
}
- } else if (SMFSource::safe_midi_file_extension (*i)) {
+ } else if (SMFSource::valid_midi_file (*i)) {
Evoral::SMF reader;
reader.open(*i);
diff --git a/libs/ardour/ardour/smf_source.h b/libs/ardour/ardour/smf_source.h
index 9c0a78f282..a068a3e385 100644
--- a/libs/ardour/ardour/smf_source.h
+++ b/libs/ardour/ardour/smf_source.h
@@ -77,6 +77,7 @@ public:
void ensure_disk_file ();
static bool safe_midi_file_extension (const std::string& path);
+ static bool valid_midi_file (const std::string& path);
void prevent_deletion ();
diff --git a/libs/ardour/smf_source.cc b/libs/ardour/smf_source.cc
index d52923c302..c3bc78c83d 100644
--- a/libs/ardour/smf_source.cc
+++ b/libs/ardour/smf_source.cc
@@ -34,6 +34,7 @@
#include <glibmm/fileutils.h>
#include "evoral/Control.hpp"
+#include "evoral/evoral/SMF.hpp"
#include "ardour/event_type_map.h"
#include "ardour/midi_model.h"
@@ -48,6 +49,7 @@
using namespace ARDOUR;
using namespace Glib;
using namespace PBD;
+using namespace Evoral;
/** Constructor used for new internal-to-session files. File cannot exist. */
SMFSource::SMFSource (Session& s, const string& path, Source::Flag flags)
@@ -497,6 +499,15 @@ SMFSource::mark_midi_streaming_write_completed (Evoral::Sequence<Evoral::Musical
}
bool
+SMFSource::valid_midi_file (const string& file)
+{
+ if (safe_midi_file_extension (file) ) {
+ return (SMF::test (file) );
+ }
+ return false;
+}
+
+bool
SMFSource::safe_midi_file_extension (const string& file)
{
static regex_t compiled_pattern;
diff --git a/libs/evoral/evoral/SMF.hpp b/libs/evoral/evoral/SMF.hpp
index 8bd05444c4..02d0710409 100644
--- a/libs/evoral/evoral/SMF.hpp
+++ b/libs/evoral/evoral/SMF.hpp
@@ -50,6 +50,7 @@ public:
SMF() : _smf(0), _smf_track(0), _empty(true) {};
virtual ~SMF();
+ static bool test(const std::string& path);
int open(const std::string& path, int track=1) THROW_FILE_ERROR;
int create(const std::string& path, int track=1, uint16_t ppqn=19200) THROW_FILE_ERROR;
void close() THROW_FILE_ERROR;
diff --git a/libs/evoral/src/SMF.cpp b/libs/evoral/src/SMF.cpp
index b84507818c..6557a01b80 100644
--- a/libs/evoral/src/SMF.cpp
+++ b/libs/evoral/src/SMF.cpp
@@ -67,6 +67,28 @@ SMF::seek_to_track(int track)
}
}
+/** Attempt to open the SMF file just to see if it is valid.
+ *
+ * \return true on success
+ * false on failure
+ */
+bool
+SMF::test(const std::string& path)
+{
+ PBD::StdioFileDescriptor d (path, "r");
+ FILE* f = d.allocate ();
+ if (f == 0) {
+ return false;
+ }
+
+ smf_t* test_smf;
+ if ((test_smf = smf_load (f)) == NULL) {
+ return false;
+ }
+ smf_delete (test_smf);
+ return true;
+}
+
/** Attempt to open the SMF file for reading and/or writing.
*
* \return 0 on success