Eliminate usage of vector<>[0] for 0-sized vectors in processor library (#84).

r=bryner

8eb9277ac0


git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@72 4c0a9323-5329-0410-9bdc-e9ce6186880e
This commit is contained in:
mmentovai 2006-11-27 21:42:07 +00:00
parent c297c50f83
commit 373c49b416

View file

@ -643,6 +643,9 @@ const u_int8_t* MinidumpMemoryRegion::GetMemory() {
return NULL; return NULL;
if (!memory_) { if (!memory_) {
if (descriptor_->memory.data_size == 0)
return NULL;
if (!minidump_->SeekSet(descriptor_->memory.rva)) if (!minidump_->SeekSet(descriptor_->memory.rva))
return NULL; return NULL;
@ -920,31 +923,34 @@ bool MinidumpThreadList::Read(u_int32_t expected_size) {
return false; return false;
} }
// TODO(mmentovai): verify rational size! if (thread_count) {
scoped_ptr<MinidumpThreads> threads( // TODO(mmentovai): verify rational size!
new MinidumpThreads(thread_count, MinidumpThread(minidump_))); scoped_ptr<MinidumpThreads> threads(
new MinidumpThreads(thread_count, MinidumpThread(minidump_)));
for (unsigned int thread_index = 0; for (unsigned int thread_index = 0;
thread_index < thread_count; thread_index < thread_count;
++thread_index) { ++thread_index) {
MinidumpThread* thread = &(*threads)[thread_index]; MinidumpThread* thread = &(*threads)[thread_index];
// Assume that the file offset is correct after the last read. // Assume that the file offset is correct after the last read.
if (!thread->Read()) if (!thread->Read())
return false; return false;
u_int32_t thread_id; u_int32_t thread_id;
if (!thread->GetThreadID(&thread_id)) if (!thread->GetThreadID(&thread_id))
return false; return false;
if (GetThreadByID(thread_id)) { if (GetThreadByID(thread_id)) {
// Another thread with this ID is already in the list. Data error. // Another thread with this ID is already in the list. Data error.
return false; return false;
}
id_to_thread_map_[thread_id] = thread;
} }
id_to_thread_map_[thread_id] = thread;
threads_ = threads.release();
} }
threads_ = threads.release();
thread_count_ = thread_count; thread_count_ = thread_count;
valid_ = true; valid_ = true;
@ -1275,7 +1281,8 @@ const string* MinidumpModule::GetDebugFilename() {
// UTF16ToUTF8 expects a vector<u_int16_t>, so create a temporary one and // UTF16ToUTF8 expects a vector<u_int16_t>, so create a temporary one and
// copy the UTF-16 data into it. // copy the UTF-16 data into it.
vector<u_int16_t> string_utf16(utf16_words); vector<u_int16_t> string_utf16(utf16_words);
memcpy(&string_utf16[0], &misc_record->data, bytes); if (utf16_words)
memcpy(&string_utf16[0], &misc_record->data, bytes);
// GetMiscRecord already byte-swapped the data[] field if it contains // GetMiscRecord already byte-swapped the data[] field if it contains
// UTF-16, so pass false as the swap argument. // UTF-16, so pass false as the swap argument.
@ -1451,29 +1458,32 @@ bool MinidumpModuleList::Read(u_int32_t expected_size) {
return false; return false;
} }
// TODO(mmentovai): verify rational size! if (module_count) {
scoped_ptr<MinidumpModules> modules( // TODO(mmentovai): verify rational size!
new MinidumpModules(module_count, MinidumpModule(minidump_))); scoped_ptr<MinidumpModules> modules(
new MinidumpModules(module_count, MinidumpModule(minidump_)));
for (unsigned int module_index = 0; for (unsigned int module_index = 0;
module_index < module_count; module_index < module_count;
++module_index) { ++module_index) {
MinidumpModule* module = &(*modules)[module_index]; MinidumpModule* module = &(*modules)[module_index];
// Assume that the file offset is correct after the last read. // Assume that the file offset is correct after the last read.
if (!module->Read()) if (!module->Read())
return false; return false;
u_int64_t base_address = module->base_address(); u_int64_t base_address = module->base_address();
u_int64_t module_size = module->size(); u_int64_t module_size = module->size();
if (base_address == (u_int64_t)-1) if (base_address == static_cast<u_int64_t>(-1))
return false; return false;
if (!range_map_->StoreRange(base_address, module_size, module_index)) if (!range_map_->StoreRange(base_address, module_size, module_index))
return false; return false;
}
modules_ = modules.release();
} }
modules_ = modules.release();
module_count_ = module_count; module_count_ = module_count;
valid_ = true; valid_ = true;
@ -1566,46 +1576,49 @@ bool MinidumpMemoryList::Read(u_int32_t expected_size) {
return false; return false;
} }
// TODO(mmentovai): verify rational size! if (region_count) {
scoped_ptr<MemoryDescriptors> descriptors( // TODO(mmentovai): verify rational size!
new MemoryDescriptors(region_count)); scoped_ptr<MemoryDescriptors> descriptors(
new MemoryDescriptors(region_count));
// Read the entire array in one fell swoop, instead of reading one entry // Read the entire array in one fell swoop, instead of reading one entry
// at a time in the loop. // at a time in the loop.
if (!minidump_->ReadBytes(&(*descriptors)[0], if (!minidump_->ReadBytes(&(*descriptors)[0],
sizeof(MDMemoryDescriptor) * region_count)) { sizeof(MDMemoryDescriptor) * region_count)) {
return false;
}
scoped_ptr<MemoryRegions> regions(
new MemoryRegions(region_count, MinidumpMemoryRegion(minidump_)));
for (unsigned int region_index = 0;
region_index < region_count;
++region_index) {
MDMemoryDescriptor* descriptor = &(*descriptors)[region_index];
if (minidump_->swap())
Swap(&*descriptor);
u_int64_t base_address = descriptor->start_of_memory_range;
u_int32_t region_size = descriptor->memory.data_size;
// Check for base + size overflow or undersize. A separate size==0
// check is needed in case base == 0.
u_int64_t high_address = base_address + region_size - 1;
if (region_size == 0 || high_address < base_address)
return false; return false;
}
if (!range_map_->StoreRange(base_address, region_size, region_index)) scoped_ptr<MemoryRegions> regions(
return false; new MemoryRegions(region_count, MinidumpMemoryRegion(minidump_)));
(*regions)[region_index].SetDescriptor(descriptor); for (unsigned int region_index = 0;
region_index < region_count;
++region_index) {
MDMemoryDescriptor* descriptor = &(*descriptors)[region_index];
if (minidump_->swap())
Swap(descriptor);
u_int64_t base_address = descriptor->start_of_memory_range;
u_int32_t region_size = descriptor->memory.data_size;
// Check for base + size overflow or undersize. A separate size==0
// check is needed in case base == 0.
u_int64_t high_address = base_address + region_size - 1;
if (region_size == 0 || high_address < base_address)
return false;
if (!range_map_->StoreRange(base_address, region_size, region_index))
return false;
(*regions)[region_index].SetDescriptor(descriptor);
}
descriptors_ = descriptors.release();
regions_ = regions.release();
} }
region_count_ = region_count; region_count_ = region_count;
descriptors_ = descriptors.release();
regions_ = regions.release();
valid_ = true; valid_ = true;
return true; return true;
@ -2110,7 +2123,7 @@ void MinidumpAirbagInfo::Print() {
Minidump::Minidump(const string& path) Minidump::Minidump(const string& path)
: header_(), : header_(),
directory_(NULL), directory_(NULL),
stream_map_(NULL), stream_map_(new MinidumpStreamMap()),
path_(path), path_(path),
fd_(-1), fd_(-1),
swap_(false), swap_(false),
@ -2147,8 +2160,7 @@ bool Minidump::Read() {
// Invalidate cached data. // Invalidate cached data.
delete directory_; delete directory_;
directory_ = NULL; directory_ = NULL;
delete stream_map_; stream_map_->clear();
stream_map_ = NULL;
valid_ = false; valid_ = false;
@ -2195,57 +2207,56 @@ bool Minidump::Read() {
if (!SeekSet(header_.stream_directory_rva)) if (!SeekSet(header_.stream_directory_rva))
return false; return false;
// TODO(mmentovai): verify rational size! if (header_.stream_count) {
scoped_ptr<MinidumpDirectoryEntries> directory( // TODO(mmentovai): verify rational size!
new MinidumpDirectoryEntries(header_.stream_count)); scoped_ptr<MinidumpDirectoryEntries> directory(
new MinidumpDirectoryEntries(header_.stream_count));
// Read the entire array in one fell swoop, instead of reading one entry // Read the entire array in one fell swoop, instead of reading one entry
// at a time in the loop. // at a time in the loop.
if (!ReadBytes(&(*directory)[0], if (!ReadBytes(&(*directory)[0],
sizeof(MDRawDirectory) * header_.stream_count)) sizeof(MDRawDirectory) * header_.stream_count))
return false; return false;
scoped_ptr<MinidumpStreamMap> stream_map(new MinidumpStreamMap()); for (unsigned int stream_index = 0;
stream_index < header_.stream_count;
++stream_index) {
MDRawDirectory* directory_entry = &(*directory)[stream_index];
for (unsigned int stream_index = 0; if (swap_) {
stream_index < header_.stream_count; Swap(&directory_entry->stream_type);
++stream_index) { Swap(&directory_entry->location);
MDRawDirectory* directory_entry = &(*directory)[stream_index]; }
if (swap_) { // Initialize the stream_map_ map, which speeds locating a stream by
Swap(&directory_entry->stream_type); // type.
Swap(&directory_entry->location); unsigned int stream_type = directory_entry->stream_type;
} switch (stream_type) {
case MD_THREAD_LIST_STREAM:
// Initialize the stream_map map, which speeds locating a stream by case MD_MODULE_LIST_STREAM:
// type. case MD_MEMORY_LIST_STREAM:
unsigned int stream_type = directory_entry->stream_type; case MD_EXCEPTION_STREAM:
switch (stream_type) { case MD_SYSTEM_INFO_STREAM:
case MD_THREAD_LIST_STREAM: case MD_MISC_INFO_STREAM:
case MD_MODULE_LIST_STREAM: case MD_AIRBAG_INFO_STREAM: {
case MD_MEMORY_LIST_STREAM: if (stream_map_->find(stream_type) != stream_map_->end()) {
case MD_EXCEPTION_STREAM: // Another stream with this type was already found. A minidump
case MD_SYSTEM_INFO_STREAM: // file should contain at most one of each of these stream types.
case MD_MISC_INFO_STREAM: return false;
case MD_AIRBAG_INFO_STREAM: { }
if (stream_map->find(stream_type) != stream_map->end()) { // Fall through to default
// Another stream with this type was already found. A minidump
// file should contain at most one of each of these stream types.
return false;
} }
// Fall through to default
}
default: { default: {
// Overwrites for stream types other than those above, but it's // Overwrites for stream types other than those above, but it's
// expected to be the user's burden in that case. // expected to be the user's burden in that case.
(*stream_map)[stream_type].stream_index = stream_index; (*stream_map_)[stream_type].stream_index = stream_index;
}
} }
} }
}
directory_ = directory.release(); directory_ = directory.release();
stream_map_ = stream_map.release(); }
valid_ = true; valid_ = true;
return true; return true;
@ -2391,8 +2402,11 @@ string* Minidump::ReadString(off_t offset) {
// TODO(mmentovai): verify rational size! // TODO(mmentovai): verify rational size!
vector<u_int16_t> string_utf16(utf16_words); vector<u_int16_t> string_utf16(utf16_words);
if (!ReadBytes(&string_utf16[0], bytes)) if (utf16_words) {
return NULL; if (!ReadBytes(&string_utf16[0], bytes)) {
return NULL;
}
}
return UTF16ToUTF8(string_utf16, swap_); return UTF16ToUTF8(string_utf16, swap_);
} }