Browse Source

UI: Fix collision of existing backup files for new scene collections

The new Scene Collection code uses the lazy creation behaviour of
OBSBasic::Load, which itself uses obs_data_create_from_json_file_safe.

The internal implementation will create a new scene collection with the
contents of an existing backup file with the same name however, thus
users would end up with a nominally "new" scene collection that
contains contents of an old backup.

This update will remove any existing backup file colliding with the
name of the new, duplicated, or renamed, scene collection and remove it
before activating it (and having OBSBasic::Load create a new one).
PatTheMav 10 months ago
parent
commit
b285a849b9
1 changed files with 18 additions and 0 deletions
  1. 18 0
      UI/window-basic-main-scene-collections.cpp

+ 18 - 0
UI/window-basic-main-scene-collections.cpp

@@ -56,6 +56,21 @@ void updateSortedSceneCollections(const OBSSceneCollectionCache &collections)
 
 	sortedSceneCollections.swap(newList);
 }
+
+void cleanBackupCollision(const OBSSceneCollection &collection)
+{
+	std::filesystem::path backupFilePath = collection.collectionFile;
+	backupFilePath.replace_extension(".json.bak");
+
+	if (std::filesystem::exists(backupFilePath)) {
+		try {
+			std::filesystem::remove(backupFilePath);
+		} catch (std::filesystem::filesystem_error &) {
+			throw std::logic_error("Failed to remove pre-existing scene collection backup file: " +
+					       backupFilePath.u8string());
+		}
+	}
+}
 } // namespace
 
 // MARK: - Main Scene Collection Management Functions
@@ -66,6 +81,7 @@ void OBSBasic::SetupNewSceneCollection(const std::string &collectionName)
 
 	OnEvent(OBS_FRONTEND_EVENT_SCENE_COLLECTION_CHANGING);
 
+	cleanBackupCollision(newCollection);
 	ActivateSceneCollection(newCollection);
 
 	blog(LOG_INFO, "Created scene collection '%s' (clean, %s)", newCollection.name.c_str(),
@@ -114,6 +130,7 @@ void OBSBasic::SetupDuplicateSceneCollection(const std::string &collectionName)
 
 	obs_data_save_json_safe(collection, newCollection.collectionFile.u8string().c_str(), "tmp", nullptr);
 
+	cleanBackupCollision(newCollection);
 	ActivateSceneCollection(newCollection);
 
 	blog(LOG_INFO, "Created scene collection '%s' (duplicate, %s)", newCollection.name.c_str(),
@@ -145,6 +162,7 @@ void OBSBasic::SetupRenameSceneCollection(const std::string &collectionName)
 
 	obs_data_save_json_safe(collection, newCollection.collectionFile.u8string().c_str(), "tmp", nullptr);
 
+	cleanBackupCollision(newCollection);
 	ActivateSceneCollection(newCollection);
 	RemoveSceneCollection(currentCollection);