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

Unified Diff: trunk/src/chrome/installer/util/registry_key_backup.cc

Issue 14330007: Revert 194643 "Remove scoped_array usage from RegistryKeyBackup." (Closed) Base URL: svn://svn.chromium.org/chrome/
Patch Set: Created 7 years, 8 months 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: trunk/src/chrome/installer/util/registry_key_backup.cc
===================================================================
--- trunk/src/chrome/installer/util/registry_key_backup.cc (revision 194653)
+++ trunk/src/chrome/installer/util/registry_key_backup.cc (working copy)
@@ -5,8 +5,7 @@
#include "chrome/installer/util/registry_key_backup.h"
#include <algorithm>
-#include <map>
-#include <utility>
+#include <limits>
#include <vector>
#include "base/logging.h"
@@ -15,11 +14,47 @@
using base::win::RegKey;
namespace {
-
const REGSAM kKeyReadNoNotify = (KEY_READ) & ~(KEY_NOTIFY);
+} // namespace
+// A container for a registry key, its values, and its subkeys.
+class RegistryKeyBackup::KeyData {
+ public:
+ KeyData();
+ ~KeyData();
+
+ // Initializes this object by reading the values and subkeys of |key|.
+ // Security descriptors are not backed up. Returns true if the operation was
+ // successful; false otherwise, in which case the state of this object is not
+ // modified.
+ bool Initialize(const RegKey& key);
+
+ // Writes the contents of this object to |key|, which must have been opened
+ // with at least REG_SET_VALUE and KEY_CREATE_SUB_KEY access rights. Returns
+ // true if the operation was successful; false otherwise, in which case the
+ // contents of |key| may have been modified.
+ bool WriteTo(RegKey* key) const;
+
+ private:
+ class ValueData;
+
+ // The values of this key.
+ scoped_array<ValueData> values_;
+ // The names of this key's sub-keys (the data for subkey_names_[i] is in
+ // subkeys_[i]).
+ scoped_array<std::wstring> subkey_names_;
+ // The key data of this key's sub-keys.
+ scoped_array<KeyData> subkeys_;
+ // The number of values for this key.
+ DWORD num_values_;
+ // The number of subkeys for this key.
+ DWORD num_subkeys_;
+
+ DISALLOW_COPY_AND_ASSIGN(KeyData);
+};
+
// A container for a registry value.
-class ValueData {
+class RegistryKeyBackup::KeyData::ValueData {
public:
ValueData();
~ValueData();
@@ -54,45 +89,18 @@
// This value's type (e.g., REG_DWORD, REG_SZ, REG_QWORD, etc).
DWORD type_;
- // Copy constructible and assignable for use in STL containers.
+ DISALLOW_COPY_AND_ASSIGN(ValueData);
};
-} // namespace
-
-// A container for a registry key, its values, and its subkeys.
-class RegistryKeyBackup::KeyData {
- public:
- KeyData();
- ~KeyData();
-
- // Initializes this object by reading the values and subkeys of |key|.
- // Security descriptors are not backed up. Returns true if the operation was
- // successful; false otherwise, in which case the state of this object is not
- // modified.
- bool Initialize(const RegKey& key);
-
- // Writes the contents of this object to |key|, which must have been opened
- // with at least REG_SET_VALUE and KEY_CREATE_SUB_KEY access rights. Returns
- // true if the operation was successful; false otherwise, in which case the
- // contents of |key| may have been modified.
- bool WriteTo(RegKey* key) const;
-
- private:
- // The values of this key.
- std::vector<ValueData> values_;
- // Map of subkey names to the corresponding KeyData.
- std::map<std::wstring, KeyData> subkeys_;
-
- // Copy constructible and assignable for use in STL containers.
-};
-
-ValueData::ValueData() : type_(REG_NONE) {
+RegistryKeyBackup::KeyData::ValueData::ValueData()
+ : type_(REG_NONE) {
}
-ValueData::~ValueData() {
+RegistryKeyBackup::KeyData::ValueData::~ValueData()
+{
}
-void ValueData::Initialize(
+void RegistryKeyBackup::KeyData::ValueData::Initialize(
const wchar_t* name_buffer,
DWORD name_size,
DWORD type,
@@ -103,15 +111,19 @@
data_.assign(data, data + data_size);
}
-RegistryKeyBackup::KeyData::KeyData() {
+RegistryKeyBackup::KeyData::KeyData()
+ : num_values_(0),
+ num_subkeys_(0) {
}
-RegistryKeyBackup::KeyData::~KeyData() {
+RegistryKeyBackup::KeyData::~KeyData()
+{
}
bool RegistryKeyBackup::KeyData::Initialize(const RegKey& key) {
- std::vector<ValueData> values;
- std::map<std::wstring, KeyData> subkeys;
+ scoped_array<ValueData> values;
+ scoped_array<std::wstring> subkey_names;
+ scoped_array<KeyData> subkeys;
DWORD num_subkeys = 0;
DWORD max_subkey_name_len = 0;
@@ -126,38 +138,52 @@
LOG(ERROR) << "Failed getting info of key to backup, result: " << result;
return false;
}
+ if (max_subkey_name_len >= std::numeric_limits<DWORD>::max() - 1 ||
+ max_value_name_len >= std::numeric_limits<DWORD>::max() - 1) {
+ LOG(ERROR)
+ << "Failed backing up key; subkeys and/or names are out of range.";
+ return false;
+ }
DWORD max_name_len = std::max(max_subkey_name_len, max_value_name_len) + 1;
- std::vector<wchar_t> name_buffer(max_name_len);
+ scoped_array<wchar_t> name_buffer(new wchar_t[max_name_len]);
// Backup the values.
if (num_values != 0) {
- values.reserve(num_values);
- std::vector<uint8> value_buffer(max_value_len != 0 ? max_value_len : 1);
+ values.reset(new ValueData[num_values]);
+ scoped_array<uint8> value_buffer(new uint8[max_value_len]);
DWORD name_size = 0;
DWORD value_type = REG_NONE;
DWORD value_size = 0;
for (DWORD i = 0; i < num_values; ) {
- name_size = name_buffer.size();
- value_size = value_buffer.size();
- result = RegEnumValue(key.Handle(), i, &name_buffer[0], &name_size,
- NULL, &value_type, &value_buffer[0], &value_size);
+ name_size = max_name_len;
+ value_size = max_value_len;
+ result = RegEnumValue(key.Handle(), i, name_buffer.get(), &name_size,
+ NULL, &value_type, value_buffer.get(), &value_size);
switch (result) {
case ERROR_NO_MORE_ITEMS:
num_values = i;
break;
case ERROR_SUCCESS:
- values.push_back(ValueData());
- values.back().Initialize(&name_buffer[0], name_size, value_type,
- &value_buffer[0], value_size);
+ values[i].Initialize(name_buffer.get(), name_size, value_type,
+ value_buffer.get(), value_size);
++i;
break;
case ERROR_MORE_DATA:
- if (value_size > value_buffer.size())
- value_buffer.resize(value_size);
- // |name_size| does not include space for the terminating NULL.
- if (name_size + 1 > name_buffer.size())
- name_buffer.resize(name_size + 1);
+ if (value_size > max_value_len) {
+ max_value_len = value_size;
+ value_buffer.reset(); // Release to heap before new allocation.
+ value_buffer.reset(new uint8[max_value_len]);
+ } else {
+ DCHECK_LT(max_name_len - 1, name_size);
+ if (name_size >= std::numeric_limits<DWORD>::max() - 1) {
+ LOG(ERROR) << "Failed backing up key; value name out of range.";
+ return false;
+ }
+ max_name_len = name_size + 1;
+ name_buffer.reset(); // Release to heap before new allocation.
+ name_buffer.reset(new wchar_t[max_name_len]);
+ }
break;
default:
LOG(ERROR) << "Failed backing up value " << i << ", result: "
@@ -165,7 +191,7 @@
return false;
}
}
- DLOG_IF(WARNING, RegEnumValue(key.Handle(), num_values, &name_buffer[0],
+ DLOG_IF(WARNING, RegEnumValue(key.Handle(), num_values, name_buffer.get(),
&name_size, NULL, &value_type, NULL,
NULL) != ERROR_NO_MORE_ITEMS)
<< "Concurrent modifications to registry key during backup operation.";
@@ -173,23 +199,30 @@
// Backup the subkeys.
if (num_subkeys != 0) {
+ subkey_names.reset(new std::wstring[num_subkeys]);
+ subkeys.reset(new KeyData[num_subkeys]);
DWORD name_size = 0;
// Get the names of them.
for (DWORD i = 0; i < num_subkeys; ) {
- name_size = name_buffer.size();
- result = RegEnumKeyEx(key.Handle(), i, &name_buffer[0], &name_size,
+ name_size = max_name_len;
+ result = RegEnumKeyEx(key.Handle(), i, name_buffer.get(), &name_size,
NULL, NULL, NULL, NULL);
switch (result) {
case ERROR_NO_MORE_ITEMS:
num_subkeys = i;
break;
case ERROR_SUCCESS:
- subkeys.insert(std::make_pair(&name_buffer[0], KeyData()));
+ subkey_names[i].assign(name_buffer.get(), name_size);
++i;
break;
case ERROR_MORE_DATA:
- name_buffer.resize(name_size + 1);
+ if (name_size >= std::numeric_limits<DWORD>::max() - 1) {
+ LOG(ERROR) << "Failed backing up key; subkey name out of range.";
+ return false;
+ }
+ max_name_len = name_size + 1;
+ name_buffer.reset(new wchar_t[max_name_len]);
break;
default:
LOG(ERROR) << "Failed getting name of subkey " << i
@@ -204,23 +237,26 @@
// Get their values.
RegKey subkey;
- for (std::map<std::wstring, KeyData>::iterator it = subkeys.begin();
- it != subkeys.end(); ++it) {
- result = subkey.Open(key.Handle(), it->first.c_str(), kKeyReadNoNotify);
+ for (DWORD i = 0; i < num_subkeys; ++i) {
+ result = subkey.Open(key.Handle(), subkey_names[i].c_str(),
+ kKeyReadNoNotify);
if (result != ERROR_SUCCESS) {
- LOG(ERROR) << "Failed opening subkey \"" << it->first
+ LOG(ERROR) << "Failed opening subkey \"" << subkey_names[i]
<< "\" for backup, result: " << result;
return false;
}
- if (!it->second.Initialize(subkey)) {
- LOG(ERROR) << "Failed backing up subkey \"" << it->first << "\"";
+ if (!subkeys[i].Initialize(subkey)) {
+ LOG(ERROR) << "Failed backing up subkey \"" << subkey_names[i] << "\"";
return false;
}
}
}
values_.swap(values);
+ subkey_names_.swap(subkey_names);
subkeys_.swap(subkeys);
+ num_values_ = num_values;
+ num_subkeys_ = num_subkeys;
return true;
}
@@ -231,9 +267,8 @@
LONG result = ERROR_SUCCESS;
// Write the values.
- for (std::vector<ValueData>::const_iterator it = values_.begin();
- it != values_.end(); ++it) {
- const ValueData& value = *it;
+ for (DWORD i = 0; i < num_values_; ++i) {
+ const ValueData& value = values_[i];
result = RegSetValueEx(key->Handle(), value.name(), 0, value.type(),
value.data(), value.data_len());
if (result != ERROR_SUCCESS) {
@@ -245,9 +280,8 @@
// Write the subkeys.
RegKey subkey;
- for (std::map<std::wstring, KeyData>::const_iterator it = subkeys_.begin();
- it != subkeys_.end(); ++it) {
- const std::wstring& name = it->first;
+ for (DWORD i = 0; i < num_subkeys_; ++i) {
+ const std::wstring& name = subkey_names_[i];
result = subkey.Create(key->Handle(), name.c_str(), KEY_WRITE);
if (result != ERROR_SUCCESS) {
@@ -255,7 +289,7 @@
<< result;
return false;
}
- if (!it->second.WriteTo(&subkey)) {
+ if (!subkeys_[i].WriteTo(&subkey)) {
LOG(ERROR) << "Failed writing subkey \"" << name << "\", result: "
<< result;
return false;
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698