OLD | NEW |
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 <algorithm> |
8 #include <string> | 8 #include <string> |
9 | 9 |
10 #include "base/file_path.h" | 10 #include "base/file_path.h" |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
52 i != providers_.end(); ++i) { | 52 i != providers_.end(); ++i) { |
53 delete *i; | 53 delete *i; |
54 } | 54 } |
55 } | 55 } |
56 | 56 |
57 bool BlacklistIO::Read(const FilePath& file) { | 57 bool BlacklistIO::Read(const FilePath& file) { |
58 // Memory map for efficient parsing. If the file cannot fit in available | 58 // Memory map for efficient parsing. If the file cannot fit in available |
59 // memory it would be the least of our worries. Typical blacklist files | 59 // memory it would be the least of our worries. Typical blacklist files |
60 // are less than 200K. | 60 // are less than 200K. |
61 file_util::MemoryMappedFile input; | 61 file_util::MemoryMappedFile input; |
62 if (!input.Initialize(file) || !input.data()) | 62 if (!input.Initialize(file) || !input.data()) { |
| 63 last_error_ = ASCIIToUTF16("File I/O error. Check path and permissions."); |
63 return false; | 64 return false; |
| 65 } |
64 | 66 |
65 const char* cur = reinterpret_cast<const char*>(input.data()); | 67 const char* cur = reinterpret_cast<const char*>(input.data()); |
66 const char* end = cur + input.length(); | 68 const char* end = cur + input.length(); |
67 | 69 |
68 // Check header. | 70 // Check header. |
69 if (!StartsWith(cur, end, header, arraysize(header))) | 71 if (!StartsWith(cur, end, header, arraysize(header))) { |
| 72 last_error_ = ASCIIToUTF16("Incorrect header."); |
70 return false; | 73 return false; |
| 74 } |
71 | 75 |
72 Blacklist::Provider* provider = new Blacklist::Provider; | 76 Blacklist::Provider* provider = new Blacklist::Provider; |
73 providers_.push_back(provider); | 77 providers_.push_back(provider); |
74 | 78 |
75 cur = std::find(cur, end, '\n') + 1; // Skip past EOL. | 79 cur = std::find(cur, end, '\n') + 1; // Skip past EOL. |
76 | 80 |
77 // Each loop iteration takes care of one input line. | 81 // Each loop iteration takes care of one input line. |
78 while (cur < end) { | 82 while (cur < end) { |
79 // Skip whitespace at beginning of line. | 83 // Skip whitespace at beginning of line. |
80 cur = std::find_if(cur, end, IsNotWhiteSpace()); | 84 cur = std::find_if(cur, end, IsNotWhiteSpace()); |
(...skipping 21 matching lines...) Expand all Loading... |
102 provider->set_url(std::string(cur, skip)); | 106 provider->set_url(std::string(cur, skip)); |
103 } | 107 } |
104 cur = std::find(cur, end, '\n') + 1; | 108 cur = std::find(cur, end, '\n') + 1; |
105 continue; | 109 continue; |
106 } | 110 } |
107 | 111 |
108 const char* skip = std::find_if(cur, end, IsWhiteSpace()); | 112 const char* skip = std::find_if(cur, end, IsWhiteSpace()); |
109 std::string pattern(cur, skip); | 113 std::string pattern(cur, skip); |
110 | 114 |
111 cur = std::find_if(cur+pattern.size(), end, IsNotWhiteSpace()); | 115 cur = std::find_if(cur+pattern.size(), end, IsNotWhiteSpace()); |
112 if (!StartsWith(cur, end, arrow_tag, arraysize(arrow_tag))) | 116 if (!StartsWith(cur, end, arrow_tag, arraysize(arrow_tag))) { |
| 117 last_error_ = ASCIIToUTF16("Missing => in rule."); |
113 return false; | 118 return false; |
| 119 } |
114 | 120 |
115 scoped_ptr<Blacklist::Entry> entry(new Blacklist::Entry(pattern, provider)); | 121 scoped_ptr<Blacklist::Entry> entry(new Blacklist::Entry(pattern, provider)); |
116 | 122 |
117 cur = std::find_if(cur+arraysize(arrow_tag), end, IsNotWhiteSpace()); | 123 cur = std::find_if(cur+arraysize(arrow_tag), end, IsNotWhiteSpace()); |
118 skip = std::find(cur, end, '\n'); | 124 skip = std::find(cur, end, '\n'); |
119 std::string buf(cur, skip); | 125 std::string buf(cur, skip); |
120 cur = skip + 1; | 126 cur = skip + 1; |
121 | 127 |
122 StringTokenizer tokenier(buf, " (),"); | 128 StringTokenizer tokenier(buf, " (),"); |
123 tokenier.set_options(StringTokenizer::RETURN_DELIMS); | 129 tokenier.set_options(StringTokenizer::RETURN_DELIMS); |
124 | 130 |
125 bool in_attribute = false; | 131 bool in_attribute = false; |
126 unsigned int last_attribute = 0; | 132 unsigned int last_attribute = 0; |
127 | 133 |
128 while (tokenier.GetNext()) { | 134 while (tokenier.GetNext()) { |
129 if (tokenier.token_is_delim()) { | 135 if (tokenier.token_is_delim()) { |
130 switch (*tokenier.token_begin()) { | 136 switch (*tokenier.token_begin()) { |
131 case '(': | 137 case '(': |
132 if (in_attribute) return false; | 138 if (in_attribute) { |
| 139 last_error_ = |
| 140 ASCIIToUTF16("Unexpected ( in attribute parameters."); |
| 141 return false; |
| 142 } |
133 in_attribute = true; | 143 in_attribute = true; |
134 continue; | 144 continue; |
135 case ')': | 145 case ')': |
136 if (!in_attribute) return false; | 146 if (!in_attribute) { |
| 147 last_error_ = ASCIIToUTF16("Unexpected ) in attribute list."); |
| 148 return false; |
| 149 } |
137 in_attribute = false; | 150 in_attribute = false; |
138 continue; | 151 continue; |
139 default: | 152 default: |
140 // No state change for other delimiters. | 153 // No state change for other delimiters. |
141 continue; | 154 continue; |
142 } | 155 } |
143 } | 156 } |
144 | 157 |
145 if (in_attribute) { | 158 if (in_attribute) { |
146 // The only attribute to support sub_tokens is kBlockByType, for now. | 159 // The only attribute to support sub_tokens is kBlockByType, for now. |
147 if (last_attribute == Blacklist::kBlockByType) | 160 if (last_attribute == Blacklist::kBlockByType) |
148 entry->AddType(tokenier.token()); | 161 entry->AddType(tokenier.token()); |
149 } else { | 162 } else { |
150 // Filter attribute. Unrecognized attributes are ignored. | 163 // Filter attribute. Unrecognized attributes are ignored. |
151 last_attribute = Blacklist::String2Attribute(tokenier.token()); | 164 last_attribute = Blacklist::String2Attribute(tokenier.token()); |
152 entry->AddAttributes(last_attribute); | 165 entry->AddAttributes(last_attribute); |
153 } | 166 } |
154 } | 167 } |
155 blacklist_.push_back(entry.release()); | 168 blacklist_.push_back(entry.release()); |
156 } | 169 } |
157 return true; | 170 return true; |
158 } | 171 } |
159 | 172 |
160 bool BlacklistIO::Write(const FilePath& file) { | 173 bool BlacklistIO::Write(const FilePath& file) { |
161 BlacklistStoreOutput output(file_util::OpenFile(file, "wb")); | 174 BlacklistStoreOutput output(file_util::OpenFile(file, "wb")); |
| 175 if (!output.is_good()) { |
| 176 last_error_ = ASCIIToUTF16("Error opening file for writing."); |
| 177 return false; |
| 178 } |
162 | 179 |
163 // Output providers, give each one an index. | 180 // Output providers, give each one an index. |
164 std::map<const Blacklist::Provider*, uint32> index; | 181 std::map<const Blacklist::Provider*, uint32> index; |
165 uint32 current = 0; | 182 uint32 current = 0; |
166 output.ReserveProviders(providers_.size()); | 183 if (!output.ReserveProviders(providers_.size())) { |
| 184 last_error_ = ASCIIToUTF16("Error writing to file."); |
| 185 return false; |
| 186 } |
| 187 |
167 for (std::list<Blacklist::Provider*>::const_iterator i = providers_.begin(); | 188 for (std::list<Blacklist::Provider*>::const_iterator i = providers_.begin(); |
168 i != providers_.end(); ++i, ++current) { | 189 i != providers_.end(); ++i, ++current) { |
169 output.StoreProvider((*i)->name(), (*i)->url()); | 190 if (!output.StoreProvider((*i)->name(), (*i)->url())) { |
| 191 last_error_ = ASCIIToUTF16("Error writing to file."); |
| 192 return false; |
| 193 } |
170 index[*i] = current; | 194 index[*i] = current; |
171 } | 195 } |
172 | 196 |
173 // Output entries, replacing the provider with its index. | 197 // Output entries, replacing the provider with its index. |
174 output.ReserveEntries(blacklist_.size()); | 198 if (!output.ReserveEntries(blacklist_.size())) { |
| 199 last_error_ = ASCIIToUTF16("Error writing to file."); |
| 200 return false; |
| 201 } |
| 202 |
175 for (std::list<Blacklist::Entry*>::const_iterator i = blacklist_.begin(); | 203 for (std::list<Blacklist::Entry*>::const_iterator i = blacklist_.begin(); |
176 i != blacklist_.end(); ++i) { | 204 i != blacklist_.end(); ++i) { |
177 output.StoreEntry((*i)->pattern_, | 205 if (!output.StoreEntry((*i)->pattern_, |
178 (*i)->attributes_, | 206 (*i)->attributes_, |
179 (*i)->types_, | 207 (*i)->types_, |
180 index[(*i)->provider_]); | 208 index[(*i)->provider_])) { |
| 209 last_error_ = ASCIIToUTF16("Error writing to file."); |
| 210 return false; |
| 211 } |
181 } | 212 } |
182 return true; | 213 return true; |
183 } | 214 } |
OLD | NEW |