// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/chrome_cleaner/test/reboot_deletion_helper.h"

#include "base/files/scoped_temp_dir.h"
#include "base/test/test_reg_util_win.h"
#include "base/win/registry.h"
#include "chrome/chrome_cleaner/os/disk_util.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace chrome_cleaner {

namespace {

// The moves-pending-reboot is a MULTISZ registry value in the HKLM part of the
// registry.
const wchar_t kSessionManagerKey[] =
    L"SYSTEM\\CurrentControlSet\\Control\\Session Manager";
const wchar_t kPendingFileRenameOps[] = L"PendingFileRenameOperations";

const uint32_t kMaxRegistryValueLength = 1024;

const wchar_t kRemoveFile1[] = L"remove_one";
const wchar_t kRemoveFile2[] = L"remove_two";
const wchar_t kRemoveFile3[] = L"remove_three";
const wchar_t kRemoveFile4[] = L"remove_four";
const wchar_t kRemoveFile5[] = L"remove_five";
const wchar_t kDeleteFile[] = L"";
const BYTE kNoNullInvalidString[] = {12, 13};
const BYTE kMissingNullEntryString[] = {65, 0, 0, 0};
const BYTE kOddSizeEntryString[] = {0, 65, 0, 66, 0xFF, 0, 0, 0, 0};
const wchar_t kRemoveRawMultipleFiles[] =
    L"remove_one\0\0remove_two\0remove_three\0\0\0";
const wchar_t kRemoveRawEmpty0[] = L"";
const wchar_t kRemoveRawEmpty1[] = L"\0";
const wchar_t kRemoveRawEmpty2[] = L"\0\0";
const wchar_t kRemoveRawCorrupt[] = L"file_with_no_ending_null";

bool TestPendingFileRenameOperations(const wchar_t* content,
                                     size_t content_size,
                                     PendingMoveVector* pending_moves) {
  DCHECK(content);
  DCHECK(pending_moves);
  pending_moves->clear();

  base::win::RegKey session_manager_key(HKEY_LOCAL_MACHINE, kSessionManagerKey,
                                        KEY_ALL_ACCESS);
  if (!session_manager_key.Handle()) {
    PLOG(ERROR) << "Can't open session manager.";
    return false;
  }

  // Write raw content of the registry value.
  if (session_manager_key.WriteValue(kPendingFileRenameOps, content,
                                     content_size,
                                     REG_MULTI_SZ) != ERROR_SUCCESS) {
    PLOG(ERROR) << "Can't write to registry value '" << kPendingFileRenameOps
                << "' value: '" << content << "'.";
    return false;
  }

  // Read back the pending moves.
  if (!GetPendingMoves(pending_moves)) {
    PLOG(ERROR) << "Can't read back or parse the registry value '"
                << kPendingFileRenameOps << "'.";
    return false;
  }

  return true;
}

}  // namespace

TEST(RebootDeletionHelper, GetPendingMovesRawValue) {
  registry_util::RegistryOverrideManager registry_override;
  registry_override.OverrideRegistry(HKEY_LOCAL_MACHINE);

  PendingMoveVector pending_moves;
  EXPECT_TRUE(
      TestPendingFileRenameOperations(kRemoveRawEmpty0, 0, &pending_moves));
  EXPECT_TRUE(pending_moves.empty());

  EXPECT_TRUE(TestPendingFileRenameOperations(
      kRemoveRawEmpty0, sizeof(kRemoveRawEmpty0), &pending_moves));
  EXPECT_TRUE(pending_moves.empty());

  EXPECT_TRUE(TestPendingFileRenameOperations(
      kRemoveRawEmpty1, sizeof(kRemoveRawEmpty1), &pending_moves));
  EXPECT_TRUE(pending_moves.empty());

  EXPECT_TRUE(TestPendingFileRenameOperations(
      kRemoveRawEmpty2, sizeof(kRemoveRawEmpty2), &pending_moves));
  EXPECT_TRUE(pending_moves.empty());

  EXPECT_TRUE(TestPendingFileRenameOperations(kRemoveRawMultipleFiles,
                                              sizeof(kRemoveRawMultipleFiles),
                                              &pending_moves));
  EXPECT_THAT(pending_moves,
              testing::ElementsAre(std::make_pair(kRemoveFile1, kDeleteFile),
                                   std::make_pair(kRemoveFile2, kRemoveFile3)));

  const wchar_t kRemoveRawSingleFile[] = L"remove_one\0\0";
  EXPECT_TRUE(TestPendingFileRenameOperations(
      kRemoveRawSingleFile, sizeof(kRemoveRawSingleFile), &pending_moves));
  EXPECT_THAT(pending_moves,
              testing::ElementsAre(std::make_pair(kRemoveFile1, kDeleteFile)));

  const wchar_t kRemoveRawRename0[] = L"remove_one\0remove_two";
  EXPECT_TRUE(TestPendingFileRenameOperations(
      kRemoveRawRename0, sizeof(kRemoveRawRename0), &pending_moves));
  EXPECT_THAT(pending_moves,
              testing::ElementsAre(std::make_pair(kRemoveFile1, kRemoveFile2)));

  const wchar_t kRemoveRawRename1[] = L"remove_one\0remove_two\0";
  EXPECT_TRUE(TestPendingFileRenameOperations(
      kRemoveRawRename1, sizeof(kRemoveRawRename1), &pending_moves));
  EXPECT_THAT(pending_moves,
              testing::ElementsAre(std::make_pair(kRemoveFile1, kRemoveFile2)));

  const wchar_t kRemoveRawRename2[] = L"remove_one\0remove_two\0\0";
  EXPECT_TRUE(TestPendingFileRenameOperations(
      kRemoveRawRename2, sizeof(kRemoveRawRename2), &pending_moves));
  EXPECT_THAT(pending_moves,
              testing::ElementsAre(std::make_pair(kRemoveFile1, kRemoveFile2)));

  EXPECT_FALSE(TestPendingFileRenameOperations(
      kRemoveRawCorrupt, sizeof(kRemoveRawCorrupt), &pending_moves));
}

