| 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 "components/policy/core/common/preg_parser.h" | 5 #include "components/policy/core/common/preg_parser.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include <algorithm> | 10 #include <algorithm> |
| (...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 287 | 287 |
| 288 namespace policy { | 288 namespace policy { |
| 289 namespace preg_parser { | 289 namespace preg_parser { |
| 290 | 290 |
| 291 const char kPRegFileHeader[8] = {'P', 'R', 'e', 'g', | 291 const char kPRegFileHeader[8] = {'P', 'R', 'e', 'g', |
| 292 '\x01', '\x00', '\x00', '\x00'}; | 292 '\x01', '\x00', '\x00', '\x00'}; |
| 293 | 293 |
| 294 bool ReadFile(const base::FilePath& file_path, | 294 bool ReadFile(const base::FilePath& file_path, |
| 295 const base::string16& root, | 295 const base::string16& root, |
| 296 RegistryDict* dict, | 296 RegistryDict* dict, |
| 297 PolicyLoadStatusSample* status_sample) { | 297 PolicyLoadStatusSampler* status) { |
| 298 base::MemoryMappedFile mapped_file; | 298 base::MemoryMappedFile mapped_file; |
| 299 if (!mapped_file.Initialize(file_path) || !mapped_file.IsValid()) { | 299 if (!mapped_file.Initialize(file_path) || !mapped_file.IsValid()) { |
| 300 PLOG(ERROR) << "Failed to map " << file_path.value(); | 300 PLOG(ERROR) << "Failed to map " << file_path.value(); |
| 301 status_sample->Add(POLICY_LOAD_STATUS_READ_ERROR); | 301 status->Add(POLICY_LOAD_STATUS_READ_ERROR); |
| 302 return false; | 302 return false; |
| 303 } | 303 } |
| 304 | 304 |
| 305 PolicyLoadStatus status = POLICY_LOAD_STATUS_SIZE; | 305 return ReadDataInternal( |
| 306 bool res = ReadDataInternal( | 306 mapped_file.data(), mapped_file.length(), root, dict, status, |
| 307 mapped_file.data(), mapped_file.length(), root, dict, &status, | |
| 308 base::StringPrintf("file '%s'", file_path.value().c_str())); | 307 base::StringPrintf("file '%s'", file_path.value().c_str())); |
| 309 if (!res) { | |
| 310 DCHECK(status != POLICY_LOAD_STATUS_SIZE); | |
| 311 status_sample->Add(status); | |
| 312 } | |
| 313 return res; | |
| 314 } | 308 } |
| 315 | 309 |
| 316 POLICY_EXPORT bool ReadDataInternal(const uint8_t* preg_data, | 310 POLICY_EXPORT bool ReadDataInternal(const uint8_t* preg_data, |
| 317 size_t preg_data_size, | 311 size_t preg_data_size, |
| 318 const base::string16& root, | 312 const base::string16& root, |
| 319 RegistryDict* dict, | 313 RegistryDict* dict, |
| 320 PolicyLoadStatus* status, | 314 PolicyLoadStatusSampler* status, |
| 321 const std::string& debug_name) { | 315 const std::string& debug_name) { |
| 322 DCHECK(status); | 316 DCHECK(status); |
| 323 DCHECK(root.empty() || root.back() != kRegistryPathSeparator[0]); | 317 DCHECK(root.empty() || root.back() != kRegistryPathSeparator[0]); |
| 324 | 318 |
| 325 // Check data size. | 319 // Check data size. |
| 326 if (preg_data_size > kMaxPRegFileSize) { | 320 if (preg_data_size > kMaxPRegFileSize) { |
| 327 LOG(ERROR) << "PReg " << debug_name << " too large: " << preg_data_size; | 321 LOG(ERROR) << "PReg " << debug_name << " too large: " << preg_data_size; |
| 328 *status = POLICY_LOAD_STATUS_TOO_BIG; | 322 status->Add(POLICY_LOAD_STATUS_TOO_BIG); |
| 329 return false; | 323 return false; |
| 330 } | 324 } |
| 331 | 325 |
| 332 // Check the header. | 326 // Check the header. |
| 333 const int kHeaderSize = arraysize(kPRegFileHeader); | 327 const int kHeaderSize = arraysize(kPRegFileHeader); |
| 334 if (!preg_data || preg_data_size < kHeaderSize || | 328 if (!preg_data || preg_data_size < kHeaderSize || |
| 335 memcmp(kPRegFileHeader, preg_data, kHeaderSize) != 0) { | 329 memcmp(kPRegFileHeader, preg_data, kHeaderSize) != 0) { |
| 336 LOG(ERROR) << "Bad PReg " << debug_name; | 330 LOG(ERROR) << "Bad PReg " << debug_name; |
| 337 *status = POLICY_LOAD_STATUS_PARSE_ERROR; | 331 status->Add(POLICY_LOAD_STATUS_PARSE_ERROR); |
| 338 return false; | 332 return false; |
| 339 } | 333 } |
| 340 | 334 |
| 341 // Parse data, which is expected to be UCS-2 and little-endian. The latter I | 335 // Parse data, which is expected to be UCS-2 and little-endian. The latter I |
| 342 // couldn't find documentation on, but the example I saw were all | 336 // couldn't find documentation on, but the example I saw were all |
| 343 // little-endian. It'd be interesting to check on big-endian hardware. | 337 // little-endian. It'd be interesting to check on big-endian hardware. |
| 344 const uint8_t* cursor = preg_data + kHeaderSize; | 338 const uint8_t* cursor = preg_data + kHeaderSize; |
| 345 const uint8_t* end = preg_data + preg_data_size; | 339 const uint8_t* end = preg_data + preg_data_size; |
| 346 while (true) { | 340 while (true) { |
| 347 if (cursor == end) | 341 if (cursor == end) |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 391 if (current != kDelimBracketClose) | 385 if (current != kDelimBracketClose) |
| 392 break; | 386 break; |
| 393 | 387 |
| 394 // Process the record if it is within the |root| subtree. | 388 // Process the record if it is within the |root| subtree. |
| 395 if (KeyRootEquals(key_name, root)) | 389 if (KeyRootEquals(key_name, root)) |
| 396 HandleRecord(key_name.substr(root.size()), value, type, data, dict); | 390 HandleRecord(key_name.substr(root.size()), value, type, data, dict); |
| 397 } | 391 } |
| 398 | 392 |
| 399 LOG(ERROR) << "Error parsing PReg " << debug_name << " at offset " | 393 LOG(ERROR) << "Error parsing PReg " << debug_name << " at offset " |
| 400 << (reinterpret_cast<const uint8_t*>(cursor - 1) - preg_data); | 394 << (reinterpret_cast<const uint8_t*>(cursor - 1) - preg_data); |
| 401 *status = POLICY_LOAD_STATUS_PARSE_ERROR; | 395 status->Add(POLICY_LOAD_STATUS_PARSE_ERROR); |
| 402 return false; | 396 return false; |
| 403 } | 397 } |
| 404 | 398 |
| 405 } // namespace preg_parser | 399 } // namespace preg_parser |
| 406 } // namespace policy | 400 } // namespace policy |
| OLD | NEW |