From: Robin Gareus Date: Thu, 17 Aug 2017 16:32:49 +0000 (+0200) Subject: Check major session file format version. X-Git-Tag: 5.12~208 X-Git-Url: https://main.carlh.net/gitweb/?a=commitdiff_plain;h=22055a07c075b5fba546f0453ba93867747519c1;p=ardour.git Check major session file format version. Don't allow to load sessions created with a newer version of Ardour with an old one (no forward compatibility). --- diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index f1cb739673..aec229e11d 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -1421,8 +1421,9 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop Glib::Threads::Mutex save_state_lock; Glib::Threads::Mutex peak_cleanup_lock; - int load_options (const XMLNode&); - int load_state (std::string snapshot_name); + int load_options (const XMLNode&); + int load_state (std::string snapshot_name); + static int parse_stateful_loading_version (const std::string&); framepos_t _last_roll_location; /** the session frame time at which we last rolled, located, or changed transport direction */ diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc index 051eca4b68..ecd8071215 100644 --- a/libs/ardour/session_state.cc +++ b/libs/ardour/session_state.cc @@ -954,20 +954,12 @@ Session::load_state (string snapshot_name) } std::string version; - if (root.get_property ("version", version)) { - if (version.find ('.') != string::npos) { - /* old school version format */ - if (version[0] == '2') { - Stateful::loading_state_version = 2000; - } else { - Stateful::loading_state_version = 3000; - } - } else { - Stateful::loading_state_version = string_to(version); - } - } else { - /* no version implies very old version of Ardour */ - Stateful::loading_state_version = 1000; + root.get_property ("version", version); + Stateful::loading_state_version = parse_stateful_loading_version (version); + + if ((Stateful::loading_state_version / 1000L) > (CURRENT_SESSION_FILE_VERSION / 1000L)) { + cerr << "Session-version: " << Stateful::loading_state_version << " is not supported. Current: " << CURRENT_SESSION_FILE_VERSION << "\n"; + throw SessionException (string_compose (_("Incomatible Session Version. That session was created with a newer version of %1"), PROGRAM_NAME)); } if (Stateful::loading_state_version < CURRENT_SESSION_FILE_VERSION && _writable) { @@ -4487,11 +4479,32 @@ Session::rename (const std::string& new_name) return 0; } +int +Session::parse_stateful_loading_version (const std::string& version) +{ + if (version.empty ()) { + /* no version implies very old version of Ardour */ + return 1000; + } + + if (version.find ('.') != string::npos) { + /* old school version format */ + if (version[0] == '2') { + return 2000; + } else { + return 3000; + } + } else { + return string_to(version); + } +} + int Session::get_info_from_path (const string& xmlpath, float& sample_rate, SampleFormat& data_format, std::string& program_version) { bool found_sr = false; bool found_data_format = false; + std::string version; program_version = ""; if (!Glib::file_test (xmlpath, Glib::FILE_TEST_EXISTS)) { @@ -4517,16 +4530,24 @@ Session::get_info_from_path (const string& xmlpath, float& sample_rate, SampleFo return -1; } - /* sample rate */ + /* sample rate & version*/ xmlAttrPtr attr; for (attr = node->properties; attr; attr = attr->next) { + if (!strcmp ((const char*)attr->name, "version") && attr->children) { + version = std::string ((char*)attr->children->content); + } if (!strcmp ((const char*)attr->name, "sample-rate") && attr->children) { sample_rate = atoi ((char*)attr->children->content); found_sr = true; } } + if ((parse_stateful_loading_version(version) / 1000L) > (CURRENT_SESSION_FILE_VERSION / 1000L)) { + return -1; + } + + node = node->children; while (node != NULL) { if (!strcmp((const char*) node->name, "ProgramVersion")) { @@ -4565,7 +4586,7 @@ Session::get_info_from_path (const string& xmlpath, float& sample_rate, SampleFo xmlFreeParserCtxt(ctxt); xmlFreeDoc (doc); - return !(found_sr && found_data_format); // zero if they are both found + return (found_sr && found_data_format) ? 0 : 1; } std::string