TEST(RebootDeletionHelper, SetPendingMovesRawValue) {
  registry_util::RegistryOverrideManager registry_override;
  registry_override.OverrideRegistry(HKEY_LOCAL_MACHINE);

  base::win::RegKey session_manager_key(HKEY_LOCAL_MACHINE, kSessionManagerKey,
                                        KEY_ALL_ACCESS);
  EXPECT_TRUE(session_manager_key.Handle());

  // Write some pending moves.
  PendingMoveVector pending_moves;
  pending_moves.push_back(std::make_pair(kRemoveFile1, kDeleteFile));
  pending_moves.push_back(std::make_pair(kRemoveFile2, kRemoveFile3));

  EXPECT_TRUE(SetPendingMoves(pending_moves));

  wchar_t buffer[kMaxRegistryValueLength];
  DWORD buffer_size = kMaxRegistryValueLength;
  DWORD buffer_type = REG_NONE;

  // Validate the raw content of the registry value.
  EXPECT_EQ(ERROR_SUCCESS,
            session_manager_key.ReadValue(kPendingFileRenameOps, &buffer[0],
                                          &buffer_size, &buffer_type));

  EXPECT_EQ(buffer_size, sizeof(kRemoveRawMultipleFiles));
  EXPECT_EQ(0, ::memcmp(kRemoveRawMultipleFiles, buffer, buffer_size));
  EXPECT_EQ(REG_MULTI_SZ, buffer_type);
}

TEST(RebootDeletionHelper, SetPendingMovesValueWithEmptyInput) {
  registry_util::RegistryOverrideManager registry_override;
  registry_override.OverrideRegistry(HKEY_LOCAL_MACHINE);

  base::win::RegKey session_manager_key(HKEY_LOCAL_MACHINE, kSessionManagerKey,
                                        KEY_ALL_ACCESS);
  EXPECT_TRUE(session_manager_key.Handle());

  // Write raw content of the registry value.
  EXPECT_EQ(ERROR_SUCCESS, session_manager_key.WriteValue(
                               kPendingFileRenameOps, kRemoveRawMultipleFiles,
                               sizeof(kRemoveRawMultipleFiles), REG_MULTI_SZ));

  // Write an empty pending moves vector.
  PendingMoveVector pending_moves;
  SetPendingMoves(pending_moves);

  // The registry value must be removed.
  EXPECT_FALSE(session_manager_key.HasValue(kPendingFileRenameOps));
}

TEST(RebootDeletionHelper, GetAndSetPendingMoves) {
  // Declare the scoped temp dir before the registry override manager because
  // the recursive deletion of folders fail when running elevated while a
  // registry override is active.
  base::ScopedTempDir temp;
  ASSERT_TRUE(temp.CreateUniqueTempDir());

  registry_util::RegistryOverrideManager registry_override;
  registry_override.OverrideRegistry(HKEY_LOCAL_MACHINE);

  // Expect the registry key to be empty.
  PendingMoveVector pending_moves;
  EXPECT_TRUE(GetPendingMoves(&pending_moves));
  ASSERT_TRUE(pending_moves.empty());

  // Write back some moves into the registry key.
  base::FilePath file_path1 = temp.GetPath().Append(kRemoveFile1);
  base::FilePath file_path2 = temp.GetPath().Append(kRemoveFile2);
  base::FilePath file_path3 = temp.GetPath().Append(kRemoveFile3);

  pending_moves.push_back(
      std::make_pair(file_path1.value(), file_path2.value()));
  pending_moves.push_back(std::make_pair(file_path3.value(), kDeleteFile));

  EXPECT_TRUE(SetPendingMoves(pending_moves));

  // Read back the written moves.
  PendingMoveVector written_moves;
  EXPECT_TRUE(GetPendingMoves(&written_moves));

  // Validate that moves before and after serialisation are the same.
  EXPECT_THAT(written_moves, testing::ElementsAreArray(pending_moves));

  // Write back an empty set of moves.
  pending_moves.clear();
  EXPECT_TRUE(SetPendingMoves(pending_moves));
  EXPECT_TRUE(GetPendingMoves(&written_moves));
  EXPECT_TRUE(written_moves.empty());
}

