OLD | NEW |
(Empty) | |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "extensions/browser/api/declarative_net_request/ruleset_manager.h" |
| 6 #include "base/threading/thread_restrictions.h" |
| 7 #include "components/subresource_filter/core/common/flat/extension_metadata_gene
rated.h" |
| 8 #include "components/subresource_filter/core/common/flat/url_pattern_index_gener
ated.h" |
| 9 #include "content/public/browser/browser_thread.h" |
| 10 #include "extensions/browser/info_map.h" |
| 11 #include "extensions/common/api/declarative_net_request/indexed_rule.h" |
| 12 #include "extensions/common/api/declarative_net_request/ruleset_indexer.h" |
| 13 |
| 14 namespace extensions { |
| 15 namespace declarative_net_request { |
| 16 |
| 17 namespace { |
| 18 |
| 19 using UrlPatternIndex = subresource_filter::flat::UrlPatternIndex; |
| 20 using UrlRule = subresource_filter::flat::UrlRule; |
| 21 using FlatUrlRuleList = flatbuffers::Vector<flatbuffers::Offset<UrlRule>>; |
| 22 using DomainList = |
| 23 flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>; |
| 24 using ExtensionRuleMetadata = flat::ExtensionRuleMetadata; |
| 25 using ExtensionMetadataList = |
| 26 flatbuffers::Vector<flatbuffers::Offset<ExtensionRuleMetadata>>; |
| 27 |
| 28 // const std::pair<OptionFlag, std::string> kOptionsPairs[] = { |
| 29 // {OptionFlag::OptionFlag_IS_WHITELIST, "IS_WHITELIST"}, |
| 30 // {OptionFlag::OptionFlag_APPLIES_TO_FIRST_PARTY, "APPLIES_TO_FIRST_PARTY"}, |
| 31 // {OptionFlag::OptionFlag_APPLIES_TO_THIRD_PARTY, "APPLIES_TO_THIRD_PARTY"}, |
| 32 // {OptionFlag::OptionFlag_IS_MATCH_CASE, "IS_MATCH_CASE"}, |
| 33 // }; |
| 34 |
| 35 // const std::pair<AnchorType, std::string> kAnchorPairs[] = { |
| 36 // {AnchorType::AnchorType_NONE, "NONE"}, |
| 37 // {AnchorType::AnchorType_BOUNDARY, "BOUNDARY"}, |
| 38 // {AnchorType::AnchorType_SUBDOMAIN, "SUBDOMAIN"}, |
| 39 // }; |
| 40 |
| 41 // const std::pair<UrlPatternType, std::string> kUrlPatternPairs[] = { |
| 42 // {UrlPatternType::UrlPatternType_SUBSTRING, "SUBSTRING"}, |
| 43 // {UrlPatternType::UrlPatternType_WILDCARDED, "WILDCARDED"}, |
| 44 // {UrlPatternType::UrlPatternType_REGEXP, "REGEXP"}, |
| 45 // }; |
| 46 |
| 47 // const std::pair<ActivationType, std::string> kActivationPairs[] = { |
| 48 // {ActivationType::ActivationType_DOCUMENT, "DOCUMENT"}, |
| 49 // {ActivationType::ActivationType_ELEM_HIDE, "ELEM_HIDE"}, |
| 50 // {ActivationType::ActivationType_GENERIC_HIDE, "GENERIC_HIDE"}, |
| 51 // {ActivationType::ActivationType_GENERIC_BLOCK, "GENERIC_BLOCK"}, |
| 52 // }; |
| 53 |
| 54 // const std::pair<ElementType, std::string> kElementTypePairs[] = { |
| 55 // {ElementType::ElementType_OTHER, "OTHER"}, |
| 56 // {ElementType::ElementType_SCRIPT, "SCRIPT"}, |
| 57 // {ElementType::ElementType_IMAGE, "IMAGE"}, |
| 58 // {ElementType::ElementType_STYLESHEET, "STYLESHEET"}, |
| 59 // {ElementType::ElementType_OBJECT, "OBJECT"}, |
| 60 // {ElementType::ElementType_XMLHTTPREQUEST, "XMLHTTPREQUEST"}, |
| 61 // {ElementType::ElementType_OBJECT_SUBREQUEST, "OBJECT_SUBREQUEST"}, |
| 62 // {ElementType::ElementType_SUBDOCUMENT, "SUBDOCUMENT"}, |
| 63 // {ElementType::ElementType_PING, "PING"}, |
| 64 // {ElementType::ElementType_MEDIA, "MEDIA"}, |
| 65 // {ElementType::ElementType_FONT, "FONT"}, |
| 66 // {ElementType::ElementType_POPUP, "POPUP"}, |
| 67 // {ElementType::ElementType_WEBSOCKET, "WEBSOCKET"}, |
| 68 // }; |
| 69 |
| 70 // void PrintDomainList(const std::string& msg, const DomainList* domain_list) { |
| 71 // LOG(ERROR) << "--------msg " << msg << "\n"; |
| 72 // for(const auto* domain : *domain_list) { |
| 73 // LOG(ERROR) << "--------*domain " << domain->c_str() << "\n"; |
| 74 // } |
| 75 // } |
| 76 |
| 77 // template <typename A, typename B,typename C> |
| 78 // std::string PrintMask(const std::pair<A, B> pairs[], size_t len, C elem) { |
| 79 // std::string s; |
| 80 // for(size_t i = 0; i < len; i++) { |
| 81 // if(elem & pairs[i].first) |
| 82 // s += pairs[i].second + " "; |
| 83 // } |
| 84 // return s; |
| 85 // } |
| 86 |
| 87 // template <typename A, typename B,typename C> |
| 88 // std::string PrintEqual(const std::pair<A, B> pairs[], size_t len, C elem) { |
| 89 // for(size_t i = 0; i < len; i++) { |
| 90 // if(elem == pairs[i].first) |
| 91 // return pairs[i].second; |
| 92 // } |
| 93 // return ""; |
| 94 // } |
| 95 |
| 96 // std::string PrintOptions(uint8_t options_mask) { |
| 97 // return PrintMask(kOptionsPairs, arraysize(kOptionsPairs), options_mask); |
| 98 // } |
| 99 |
| 100 // std::string PrintAnchor(uint8_t anchor) { |
| 101 // return PrintEqual(kAnchorPairs, arraysize(kAnchorPairs), anchor); |
| 102 // } |
| 103 |
| 104 // std::string PrintUrlPatternType(uint8_t url_pattern_type) { |
| 105 // return PrintEqual(kUrlPatternPairs, arraysize(kUrlPatternPairs), |
| 106 // url_pattern_type); |
| 107 // } |
| 108 |
| 109 // std::string PrintActivation(uint8_t activation_mask) { |
| 110 // return PrintMask(kActivationPairs, arraysize(kActivationPairs), |
| 111 // activation_mask); |
| 112 // } |
| 113 |
| 114 // std::string PrintElements(uint16_t element_mask) { |
| 115 // return PrintMask(kElementTypePairs, arraysize(kElementTypePairs), |
| 116 // element_mask); |
| 117 // } |
| 118 |
| 119 // void PrintRuleList(const std::string& msg, const FlatUrlRuleList* rule_list) |
| 120 // { |
| 121 // LOG(ERROR) << "--------msg " << msg << "\n"; |
| 122 // for(const auto* rule : *rule_list) { |
| 123 // LOG(ERROR) << "--------rule->id() " << rule->id() << "\n"; |
| 124 // LOG(ERROR) << "--------rule->priority() " << rule->priority() << "\n"; |
| 125 // LOG(ERROR) << "--------rule->options() " << PrintOptions(rule->options()) |
| 126 // << "\n"; LOG(ERROR) << "--------rule->element_types() " << |
| 127 // PrintElements(rule->element_types()) << "\n"; LOG(ERROR) << |
| 128 // "--------rule->activation_types() " << |
| 129 // PrintActivation(rule->activation_types()) << "\n"; LOG(ERROR) << |
| 130 // "--------rule->url_pattern_type() " << |
| 131 // PrintUrlPatternType(rule->url_pattern_type()) << "\n"; LOG(ERROR) << |
| 132 // "--------rule->anchor_left() " << PrintAnchor(rule->anchor_left()) << |
| 133 // "\n"; LOG(ERROR) << "--------rule->anchor_right() " << |
| 134 // PrintAnchor(rule->anchor_right()) << "\n"; LOG(ERROR) << |
| 135 // "--------rule->url_pattern() " << rule->url_pattern()->c_str() << "\n"; |
| 136 // PrintDomainList("included_domains", rule->domains_included()); |
| 137 // PrintDomainList("excluded_domains", rule->domains_excluded()); |
| 138 // } |
| 139 // } |
| 140 |
| 141 // std::string string_to_hex(const std::string& input) |
| 142 // { |
| 143 // static const char* const lut = "0123456789ABCDEF"; |
| 144 // size_t len = input.length(); |
| 145 |
| 146 // std::string output; |
| 147 // output.reserve(2 * len); |
| 148 // for (size_t i = 0; i < len; ++i) |
| 149 // { |
| 150 // const unsigned char c = input[i]; |
| 151 // output.push_back(lut[c >> 4]); |
| 152 // output.push_back(lut[c & 15]); |
| 153 // } |
| 154 // return output; |
| 155 // } |
| 156 |
| 157 // void PrintIndex(const std::string& str, const UrlPatternIndex* index) { |
| 158 // LOG(ERROR) << "--------str " << str << "\n"; |
| 159 // LOG(ERROR) << "--------index->n() " << index->n() << "\n"; |
| 160 // const ::subresource_filter::flat::NGramToRules* empty_slot = |
| 161 // index->ngram_index_empty_slot(); PrintRuleList("fallback_rules", |
| 162 // index->fallback_rules()); for(const auto* n_gram_rules: |
| 163 // *index->ngram_index()) { |
| 164 // if (n_gram_rules == empty_slot) |
| 165 // continue; |
| 166 // PrintRuleList("rule_list" + std::to_string(n_gram_rules->ngram()), |
| 167 // n_gram_rules->rule_list()); |
| 168 // } |
| 169 // } |
| 170 |
| 171 // void PrintExtensionMetadata(const std::string& msg, const |
| 172 // ExtensionMetadataList* metadata_list) { |
| 173 // LOG(ERROR) << "--------msg " << msg << "\n"; |
| 174 // for (const auto* metadata : *metadata_list) { |
| 175 // LOG(ERROR) << "--------metadata->id() " << metadata->id() << "\n"; |
| 176 // LOG(ERROR) << "--------metadata->redirect_url()->c_str() " << |
| 177 // metadata->redirect_url()->c_str() << "\n"; |
| 178 // } |
| 179 // } |
| 180 |
| 181 // void PrintIndexedRuleset(base::MemoryMappedFile* file) { |
| 182 // RulesetIndexer::SerializedData data(file->data(), file->length()); |
| 183 // std::string file_data(reinterpret_cast<const char*>(data.first), |
| 184 // data.second); LOG(ERROR) << "--------file_data " << |
| 185 // string_to_hex(file_data) << "\n"; flatbuffers::Verifier |
| 186 // verifier(data.first, data.second); bool verify = |
| 187 // flat::VerifyExtensionIndexedRulesetBuffer(verifier); LOG(ERROR) << |
| 188 // "--------verify " << verify << "\n"; CHECK(verify); |
| 189 |
| 190 // const flat::ExtensionIndexedRuleset* ruleset = |
| 191 // flat::GetExtensionIndexedRuleset(data.first); PrintIndex("blacklist_index", |
| 192 // ruleset->blacklist_index()); PrintIndex("whitelist_index", |
| 193 // ruleset->whitelist_index()); PrintIndex("redirect_index", |
| 194 // ruleset->redirect_index()); PrintExtensionMetadata("extension_metdata", |
| 195 // ruleset->extension_metdata()); |
| 196 // } |
| 197 } |
| 198 |
| 199 RulesetManager::ExtensionKey::ExtensionKey(ExtensionId extension_id, |
| 200 base::Time extension_install_time) |
| 201 : id(std::move(extension_id)), |
| 202 install_time(std::move(extension_install_time)) {} |
| 203 RulesetManager::ExtensionKey::~ExtensionKey() = default; |
| 204 |
| 205 // Comparator to ensure that ExtensionKey are sorted in order of decreasing |
| 206 // extension install time i.e. most recently installed extension first. For |
| 207 // equal install times, sort by id. This is also necessary since a set uses the |
| 208 // this to prevent duplicates. Hence only sorting on a single parameter would |
| 209 // be incorrect. |
| 210 bool RulesetManager::ExtensionKeyComparator::operator()( |
| 211 const ExtensionKey& lhs, |
| 212 const ExtensionKey& rhs) const { |
| 213 return lhs.install_time > rhs.install_time || lhs.id < rhs.id; |
| 214 } |
| 215 |
| 216 RulesetManager::RulesetManager(InfoMap* info_map) : info_map_(info_map) { |
| 217 DCHECK(info_map_); |
| 218 } |
| 219 RulesetManager::~RulesetManager() = default; |
| 220 |
| 221 void RulesetManager::AddRuleset( |
| 222 ExtensionId extension_id, |
| 223 std::unique_ptr<ExtensionIndexedRulesetMatcher> ruleset_matcher) { |
| 224 DCHECK(info_map_); |
| 225 base::Time install_time = info_map_->GetInstallTime(extension_id); |
| 226 ExtensionKey key(std::move(extension_id), std::move(install_time)); |
| 227 // PrintIndexedRuleset(ruleset.get()); |
| 228 auto it = rules_.insert(std::make_pair(key, std::move(ruleset_matcher))); |
| 229 // Verify insertion actually occured. |
| 230 DCHECK(it.second); |
| 231 } |
| 232 |
| 233 // Todo actually this should take a const std::string&, since it won't be moved. |
| 234 // But then the API would become inconsistent. |
| 235 void RulesetManager::RemoveRuleset(ExtensionId extension_id) { |
| 236 DCHECK(info_map_); |
| 237 base::Time install_time = info_map_->GetInstallTime(extension_id); |
| 238 LOG(ERROR) << "--------Removing ruleset for " << extension_id; |
| 239 // This is a bit problematic. We are depending on info map to provide the |
| 240 // extension install time. If the provided time changes, the key won't be |
| 241 // removed. And we won't be able to ensure that single key for single id. |
| 242 // TODO Add DCHECK to ensure keys for ids are unique. |
| 243 // TODO yeah this is probematic as Info::RemoveExtension may be called first. |
| 244 // Check. |
| 245 ExtensionKey key(std::move(extension_id), std::move(install_time)); |
| 246 size_t erase_count = rules_.erase(key); |
| 247 DCHECK_EQ(1u, erase_count); |
| 248 } |
| 249 |
| 250 } // namespace declarative_net_request |
| 251 } // namespace extensions |
OLD | NEW |