From df3b9a9478d8566b7456e7f6142b0082b5b400ff Mon Sep 17 00:00:00 2001 From: Mike Conley Date: Tue, 17 Sep 2024 13:54:28 +0000 Subject: [PATCH] Bug 1914940 - Do not back up permissions or content prefs databases if the browser is not configured to remember history, or to clear history on shutdown. r=backup-reviewers,kpatenio Differential Revision: https://phabricator.services.mozilla.com/D221552 --- .../PreferencesBackupResource.sys.mjs | 14 ++- .../test_PreferencesBackupResource.js | 119 ++++++++++++++++++ 2 files changed, 127 insertions(+), 6 deletions(-) diff --git a/browser/components/backup/resources/PreferencesBackupResource.sys.mjs b/browser/components/backup/resources/PreferencesBackupResource.sys.mjs index 65aaa5a8c799..728409e08914 100644 --- a/browser/components/backup/resources/PreferencesBackupResource.sys.mjs +++ b/browser/components/backup/resources/PreferencesBackupResource.sys.mjs @@ -39,12 +39,14 @@ export class PreferencesBackupResource extends BackupResource { ]; await BackupResource.copyFiles(profilePath, stagingPath, simpleCopyFiles); - const sqliteDatabases = ["permissions.sqlite", "content-prefs.sqlite"]; - await BackupResource.copySqliteDatabases( - profilePath, - stagingPath, - sqliteDatabases - ); + if (BackupResource.canBackupHistory()) { + const sqliteDatabases = ["permissions.sqlite", "content-prefs.sqlite"]; + await BackupResource.copySqliteDatabases( + profilePath, + stagingPath, + sqliteDatabases + ); + } // prefs.js is a special case - we have a helper function to flush the // current prefs state to disk off of the main thread. diff --git a/browser/components/backup/tests/xpcshell/test_PreferencesBackupResource.js b/browser/components/backup/tests/xpcshell/test_PreferencesBackupResource.js index de8ca3a16fb7..80bc20d53e4e 100644 --- a/browser/components/backup/tests/xpcshell/test_PreferencesBackupResource.js +++ b/browser/components/backup/tests/xpcshell/test_PreferencesBackupResource.js @@ -151,6 +151,125 @@ add_task(async function test_backup() { sandbox.restore(); }); +/** + * Tests that the backup method does not copy the permissions or content prefs + * databases if the browser is configured to not save history - either while + * running, or to clear it at shutdown. + */ +add_task(async function test_backup_no_saved_history() { + let preferencesBackupResource = new PreferencesBackupResource(); + let sourcePath = await IOUtils.createUniqueDirectory( + PathUtils.tempDir, + "PreferencesBackupResource-source-test" + ); + let stagingPath = await IOUtils.createUniqueDirectory( + PathUtils.tempDir, + "PreferencesBackupResource-staging-test" + ); + + let sandbox = sinon.createSandbox(); + let fakeConnection = { + backup: sandbox.stub().resolves(true), + close: sandbox.stub().resolves(true), + }; + sandbox.stub(Sqlite, "openConnection").returns(fakeConnection); + + // First, we'll try with browsing history in general being disabled. + Services.prefs.setBoolPref(HISTORY_ENABLED_PREF, false); + Services.prefs.setBoolPref(SANITIZE_ON_SHUTDOWN_PREF, false); + + let manifestEntry = await preferencesBackupResource.backup( + stagingPath, + sourcePath + ); + Assert.deepEqual( + manifestEntry, + { profilePath: sourcePath }, + "PreferencesBackupResource.backup should return the original profile path " + + "in its ManifestEntry" + ); + + Assert.ok( + fakeConnection.backup.notCalled, + "No sqlite connections should have been made with remember history disabled" + ); + + // Now verify that the sanitize shutdown pref also prevents us from backing + // up site permissions and preferences + Services.prefs.setBoolPref(HISTORY_ENABLED_PREF, true); + Services.prefs.setBoolPref(SANITIZE_ON_SHUTDOWN_PREF, true); + + fakeConnection.backup.resetHistory(); + manifestEntry = await preferencesBackupResource.backup( + stagingPath, + sourcePath + ); + Assert.deepEqual( + manifestEntry, + { profilePath: sourcePath }, + "PreferencesBackupResource.backup should return the original profile path " + + "in its ManifestEntry" + ); + + Assert.ok( + fakeConnection.backup.notCalled, + "No sqlite connections should have been made with sanitize shutdown enabled" + ); + + await maybeRemovePath(stagingPath); + await maybeRemovePath(sourcePath); + + sandbox.restore(); + Services.prefs.clearUserPref(HISTORY_ENABLED_PREF); + Services.prefs.clearUserPref(SANITIZE_ON_SHUTDOWN_PREF); +}); + +/** + * Tests that the backup method correctly skips backing up the permissions and + * content prefs databases if permanent private browsing mode is enabled. + */ +add_task(async function test_backup_private_browsing() { + let sandbox = sinon.createSandbox(); + + let preferencesBackupResource = new PreferencesBackupResource(); + let sourcePath = await IOUtils.createUniqueDirectory( + PathUtils.tempDir, + "PreferencesBackupResource-source-test" + ); + let stagingPath = await IOUtils.createUniqueDirectory( + PathUtils.tempDir, + "PreferencesBackupResource-staging-test" + ); + + let fakeConnection = { + backup: sandbox.stub().resolves(true), + close: sandbox.stub().resolves(true), + }; + sandbox.stub(Sqlite, "openConnection").returns(fakeConnection); + sandbox.stub(PrivateBrowsingUtils, "permanentPrivateBrowsing").value(true); + + let manifestEntry = await preferencesBackupResource.backup( + stagingPath, + sourcePath + ); + Assert.deepEqual( + manifestEntry, + { profilePath: sourcePath }, + "PreferencesBackupResource.backup should return the original profile path " + + "in its ManifestEntry" + ); + + Assert.ok( + fakeConnection.backup.notCalled, + "No sqlite connections should have been made with permanent private browsing enabled" + ); + + await maybeRemovePath(stagingPath); + await maybeRemovePath(sourcePath); + + sandbox.restore(); +}); + /** * Test that the recover method correctly copies items from the recovery * directory into the destination profile directory.