TEST(RebootDeletionHelper, GetInvalidPendingMoves) {
  // Open the pending registry key to write into invalid data.
  registry_util::RegistryOverrideManager registry_override;
  registry_override.OverrideRegistry(HKEY_LOCAL_MACHINE);

  base::win::RegKey session_manager_key(HKEY_LOCAL_MACHINE, kSessionManagerKey,
                                        KEY_CREATE_SUB_KEY | KEY_SET_VALUE);
  EXPECT_TRUE(session_manager_key.Handle());

  // Write an invalid pending moves registry key with a wrong type.
  EXPECT_EQ(ERROR_SUCCESS,
            session_manager_key.WriteValue(kPendingFileRenameOps, 0xCCCCCCCC));
  PendingMoveVector pending_moves;
  EXPECT_FALSE(GetPendingMoves(&pending_moves));

  // Write an invalid pending moves registry key with an invalid string format.
  EXPECT_EQ(ERROR_SUCCESS, session_manager_key.WriteValue(
                               kPendingFileRenameOps, kNoNullInvalidString,
                               sizeof(kNoNullInvalidString), REG_MULTI_SZ));
  EXPECT_FALSE(GetPendingMoves(&pending_moves));

  // Write an invalid string without the ending empty entry.
  EXPECT_EQ(ERROR_SUCCESS, session_manager_key.WriteValue(
                               kPendingFileRenameOps, kMissingNullEntryString,
                               sizeof(kMissingNullEntryString), REG_MULTI_SZ));
  EXPECT_FALSE(GetPendingMoves(&pending_moves));

  // Write an invalid string with an odd number of bytes.
  EXPECT_EQ(ERROR_SUCCESS, session_manager_key.WriteValue(
                               kPendingFileRenameOps, kOddSizeEntryString,
                               sizeof(kOddSizeEntryString), REG_MULTI_SZ));
  EXPECT_TRUE(GetPendingMoves(&pending_moves));
}

TEST(RebootDeletionHelper, UnregisterPostRebootRemovals) {
  // Declare the scoped temp dir before the registry override manager because
  // the recursive deletion of folders fail when running elevated while a
  // registry override is active.
  base::ScopedTempDir temp;
  ASSERT_TRUE(temp.CreateUniqueTempDir());

  registry_util::RegistryOverrideManager registry_override;
  registry_override.OverrideRegistry(HKEY_LOCAL_MACHINE);

  // Write some moves and renamings into the registry key.
  base::FilePath file_path1 = temp.GetPath().Append(kRemoveFile1);
  base::FilePath file_path2 = temp.GetPath().Append(kRemoveFile2);
  base::FilePath file_path3 = temp.GetPath().Append(kRemoveFile3);
  base::FilePath file_path4 = temp.GetPath().Append(kRemoveFile4);
  base::FilePath file_path5 = temp.GetPath().Append(kRemoveFile5);

  PendingMoveVector pending_moves;
  pending_moves.push_back(std::make_pair(file_path1.value(), kDeleteFile));
  pending_moves.push_back(std::make_pair(file_path2.value(), kDeleteFile));
  pending_moves.push_back(std::make_pair(file_path3.value(), kDeleteFile));
  pending_moves.push_back(
      std::make_pair(file_path4.value(), file_path5.value()));

  EXPECT_TRUE(SetPendingMoves(pending_moves));

  // Unregister paths from the pending moves.
  FilePathSet paths;
  paths.Insert(file_path2);
  paths.Insert(file_path3);
  // A file renaming action must not be removed, even if a unregister is
  // requested.
  paths.Insert(file_path4);
  EXPECT_TRUE(UnregisterPostRebootRemovals(paths));

  // Read back the pending moves.
  PendingMoveVector written_moves;
  EXPECT_TRUE(GetPendingMoves(&written_moves));
  EXPECT_THAT(written_moves,
              testing::ElementsAre(
                  std::make_pair(file_path1.value(), kDeleteFile),
                  std::make_pair(file_path4.value(), file_path5.value())));
}

TEST(RebootDeletionHelper, UnregisterPostRebootRemovalsOfQualifiedPath) {
  registry_util::RegistryOverrideManager registry_override;
  registry_override.OverrideRegistry(HKEY_LOCAL_MACHINE);

  // Add a pending deletion with a qualified path.
  PendingMoveVector pending_moves;
  pending_moves.push_back(
      std::make_pair(L"\\??\\C:\\this_file_doesnt_exist", kDeleteFile));
  EXPECT_TRUE(SetPendingMoves(pending_moves));

  // Try to remove it with an unqualified path.
  FilePathSet paths;
  paths.Insert(base::FilePath(FILE_PATH_LITERAL("C:\\this_file_doesnt_exist")));
  EXPECT_TRUE(UnregisterPostRebootRemovals(paths));

  // Read back the pending moves.
  PendingMoveVector written_moves;
  EXPECT_TRUE(GetPendingMoves(&written_moves));
  EXPECT_TRUE(written_moves.empty());
}

}  // namespace chrome_cleaner
