| // 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/test_pup_data.h" |
| |
| #include "base/logging.h" |
| #include "chrome/chrome_cleaner/proto/shared_pup_enums.pb.h" |
| #include "chrome/chrome_cleaner/pup_data/uws_catalog.h" |
| |
| namespace chrome_cleaner { |
| |
| namespace { |
| |
| const PUPData::UwSSignature kEmptyPUP = {PUPData::kInvalidUwSId, |
| PUPData::FLAGS_NONE, |
| nullptr, |
| 0, |
| kNoDisk, |
| kNoRegistry, |
| kNoCustomMatcher}; |
| |
| const PUPData::UwSSignature kEmptyPUPs[] = { |
| kEmptyPUP, |
| }; |
| |
| } // namespace |
| |
| TestPUPData* TestPUPData::current_test_ = nullptr; |
| TestPUPData* TestPUPData::previous_test_ = nullptr; |
| |
| SimpleTestPUP::SimpleTestPUP() : PUPData::PUP(&kEmptyPUP) {} |
| |
| TestPUPData::TestPUPData() |
| : previous_catalogs_(PUPData::GetUwSCatalogs()), |
| previous_pups_(PUPData::kPUPs) { |
| // Make sure tests don't step on each other. |
| previous_test_ = current_test_; |
| current_test_ = this; |
| |
| // Assume there will be no UwSCatalogs used during the test. If not, the |
| // caller can call Reset again with an explicit list of catalogs. |
| Reset({}); |
| } |
| |
| TestPUPData::~TestPUPData() { |
| // So that next tests start fresh. |
| PUPData::kPUPs = previous_pups_; |
| |
| // Reset the global PUP data to the non-test version. |
| PUPData::InitializePUPData(previous_catalogs_); |
| |
| CHECK_EQ(this, current_test_); |
| current_test_ = previous_test_; |
| } |
| |
| void TestPUPData::Reset(const PUPData::UwSCatalogs& test_uws_catalogs) { |
| CHECK_EQ(this, current_test_); |
| PUPData::kPUPs = kEmptyPUPs; |
| PUPData::kRemovedPUPs = kEmptyPUPs; |
| PUPData::kObservedPUPs = kEmptyPUPs; |
| cpp_pup_footprints_.clear(); |
| mirror_pup_footprints_.clear(); |
| |
| PUPData::InitializePUPData(test_uws_catalogs); |
| } |
| |
| void TestPUPData::AddPUP(UwSId pup_id, |
| PUPData::Flags flags, |
| const char* name, |
| size_t max_files_to_remove) { |
| CHECK_EQ(this, current_test_); |
| size_t mirror_index = EnsurePUP(pup_id); |
| mirror_pup_footprints_[mirror_index].flags = flags; |
| mirror_pup_footprints_[mirror_index].max_files_to_remove = |
| max_files_to_remove; |
| // We keep a C++ version of the strings to control lifespan of the pointer |
| // put in the C array. |
| if (name) { |
| cpp_pup_footprints_[pup_id].name = name; |
| mirror_pup_footprints_[mirror_index].name = |
| cpp_pup_footprints_[pup_id].name.c_str(); |
| } else { |
| cpp_pup_footprints_[pup_id].name.clear(); |
| mirror_pup_footprints_[mirror_index].name = nullptr; |
| } |
| } |
| |
| void TestPUPData::AddDiskFootprint(UwSId pup_id, |
| int csidl, |
| const wchar_t* path, |
| PUPData::DiskMatchRule rule) { |
| CHECK_EQ(this, current_test_); |
| size_t mirror_index = EnsurePUP(pup_id); |
| |
| PUPData::StaticDiskFootprint footprint; |
| footprint.csidl = csidl; |
| footprint.path = path; |
| footprint.rule = rule; |
| |
| // Insert before the null terminating entry. |
| cpp_pup_footprints_[pup_id].disk_footprints.insert( |
| cpp_pup_footprints_[pup_id].disk_footprints.end() - 1, footprint); |
| mirror_pup_footprints_[mirror_index].disk_footprints = |
| cpp_pup_footprints_[pup_id].disk_footprints.data(); |
| } |
| |
| void TestPUPData::AddRegistryFootprint(UwSId pup_id, |
| RegistryRoot registry_root, |
| const wchar_t* key_path, |
| const wchar_t* value_name, |
| const wchar_t* value_substring, |
| RegistryMatchRule rule) { |
| CHECK_EQ(this, current_test_); |
| size_t mirror_index = EnsurePUP(pup_id); |
| |
| // Sanity checks to avoid making silly mistakes in unittests. |
| CHECK(key_path); |
| if (rule == REGISTRY_VALUE_MATCH_KEY) { |
| CHECK(!value_name); |
| CHECK(!value_substring); |
| } else if (rule == REGISTRY_VALUE_MATCH_VALUE_NAME) { |
| CHECK(value_name); |
| CHECK(!value_substring); |
| } else { |
| CHECK(value_name); |
| CHECK(value_substring); |
| } |
| |
| PUPData::StaticRegistryFootprint footprint; |
| footprint.registry_root = registry_root; |
| footprint.key_path = key_path; |
| footprint.value_name = value_name; |
| footprint.value_substring = value_substring; |
| footprint.rule = rule; |
| |
| // Insert before the null terminating entry. |
| cpp_pup_footprints_[pup_id].registry_footprints.insert( |
| cpp_pup_footprints_[pup_id].registry_footprints.end() - 1, footprint); |
| mirror_pup_footprints_[mirror_index].registry_footprints = |
| cpp_pup_footprints_[pup_id].registry_footprints.data(); |
| } |
| |
| TestPUPData::CPPPUP::CPPPUP() = default; |
| |
| TestPUPData::CPPPUP::~CPPPUP() = default; |
| |
| void TestPUPData::AddCustomMatcher(UwSId pup_id, |
| PUPData::CustomMatcher matcher) { |
| CHECK_EQ(this, current_test_); |
| size_t mirror_index = EnsurePUP(pup_id); |
| |
| // Insert before the null terminating entry. |
| cpp_pup_footprints_[pup_id].custom_matchers.insert( |
| cpp_pup_footprints_[pup_id].custom_matchers.end() - 1, matcher); |
| mirror_pup_footprints_[mirror_index].custom_matchers = |
| cpp_pup_footprints_[pup_id].custom_matchers.data(); |
| } |
| |
| size_t TestPUPData::EnsurePUP(UwSId pup_id) { |
| if (mirror_pup_footprints_.empty()) { |
| // If we are adding the first entry, we need an initial one for the null |
| // terminating entry. |
| mirror_pup_footprints_.push_back(kEmptyPUP); |
| } else { |
| for (size_t i = 0; i < mirror_pup_footprints_.size(); ++i) { |
| if (mirror_pup_footprints_[i].id == pup_id) |
| return i; |
| } |
| } |
| |
| // Make sure the last entry is a null terminating entry. |
| size_t index = mirror_pup_footprints_.size() - 1; |
| DCHECK_EQ(PUPData::kInvalidUwSId, mirror_pup_footprints_[index].id); |
| |
| // Set up the new value to be inserted before the null terminating entry. |
| PUPData::UwSSignature new_pup; |
| new_pup.id = pup_id; |
| new_pup.flags = PUPData::FLAGS_ACTION_REMOVE; |
| |
| // Initialize all C++ arrays with a null terminating entry, and use their data |
| // pointers in the C array mirror. |
| cpp_pup_footprints_[pup_id].disk_footprints.push_back({}); |
| new_pup.disk_footprints = cpp_pup_footprints_[pup_id].disk_footprints.data(); |
| cpp_pup_footprints_[pup_id].registry_footprints.push_back({}); |
| new_pup.registry_footprints = |
| cpp_pup_footprints_[pup_id].registry_footprints.data(); |
| cpp_pup_footprints_[pup_id].custom_matchers.push_back({}); |
| new_pup.custom_matchers = cpp_pup_footprints_[pup_id].custom_matchers.data(); |
| |
| mirror_pup_footprints_.insert(mirror_pup_footprints_.end() - 1, new_pup); |
| PUPData::kPUPs = mirror_pup_footprints_.data(); |
| |
| // Add any newly-created UwS to the cache. Don't touch anything that already |
| // existed, since this is often called during tests that have pointers to |
| // that UwS. |
| PUPData::UpdateCachedUwS(); |
| |
| return index; |
| } |
| |
| } // namespace chrome_cleaner |