OLD | NEW |
---|---|
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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/policy/preg_parser_win.h" | 5 #include "chrome/browser/policy/preg_parser_win.h" |
6 | 6 |
7 #include <windows.h> | 7 #include <windows.h> |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 #include <iterator> | 10 #include <iterator> |
11 #include <vector> | 11 #include <vector> |
12 | 12 |
13 #include "base/basictypes.h" | 13 #include "base/basictypes.h" |
14 #include "base/files/file_path.h" | 14 #include "base/files/file_path.h" |
15 #include "base/files/memory_mapped_file.h" | 15 #include "base/files/memory_mapped_file.h" |
16 #include "base/logging.h" | 16 #include "base/logging.h" |
17 #include "base/stl_util.h" | 17 #include "base/stl_util.h" |
18 #include "base/string16.h" | 18 #include "base/string16.h" |
19 #include "base/string_util.h" | 19 #include "base/string_util.h" |
20 #include "base/sys_byteorder.h" | 20 #include "base/sys_byteorder.h" |
21 #include "base/utf_string_conversions.h" | 21 #include "base/utf_string_conversions.h" |
22 #include "base/values.h" | 22 #include "base/values.h" |
23 #include "chrome/browser/policy/policy_load_status.h" | |
23 | 24 |
24 namespace policy { | 25 namespace policy { |
25 namespace preg_parser { | 26 namespace preg_parser { |
26 | 27 |
27 const char kPRegFileHeader[8] = | 28 const char kPRegFileHeader[8] = |
28 { 'P', 'R', 'e', 'g', '\x01', '\x00', '\x00', '\x00' }; | 29 { 'P', 'R', 'e', 'g', '\x01', '\x00', '\x00', '\x00' }; |
Joao da Silva
2013/04/16 19:32:57
Why did you revert this in the 2nd patch set?
Mattias Nissler (ping if slow)
2013/04/17 10:16:35
I didn't revert. The second patch set is rebased o
| |
29 | 30 |
30 // Maximum PReg file size we're willing to accept. | 31 // Maximum PReg file size we're willing to accept. |
31 const int64 kMaxPRegFileSize = 1024 * 1024 * 16; | 32 const int64 kMaxPRegFileSize = 1024 * 1024 * 16; |
32 | 33 |
33 // Constants for PReg file delimiters. | 34 // Constants for PReg file delimiters. |
34 const char16 kDelimBracketOpen = L'['; | 35 const char16 kDelimBracketOpen = L'['; |
35 const char16 kDelimBracketClose = L']'; | 36 const char16 kDelimBracketClose = L']'; |
36 const char16 kDelimSemicolon = L';'; | 37 const char16 kDelimSemicolon = L';'; |
37 | 38 |
38 // Registry path separator. | 39 // Registry path separator. |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
208 } else if (StartsWithASCII(action_trigger, kActionTriggerSecureKey, true) || | 209 } else if (StartsWithASCII(action_trigger, kActionTriggerSecureKey, true) || |
209 StartsWithASCII(action_trigger, kActionTriggerSoft, true)) { | 210 StartsWithASCII(action_trigger, kActionTriggerSoft, true)) { |
210 // Doesn't affect values. | 211 // Doesn't affect values. |
211 } else { | 212 } else { |
212 LOG(ERROR) << "Bad action trigger " << value_name; | 213 LOG(ERROR) << "Bad action trigger " << value_name; |
213 } | 214 } |
214 } | 215 } |
215 | 216 |
216 bool ReadFile(const base::FilePath& file_path, | 217 bool ReadFile(const base::FilePath& file_path, |
217 const string16& root, | 218 const string16& root, |
218 base::DictionaryValue* dict) { | 219 base::DictionaryValue* dict, |
220 PolicyLoadStatusSample* status) { | |
219 base::MemoryMappedFile mapped_file; | 221 base::MemoryMappedFile mapped_file; |
220 if (!mapped_file.Initialize(file_path) || !mapped_file.IsValid()) { | 222 if (!mapped_file.Initialize(file_path) || !mapped_file.IsValid()) { |
221 PLOG(ERROR) << "Failed to map " << file_path.value(); | 223 PLOG(ERROR) << "Failed to map " << file_path.value(); |
224 status->Add(POLICY_LOAD_STATUS_READ_ERROR); | |
222 return false; | 225 return false; |
223 } | 226 } |
224 | 227 |
225 if (mapped_file.length() > kMaxPRegFileSize) { | 228 if (mapped_file.length() > kMaxPRegFileSize) { |
226 LOG(ERROR) << "PReg file " << file_path.value() << " too large: " | 229 LOG(ERROR) << "PReg file " << file_path.value() << " too large: " |
227 << mapped_file.length(); | 230 << mapped_file.length(); |
231 status->Add(POLICY_LOAD_STATUS_TOO_BIG); | |
228 return false; | 232 return false; |
229 } | 233 } |
230 | 234 |
231 // Check the header. | 235 // Check the header. |
232 const int kHeaderSize = arraysize(kPRegFileHeader); | 236 const int kHeaderSize = arraysize(kPRegFileHeader); |
233 if (mapped_file.length() < kHeaderSize || | 237 if (mapped_file.length() < kHeaderSize || |
234 memcmp(kPRegFileHeader, mapped_file.data(), kHeaderSize) != 0) { | 238 memcmp(kPRegFileHeader, mapped_file.data(), kHeaderSize) != 0) { |
235 LOG(ERROR) << "Bad policy file " << file_path.value(); | 239 LOG(ERROR) << "Bad policy file " << file_path.value(); |
240 status->Add(POLICY_LOAD_STATUS_PARSE_ERROR); | |
236 return false; | 241 return false; |
237 } | 242 } |
238 | 243 |
239 // Parse file contents, which is UCS-2 and little-endian. The latter I | 244 // Parse file contents, which is UCS-2 and little-endian. The latter I |
240 // couldn't find documentation on, but the example I saw were all | 245 // couldn't find documentation on, but the example I saw were all |
241 // little-endian. It'd be interesting to check on big-endian hardware. | 246 // little-endian. It'd be interesting to check on big-endian hardware. |
242 const uint8* cursor = mapped_file.data() + kHeaderSize; | 247 const uint8* cursor = mapped_file.data() + kHeaderSize; |
243 const uint8* end = mapped_file.data() + mapped_file.length(); | 248 const uint8* end = mapped_file.data() + mapped_file.length(); |
244 while (true) { | 249 while (true) { |
245 if (cursor == end) | 250 if (cursor == end) |
(...skipping 27 matching lines...) Expand all Loading... | |
273 | 278 |
274 if (current == kDelimSemicolon) { | 279 if (current == kDelimSemicolon) { |
275 if (!ReadField32(&cursor, end, &size)) | 280 if (!ReadField32(&cursor, end, &size)) |
276 break; | 281 break; |
277 current = NextChar(&cursor, end); | 282 current = NextChar(&cursor, end); |
278 } | 283 } |
279 | 284 |
280 if (current == kDelimSemicolon) { | 285 if (current == kDelimSemicolon) { |
281 if (size > kMaxPRegFileSize) | 286 if (size > kMaxPRegFileSize) |
282 break; | 287 break; |
283 data.resize(size); | 288 data.resize(size); |
Joao da Silva
2013/04/16 17:31:04
This escaped the first code review: my concern bac
Mattias Nissler (ping if slow)
2013/04/16 18:51:14
The kMaxPRegFileSize check two lines above should
Joao da Silva
2013/04/16 19:32:57
Looking at this again I now see the size check in
| |
284 if (!ReadFieldBinary(&cursor, end, size, vector_as_array(&data))) | 289 if (!ReadFieldBinary(&cursor, end, size, vector_as_array(&data))) |
285 break; | 290 break; |
286 current = NextChar(&cursor, end); | 291 current = NextChar(&cursor, end); |
287 } | 292 } |
288 | 293 |
289 if (current != kDelimBracketClose) | 294 if (current != kDelimBracketClose) |
290 break; | 295 break; |
291 | 296 |
292 // Process the record if it is within the |root| subtree. | 297 // Process the record if it is within the |root| subtree. |
293 if (StartsWith(key_name, root, false)) | 298 if (StartsWith(key_name, root, false)) |
294 HandleRecord(key_name.substr(root.size()), value, type, data, dict); | 299 HandleRecord(key_name.substr(root.size()), value, type, data, dict); |
295 } | 300 } |
296 | 301 |
297 LOG(ERROR) << "Error parsing " << file_path.value() << " at offset " | 302 LOG(ERROR) << "Error parsing " << file_path.value() << " at offset " |
298 << reinterpret_cast<const uint8*>(cursor - 1) - mapped_file.data(); | 303 << reinterpret_cast<const uint8*>(cursor - 1) - mapped_file.data(); |
304 status->Add(POLICY_LOAD_STATUS_PARSE_ERROR); | |
299 return false; | 305 return false; |
300 } | 306 } |
301 | 307 |
302 } // namespace preg_parser | 308 } // namespace preg_parser |
303 } // namespace policy | 309 } // namespace policy |
OLD | NEW |