| 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 |