Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(6)

Side by Side Diff: chrome/browser/privacy_blacklist/blacklist_io.cc

Issue 337025: Design changes in browser/privacy_blacklist needed to integrate (Closed)
Patch Set: fixes Created 11 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/privacy_blacklist/blacklist_io.h" 5 #include "chrome/browser/privacy_blacklist/blacklist_io.h"
6 6
7 #include <algorithm> 7 #include <limits>
8 #include <string>
9 8
10 #include "base/file_path.h" 9 #include "base/file_path.h"
11 #include "base/file_util.h" 10 #include "base/file_util.h"
11 #include "base/string_tokenizer.h"
12 #include "base/string_util.h" 12 #include "base/string_util.h"
13 #include "base/string_tokenizer.h" 13 #include "chrome/browser/privacy_blacklist/blacklist.h"
14 #include "chrome/browser/privacy_blacklist/blacklist_store.h" 14 #include "chrome/browser/privacy_blacklist/blacklist_store.h"
15 15
16 namespace { 16 namespace {
17 17
18 const char header[] = "[Chromium::PrivacyBlacklist]"; 18 const char header[] = "[Chromium::PrivacyBlacklist]";
19 const char name_tag[] = "Name:"; 19 const char name_tag[] = "Name:";
20 const char url_tag[] = "URL:"; 20 const char url_tag[] = "URL:";
21 const char arrow_tag[] = "=>"; 21 const char arrow_tag[] = "=>";
22 const char eol[] = "\n\r"; 22 const char eol[] = "\n\r";
23 23
24 class IsWhiteSpace { 24 class IsWhiteSpace {
25 public: 25 public:
26 bool operator()(const char& c) const { 26 bool operator()(const char& c) const {
27 return IsAsciiWhitespace(c); 27 return IsAsciiWhitespace(c);
28 } 28 }
29 }; 29 };
30 30
31 class IsNotWhiteSpace { 31 class IsNotWhiteSpace {
32 public: 32 public:
33 bool operator()(const char& c) const { 33 bool operator()(const char& c) const {
34 return !IsAsciiWhitespace(c); 34 return !IsAsciiWhitespace(c);
35 } 35 }
36 }; 36 };
37 37
38 bool StartsWith(const char* cur, const char* end, 38 bool StartsWith(const char* cur, const char* end,
39 const char* tag, std::size_t size) { 39 const char* tag, std::size_t size) {
40 return cur+size <= end && std::equal(tag, tag+size-1, cur); 40 return cur + size <= end && std::equal(tag, tag + size - 1, cur);
41 } 41 }
42 42
43 } // namespace 43 } // namespace
44 44
45 BlacklistIO::BlacklistIO() {} 45 // static
46 46 bool BlacklistIO::ReadText(Blacklist* blacklist,
47 BlacklistIO::~BlacklistIO() { 47 const FilePath& path,
48 for (std::list<Blacklist::Entry*>::iterator i = blacklist_.begin(); 48 std::string* error_string) {
49 i != blacklist_.end(); ++i) { 49 DCHECK(blacklist);
50 delete *i; 50
51 }
52 for (std::list<Blacklist::Provider*>::iterator i = providers_.begin();
53 i != providers_.end(); ++i) {
54 delete *i;
55 }
56 }
57
58 bool BlacklistIO::Read(const FilePath& file) {
59 // Memory map for efficient parsing. If the file cannot fit in available 51 // Memory map for efficient parsing. If the file cannot fit in available
60 // memory it would be the least of our worries. Typical blacklist files 52 // memory it would be the least of our worries. Typical blacklist files
61 // are less than 200K. 53 // are less than 200K.
62 file_util::MemoryMappedFile input; 54 file_util::MemoryMappedFile input;
63 if (!input.Initialize(file) || !input.data()) { 55 if (!input.Initialize(path) || !input.data()) {
64 last_error_ = ASCIIToUTF16("File I/O error. Check path and permissions."); 56 *error_string = "File I/O error. Check path and permissions.";
65 return false; 57 return false;
66 } 58 }
67 59
68 const char* cur = reinterpret_cast<const char*>(input.data()); 60 const char* cur = reinterpret_cast<const char*>(input.data());
69 const char* end = cur + input.length(); 61 const char* end = cur + input.length();
70 62
71 // Check header. 63 // Check header.
72 if (!StartsWith(cur, end, header, arraysize(header))) { 64 if (!StartsWith(cur, end, header, arraysize(header))) {
73 last_error_ = ASCIIToUTF16("Incorrect header."); 65 *error_string = "Incorrect header.";
74 return false; 66 return false;
75 } 67 }
76 68
69 Blacklist::EntryList entries;
70 Blacklist::ProviderList providers;
71
77 Blacklist::Provider* provider = new Blacklist::Provider; 72 Blacklist::Provider* provider = new Blacklist::Provider;
78 providers_.push_back(provider); 73 providers.push_back(linked_ptr<Blacklist::Provider>(provider));
79 74
80 cur = std::find(cur, end, '\n') + 1; // Skip past EOL. 75 cur = std::find(cur, end, '\n') + 1; // Skip past EOL.
81 76
82 // Each loop iteration takes care of one input line. 77 // Each loop iteration takes care of one input line.
83 while (cur < end) { 78 while (cur < end) {
84 // Skip whitespace at beginning of line. 79 // Skip whitespace at beginning of line.
85 cur = std::find_if(cur, end, IsNotWhiteSpace()); 80 cur = std::find_if(cur, end, IsNotWhiteSpace());
86 if (cur == end) 81 if (cur == end)
87 break; 82 break;
88 83
89 if (*cur == '#') { 84 if (*cur == '#') {
90 cur = std::find(cur, end, '\n') + 1; 85 cur = std::find(cur, end, '\n') + 1;
91 continue; 86 continue;
92 } 87 }
93 88
94 if (*cur == '|') { 89 if (*cur == '|') {
95 ++cur; 90 ++cur;
96 if (StartsWith(cur, end, name_tag, arraysize(name_tag))) { 91 if (StartsWith(cur, end, name_tag, arraysize(name_tag))) {
97 // Edge condition: if the find below fails, the next one will too, 92 // Edge condition: if the find below fails, the next one will too,
98 // so we'll just skip to the EOF below. 93 // so we'll just skip to the EOF below.
99 cur = std::find_if(cur+arraysize(name_tag), end, IsNotWhiteSpace()); 94 cur = std::find_if(cur + arraysize(name_tag), end, IsNotWhiteSpace());
100 const char* skip = std::find_if(cur, end, IsWhiteSpace()); 95 const char* skip = std::find_if(cur, end, IsWhiteSpace());
101 if (skip < end) 96 if (skip < end)
102 provider->set_name(std::string(cur, skip)); 97 provider->set_name(std::string(cur, skip));
103 } else if (StartsWith(cur, end, url_tag, arraysize(url_tag))) { 98 } else if (StartsWith(cur, end, url_tag, arraysize(url_tag))) {
104 cur = std::find_if(cur+arraysize(url_tag), end, IsNotWhiteSpace()); 99 cur = std::find_if(cur + arraysize(url_tag), end, IsNotWhiteSpace());
105 const char* skip = std::find_if(cur, end, IsWhiteSpace()); 100 const char* skip = std::find_if(cur, end, IsWhiteSpace());
106 if (skip < end) 101 if (skip < end)
107 provider->set_url(std::string(cur, skip)); 102 provider->set_url(std::string(cur, skip));
108 } 103 }
109 cur = std::find(cur, end, '\n') + 1; 104 cur = std::find(cur, end, '\n') + 1;
110 continue; 105 continue;
111 } 106 }
112 107
113 const char* skip = std::find_if(cur, end, IsWhiteSpace()); 108 const char* skip = std::find_if(cur, end, IsWhiteSpace());
114 std::string pattern(cur, skip); 109 std::string pattern(cur, skip);
115 110
116 cur = std::find_if(cur+pattern.size(), end, IsNotWhiteSpace()); 111 cur = std::find_if(cur + pattern.size(), end, IsNotWhiteSpace());
117 if (!StartsWith(cur, end, arrow_tag, arraysize(arrow_tag))) { 112 if (!StartsWith(cur, end, arrow_tag, arraysize(arrow_tag))) {
118 last_error_ = ASCIIToUTF16("Missing => in rule."); 113 *error_string = "Missing => in rule.";
119 return false; 114 return false;
120 } 115 }
121 116
122 scoped_ptr<Blacklist::Entry> entry(new Blacklist::Entry(pattern, provider)); 117 linked_ptr<Blacklist::Entry> entry(new Blacklist::Entry(pattern, provider));
123 118
124 cur = std::find_if(cur+arraysize(arrow_tag), end, IsNotWhiteSpace()); 119 cur = std::find_if(cur + arraysize(arrow_tag), end, IsNotWhiteSpace());
125 skip = std::find_first_of(cur, end, eol, eol+2); 120 skip = std::find_first_of(cur, end, eol, eol + 2);
126 std::string buf(cur, skip); 121 std::string buf(cur, skip);
127 cur = skip + 1; 122 cur = skip + 1;
128 123
129 StringTokenizer tokenier(buf, " (),\n\r"); 124 StringTokenizer tokenizer(buf, " (),\n\r");
130 tokenier.set_options(StringTokenizer::RETURN_DELIMS); 125 tokenizer.set_options(StringTokenizer::RETURN_DELIMS);
131 126
132 bool in_attribute = false; 127 bool in_attribute = false;
133 unsigned int last_attribute = 0; 128 unsigned int last_attribute = 0;
134 129
135 while (tokenier.GetNext()) { 130 while (tokenizer.GetNext()) {
136 if (tokenier.token_is_delim()) { 131 if (tokenizer.token_is_delim()) {
137 switch (*tokenier.token_begin()) { 132 switch (*tokenizer.token_begin()) {
138 case '(': 133 case '(':
139 if (in_attribute) { 134 if (in_attribute) {
140 last_error_ = 135 *error_string = "Unexpected ( in attribute parameters.";
141 ASCIIToUTF16("Unexpected ( in attribute parameters.");
142 return false; 136 return false;
143 } 137 }
144 in_attribute = true; 138 in_attribute = true;
145 continue; 139 continue;
146 case ')': 140 case ')':
147 if (!in_attribute) { 141 if (!in_attribute) {
148 last_error_ = ASCIIToUTF16("Unexpected ) in attribute list."); 142 *error_string = "Unexpected ) in attribute list.";
149 return false; 143 return false;
150 } 144 }
151 in_attribute = false; 145 in_attribute = false;
152 continue; 146 continue;
153 default: 147 default:
154 // No state change for other delimiters. 148 // No state change for other delimiters.
155 continue; 149 continue;
156 } 150 }
157 } 151 }
158 152
159 if (in_attribute) { 153 if (in_attribute) {
160 // The only attribute to support sub_tokens is kBlockByType, for now. 154 // The only attribute to support sub_tokens is kBlockByType, for now.
161 if (last_attribute == Blacklist::kBlockByType) 155 if (last_attribute == Blacklist::kBlockByType)
162 entry->AddType(tokenier.token()); 156 entry->AddType(tokenizer.token());
163 } else { 157 } else {
164 // Filter attribute. Unrecognized attributes are ignored. 158 // Filter attribute. Unrecognized attributes are ignored.
165 last_attribute = Blacklist::String2Attribute(tokenier.token()); 159 last_attribute = Blacklist::String2Attribute(tokenizer.token());
166 entry->AddAttributes(last_attribute); 160 entry->AddAttributes(last_attribute);
167 } 161 }
168 } 162 }
169 blacklist_.push_back(entry.release()); 163 entries.push_back(entry);
170 } 164 }
165
166 for (Blacklist::EntryList::iterator i = entries.begin();
167 i != entries.end(); ++i) {
168 blacklist->AddEntry(i->release());
169 }
170 for (Blacklist::ProviderList::iterator i = providers.begin();
171 i != providers.end(); ++i) {
172 blacklist->AddProvider(i->release());
173 }
174
171 return true; 175 return true;
172 } 176 }
173 177
174 bool BlacklistIO::Write(const FilePath& file) { 178 // static
179 bool BlacklistIO::ReadBinary(Blacklist* blacklist, const FilePath& path) {
180 DCHECK(blacklist);
181
182 FILE* fp = file_util::OpenFile(path, "rb");
183 if (fp == NULL)
184 return false;
185
186 BlacklistStoreInput input(fp);
187
188 // Read the providers.
189 uint32 num_providers = input.ReadNumProviders();
190 if (num_providers == std::numeric_limits<uint32>::max())
191 return false;
192
193 Blacklist::EntryList entries;
194 Blacklist::ProviderList providers;
195 std::map<size_t, Blacklist::Provider*> provider_map;
196
197 std::string name;
198 std::string url;
199 for (size_t i = 0; i < num_providers; ++i) {
200 if (!input.ReadProvider(&name, &url))
201 return false;
202 provider_map[i] = new Blacklist::Provider(name.c_str(), url.c_str());
203 providers.push_back(linked_ptr<Blacklist::Provider>(provider_map[i]));
204 }
205
206 // Read the entries.
207 uint32 num_entries = input.ReadNumEntries();
208 if (num_entries == std::numeric_limits<uint32>::max())
209 return false;
210
211 std::string pattern;
212 unsigned int attributes, provider;
213 std::vector<std::string> types;
214 for (size_t i = 0; i < num_entries; ++i) {
215 if (!input.ReadEntry(&pattern, &attributes, &types, &provider))
216 return false;
217
218 Blacklist::Entry* entry =
219 new Blacklist::Entry(pattern, provider_map[provider]);
220 entry->AddAttributes(attributes);
221 entry->SwapTypes(&types);
222 entries.push_back(linked_ptr<Blacklist::Entry>(entry));
223 }
224
225 for (Blacklist::EntryList::iterator i = entries.begin();
226 i != entries.end(); ++i) {
227 blacklist->AddEntry(i->release());
228 }
229 for (Blacklist::ProviderList::iterator i = providers.begin();
230 i != providers.end(); ++i) {
231 blacklist->AddProvider(i->release());
232 }
233
234 return true;
235 }
236
237 // static
238 bool BlacklistIO::WriteBinary(const Blacklist* blacklist,
239 const FilePath& file) {
175 BlacklistStoreOutput output(file_util::OpenFile(file, "wb")); 240 BlacklistStoreOutput output(file_util::OpenFile(file, "wb"));
176 if (!output.is_good()) { 241 if (!output.is_good())
177 last_error_ = ASCIIToUTF16("Error opening file for writing.");
178 return false; 242 return false;
179 } 243
244 Blacklist::EntryList entries(blacklist->entries_begin(),
245 blacklist->entries_end());
246 Blacklist::ProviderList providers(blacklist->providers_begin(),
247 blacklist->providers_end());
180 248
181 // Output providers, give each one an index. 249 // Output providers, give each one an index.
182 std::map<const Blacklist::Provider*, uint32> index; 250 std::map<const Blacklist::Provider*, uint32> index;
183 uint32 current = 0; 251 uint32 current = 0;
184 if (!output.ReserveProviders(providers_.size())) { 252 if (!output.ReserveProviders(providers.size()))
185 last_error_ = ASCIIToUTF16("Error writing to file.");
186 return false; 253 return false;
187 }
188 254
189 for (std::list<Blacklist::Provider*>::const_iterator i = providers_.begin(); 255 for (Blacklist::ProviderList::const_iterator i = providers.begin();
190 i != providers_.end(); ++i, ++current) { 256 i != providers.end(); ++i, ++current) {
191 if (!output.StoreProvider((*i)->name(), (*i)->url())) { 257 if (!output.StoreProvider((*i)->name(), (*i)->url()))
192 last_error_ = ASCIIToUTF16("Error writing to file.");
193 return false; 258 return false;
194 } 259 index[i->get()] = current;
195 index[*i] = current;
196 } 260 }
197 261
198 // Output entries, replacing the provider with its index. 262 // Output entries, replacing the provider with its index.
199 if (!output.ReserveEntries(blacklist_.size())) { 263 if (!output.ReserveEntries(entries.size()))
200 last_error_ = ASCIIToUTF16("Error writing to file.");
201 return false; 264 return false;
202 }
203 265
204 for (std::list<Blacklist::Entry*>::const_iterator i = blacklist_.begin(); 266 for (Blacklist::EntryList::const_iterator i = entries.begin();
205 i != blacklist_.end(); ++i) { 267 i != entries.end(); ++i) {
206 if (!output.StoreEntry((*i)->pattern_, 268 if (!output.StoreEntry((*i)->pattern_,
207 (*i)->attributes_, 269 (*i)->attributes_,
208 (*i)->types_, 270 (*i)->types_,
209 index[(*i)->provider_])) { 271 index[(*i)->provider_])) {
210 last_error_ = ASCIIToUTF16("Error writing to file.");
211 return false; 272 return false;
212 } 273 }
213 } 274 }
214 return true; 275 return true;
215 } 276 }
OLDNEW
« no previous file with comments | « chrome/browser/privacy_blacklist/blacklist_io.h ('k') | chrome/browser/privacy_blacklist/blacklist_io_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698