From 7e2bb36104861369e8f19b8aed24d7c996ebdb1a Mon Sep 17 00:00:00 2001 From: Dave French Date: Mon, 23 Feb 2015 21:16:38 +0000 Subject: [PATCH 1/5] Added Checking of filetypes from the xml. Added a static function fileTypeFromData to the DataFile class. This opens the given file and checks the xml for its file type, as oposed to relying on the file extension --- include/DataFile.h | 5 +++++ src/core/DataFile.cpp | 39 +++++++++++++++++++++++++++++++++++++++ src/gui/FileBrowser.cpp | 3 ++- 3 files changed, 46 insertions(+), 1 deletion(-) diff --git a/include/DataFile.h b/include/DataFile.h index 1d5f71f78..86dee8675 100644 --- a/include/DataFile.h +++ b/include/DataFile.h @@ -56,6 +56,11 @@ public: DataFile( const QByteArray& data ); DataFile( Type type ); + /// \brief fileTypeFromData + /// Reads the given file and checks the xml for the type + /// returns UnknownType if the file is not reconised + static DataFile::Type fileTypeFromData( const QString fileName); + virtual ~DataFile(); QString nameWithExtension( const QString& fn ) const; diff --git a/src/core/DataFile.cpp b/src/core/DataFile.cpp index 1e79b0c08..2be3f0377 100644 --- a/src/core/DataFile.cpp +++ b/src/core/DataFile.cpp @@ -114,6 +114,45 @@ DataFile::DataFile( Type type ) : } +DataFile::Type DataFile::fileTypeFromData(const QString fileName) +{ + QString errorMsg; + DataFile::Type t; + QDomDocument doc; + + QFile inFile( fileName ); + if( !inFile.open( QIODevice::ReadOnly ) ) + { + return DataFile::Type::UnknownType; + } + + QByteArray data = inFile.readAll(); + inFile.close(); + + int line = -1, col = -1; + if( !doc.setContent( data, &errorMsg, &line, &col ) ) + { + // parsing failed? then try to uncompress data + QByteArray uncompressed = qUncompress( data ); + if( !uncompressed.isEmpty() ) + { + if( doc.setContent( uncompressed, &errorMsg, &line, &col ) ) + { + line = col = -1; + } + } + if( line >= 0 && col >= 0 ) + { + return DataFile::Type::UnknownType; + } + } + + QDomElement root = doc.documentElement(); + t = type( root.attribute( "type" ) ); + + return t; +} + diff --git a/src/gui/FileBrowser.cpp b/src/gui/FileBrowser.cpp index 0d19ec6aa..4253ce55d 100644 --- a/src/gui/FileBrowser.cpp +++ b/src/gui/FileBrowser.cpp @@ -459,7 +459,8 @@ void FileBrowserTreeWidget::mousePressEvent(QMouseEvent * me ) } else if( f->type() != FileItem::VstPluginFile && ( f->handling() == FileItem::LoadAsPreset || - f->handling() == FileItem::LoadByPlugin ) ) + f->handling() == FileItem::LoadByPlugin ) + && DataFile::fileTypeFromData( f->fullName() ) == DataFile::Type::InstrumentTrackSettings ) { m_previewPlayHandle = new PresetPreviewPlayHandle( f->fullName(), f->handling() == FileItem::LoadByPlugin ); } From 09232ce6e81bdd3798fb2fdba92c662bb4ba4636 Mon Sep 17 00:00:00 2001 From: Dave French Date: Wed, 25 Feb 2015 21:30:45 +0000 Subject: [PATCH 2/5] Begginings of XML validation --- include/DataFile.h | 7 +-- include/PresetPreviewPlayHandle.h | 2 +- src/core/DataFile.cpp | 87 +++++++++++++++------------- src/core/PresetPreviewPlayHandle.cpp | 22 +++++-- src/gui/FileBrowser.cpp | 15 ++++- 5 files changed, 80 insertions(+), 53 deletions(-) diff --git a/include/DataFile.h b/include/DataFile.h index 86dee8675..6f01ffc5e 100644 --- a/include/DataFile.h +++ b/include/DataFile.h @@ -56,13 +56,10 @@ public: DataFile( const QByteArray& data ); DataFile( Type type ); - /// \brief fileTypeFromData - /// Reads the given file and checks the xml for the type - /// returns UnknownType if the file is not reconised - static DataFile::Type fileTypeFromData( const QString fileName); - virtual ~DataFile(); + bool validate( QString extension ); + QString nameWithExtension( const QString& fn ) const; void write( QTextStream& strm ); diff --git a/include/PresetPreviewPlayHandle.h b/include/PresetPreviewPlayHandle.h index 6dd8c8e19..0ebed9c89 100644 --- a/include/PresetPreviewPlayHandle.h +++ b/include/PresetPreviewPlayHandle.h @@ -35,7 +35,7 @@ class PreviewTrackContainer; class EXPORT PresetPreviewPlayHandle : public PlayHandle { public: - PresetPreviewPlayHandle( const QString& presetFile, bool loadByPlugin = false ); + PresetPreviewPlayHandle( const QString& presetFile, bool loadByPlugin = false, DataFile *dataFile = 0 ); virtual ~PresetPreviewPlayHandle(); virtual void play( sampleFrame* buffer ); diff --git a/src/core/DataFile.cpp b/src/core/DataFile.cpp index 2be3f0377..85d7f0e35 100644 --- a/src/core/DataFile.cpp +++ b/src/core/DataFile.cpp @@ -114,45 +114,6 @@ DataFile::DataFile( Type type ) : } -DataFile::Type DataFile::fileTypeFromData(const QString fileName) -{ - QString errorMsg; - DataFile::Type t; - QDomDocument doc; - - QFile inFile( fileName ); - if( !inFile.open( QIODevice::ReadOnly ) ) - { - return DataFile::Type::UnknownType; - } - - QByteArray data = inFile.readAll(); - inFile.close(); - - int line = -1, col = -1; - if( !doc.setContent( data, &errorMsg, &line, &col ) ) - { - // parsing failed? then try to uncompress data - QByteArray uncompressed = qUncompress( data ); - if( !uncompressed.isEmpty() ) - { - if( doc.setContent( uncompressed, &errorMsg, &line, &col ) ) - { - line = col = -1; - } - } - if( line >= 0 && col >= 0 ) - { - return DataFile::Type::UnknownType; - } - } - - QDomElement root = doc.documentElement(); - t = type( root.attribute( "type" ) ); - - return t; -} - @@ -202,6 +163,54 @@ DataFile::~DataFile() +bool DataFile::validate( QString extension ) +{ + bool result = false; + switch( m_type ) + { + case Type::SongProject: + if( extension == "mmp" || extension == "mmpz" ) + { + result = true; + } + break; + case Type::SongProjectTemplate: + if( extension == "mpt" ) + { + result = true; + } + break; + case Type::InstrumentTrackSettings: + if ( extension == "xpf" || extension == "xml" ) + { + result = true; + } + break; + case Type::UnknownType: + if (! ( extension == "mmp" || extension == "mpt" || extension == "mmpz" || + extension == "xpf" || extension == "xml" || + ( extension == "xiz" && Engine::pluginFileHandling().contains( extension ) ) || + extension == "sf2" || extension == "pat" || extension == "mid" || + extension == "flp" || extension == "dll" + ) ) + { + result = true; + } + if( extension == "wav" || extension == "ogg" || + extension == "ds" ) + { + result = true; + } + break; + default: + return true; + } + return result; +} + + + + QString DataFile::nameWithExtension( const QString & _fn ) const { switch( type() ) diff --git a/src/core/PresetPreviewPlayHandle.cpp b/src/core/PresetPreviewPlayHandle.cpp index 09ebaca16..658160098 100644 --- a/src/core/PresetPreviewPlayHandle.cpp +++ b/src/core/PresetPreviewPlayHandle.cpp @@ -111,7 +111,7 @@ PreviewTrackContainer * PresetPreviewPlayHandle::s_previewTC; -PresetPreviewPlayHandle::PresetPreviewPlayHandle( const QString & _preset_file, bool _load_by_plugin ) : +PresetPreviewPlayHandle::PresetPreviewPlayHandle( const QString & _preset_file, bool _load_by_plugin, DataFile *dataFile ) : PlayHandle( TypePresetPreviewHandle ), m_previewNote( NULL ) { @@ -144,22 +144,34 @@ PresetPreviewPlayHandle::PresetPreviewPlayHandle( const QString & _preset_file, } else { - DataFile dataFile( _preset_file ); + bool dataFileCreated = false; + if( dataFile == 0 ) + { + dataFile = new DataFile( _preset_file ); + dataFileCreated = true; + } + + DataFile data(*dataFile); + // vestige previews are bug prone; fallback on 3xosc with volume of 0 // without an instrument in preview track, it will segfault - if(dataFile.content().elementsByTagName( "vestige" ).length() == 0 ) + if(data.content().elementsByTagName( "vestige" ).length() == 0 ) { s_previewTC->previewInstrumentTrack()-> loadTrackSpecificSettings( - dataFile.content().firstChild().toElement() ); + data.content().firstChild().toElement() ); } else { s_previewTC->previewInstrumentTrack()->loadInstrument("tripleoscillator"); s_previewTC->previewInstrumentTrack()->setVolume( 0 ); } + if( dataFileCreated ) + { + delete dataFile; + } } - + dataFile = 0; // make sure, our preset-preview-track does not appear in any MIDI- // devices list, so just disable receiving/sending MIDI-events at all s_previewTC->previewInstrumentTrack()-> diff --git a/src/gui/FileBrowser.cpp b/src/gui/FileBrowser.cpp index 4253ce55d..f865fab19 100644 --- a/src/gui/FileBrowser.cpp +++ b/src/gui/FileBrowser.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include "FileBrowser.h" #include "BBTrackContainer.h" @@ -459,10 +460,18 @@ void FileBrowserTreeWidget::mousePressEvent(QMouseEvent * me ) } else if( f->type() != FileItem::VstPluginFile && ( f->handling() == FileItem::LoadAsPreset || - f->handling() == FileItem::LoadByPlugin ) - && DataFile::fileTypeFromData( f->fullName() ) == DataFile::Type::InstrumentTrackSettings ) + f->handling() == FileItem::LoadByPlugin ) ) { - m_previewPlayHandle = new PresetPreviewPlayHandle( f->fullName(), f->handling() == FileItem::LoadByPlugin ); + DataFile dataFile( f->fullName() ); + if( !dataFile.validate( f->extension() ) ) + { + QMessageBox::warning( 0, "Corrupt File", + "File : " + f->fullName() + " contains invalid data", + QMessageBox::Ok, QMessageBox::NoButton ); + m_pphMutex.unlock(); + return; + } + m_previewPlayHandle = new PresetPreviewPlayHandle( f->fullName(), f->handling() == FileItem::LoadByPlugin, &dataFile ); } if( m_previewPlayHandle != NULL ) { From 7f72be6f69b048aa044c7d48e0aba7d96f7b9009 Mon Sep 17 00:00:00 2001 From: Dave French Date: Thu, 26 Feb 2015 20:07:45 +0000 Subject: [PATCH 3/5] Validates Xml files opened with the main menu --- src/core/DataFile.cpp | 13 ++++++------- src/core/Song.cpp | 2 +- src/gui/FileBrowser.cpp | 4 ++-- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/core/DataFile.cpp b/src/core/DataFile.cpp index 85d7f0e35..06afd9bc3 100644 --- a/src/core/DataFile.cpp +++ b/src/core/DataFile.cpp @@ -165,25 +165,24 @@ DataFile::~DataFile() bool DataFile::validate( QString extension ) { - bool result = false; switch( m_type ) { case Type::SongProject: if( extension == "mmp" || extension == "mmpz" ) { - result = true; + return true; } break; case Type::SongProjectTemplate: if( extension == "mpt" ) { - result = true; + return true; } break; case Type::InstrumentTrackSettings: if ( extension == "xpf" || extension == "xml" ) { - result = true; + return true; } break; case Type::UnknownType: @@ -194,18 +193,18 @@ bool DataFile::validate( QString extension ) extension == "flp" || extension == "dll" ) ) { - result = true; + return true; } if( extension == "wav" || extension == "ogg" || extension == "ds" ) { - result = true; + return true; } break; default: return true; } - return result; + return false; } diff --git a/src/core/Song.cpp b/src/core/Song.cpp index 7942b6452..0f072076e 100644 --- a/src/core/Song.cpp +++ b/src/core/Song.cpp @@ -924,7 +924,7 @@ void Song::loadProject( const QString & _file_name ) DataFile dataFile( m_fileName ); // if file could not be opened, head-node is null and we create // new project - if( dataFile.head().isNull() ) + if( !dataFile.validate( _file_name.right(_file_name.lastIndexOf(".") ) ) ) { return; } diff --git a/src/gui/FileBrowser.cpp b/src/gui/FileBrowser.cpp index f865fab19..50059734c 100644 --- a/src/gui/FileBrowser.cpp +++ b/src/gui/FileBrowser.cpp @@ -465,8 +465,8 @@ void FileBrowserTreeWidget::mousePressEvent(QMouseEvent * me ) DataFile dataFile( f->fullName() ); if( !dataFile.validate( f->extension() ) ) { - QMessageBox::warning( 0, "Corrupt File", - "File : " + f->fullName() + " contains invalid data", + QMessageBox::warning( 0, tr ( "Error" ), + f->fullName() + " " + tr( "does not appear to be a valid") + " " + f->extension(), QMessageBox::Ok, QMessageBox::NoButton ); m_pphMutex.unlock(); return; From de74760586211f949bbd90527b3afded0bfea32e Mon Sep 17 00:00:00 2001 From: Dave French Date: Thu, 26 Feb 2015 20:45:34 +0000 Subject: [PATCH 4/5] xml validation, removed redundant boxing, unknown files fail validation, caught a inverse logic error --- src/core/DataFile.cpp | 2 +- src/core/PresetPreviewPlayHandle.cpp | 6 ++---- src/core/Song.cpp | 2 +- src/gui/FileBrowser.cpp | 3 ++- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/core/DataFile.cpp b/src/core/DataFile.cpp index 06afd9bc3..15fa5abde 100644 --- a/src/core/DataFile.cpp +++ b/src/core/DataFile.cpp @@ -202,7 +202,7 @@ bool DataFile::validate( QString extension ) } break; default: - return true; + return false; } return false; } diff --git a/src/core/PresetPreviewPlayHandle.cpp b/src/core/PresetPreviewPlayHandle.cpp index 658160098..a91681758 100644 --- a/src/core/PresetPreviewPlayHandle.cpp +++ b/src/core/PresetPreviewPlayHandle.cpp @@ -151,15 +151,13 @@ PresetPreviewPlayHandle::PresetPreviewPlayHandle( const QString & _preset_file, dataFileCreated = true; } - DataFile data(*dataFile); - // vestige previews are bug prone; fallback on 3xosc with volume of 0 // without an instrument in preview track, it will segfault - if(data.content().elementsByTagName( "vestige" ).length() == 0 ) + if(dataFile->content().elementsByTagName( "vestige" ).length() == 0 ) { s_previewTC->previewInstrumentTrack()-> loadTrackSpecificSettings( - data.content().firstChild().toElement() ); + dataFile->content().firstChild().toElement() ); } else { diff --git a/src/core/Song.cpp b/src/core/Song.cpp index 0f072076e..7e5d36e8b 100644 --- a/src/core/Song.cpp +++ b/src/core/Song.cpp @@ -924,7 +924,7 @@ void Song::loadProject( const QString & _file_name ) DataFile dataFile( m_fileName ); // if file could not be opened, head-node is null and we create // new project - if( !dataFile.validate( _file_name.right(_file_name.lastIndexOf(".") ) ) ) + if( dataFile.validate( _file_name.right(_file_name.lastIndexOf(".") ) ) ) { return; } diff --git a/src/gui/FileBrowser.cpp b/src/gui/FileBrowser.cpp index 50059734c..942e1f360 100644 --- a/src/gui/FileBrowser.cpp +++ b/src/gui/FileBrowser.cpp @@ -466,7 +466,8 @@ void FileBrowserTreeWidget::mousePressEvent(QMouseEvent * me ) if( !dataFile.validate( f->extension() ) ) { QMessageBox::warning( 0, tr ( "Error" ), - f->fullName() + " " + tr( "does not appear to be a valid") + " " + f->extension(), + f->fullName() + " " + tr( "does not appear to be a valid" ) + " " + f->extension() + + " " + tr( "file" ), QMessageBox::Ok, QMessageBox::NoButton ); m_pphMutex.unlock(); return; From 3829990e00f6e8b112e55374687595a79de02cd3 Mon Sep 17 00:00:00 2001 From: Dave French Date: Sun, 8 Mar 2015 14:48:23 +0000 Subject: [PATCH 5/5] Commented DataFile::validate in headder --- include/DataFile.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/DataFile.h b/include/DataFile.h index 6f01ffc5e..c8586fd9d 100644 --- a/include/DataFile.h +++ b/include/DataFile.h @@ -58,6 +58,10 @@ public: virtual ~DataFile(); + /// + /// \brief validate + /// performs basic validation, compared to file extension. + /// bool validate( QString extension ); QString nameWithExtension( const QString& fn ) const;