aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client/windows/build/common.gypi6
-rw-r--r--src/client/windows/handler/exception_handler.cc18
-rw-r--r--src/client/windows/handler/exception_handler.h12
-rw-r--r--src/client/windows/tests/crash_generation_app/crash_generation_app.cc20
-rw-r--r--src/client/windows/unittests/exception_handler_death_test.cc76
-rwxr-xr-xsrc/client/windows/unittests/exception_handler_nesting_test.cc4
-rw-r--r--src/client/windows/unittests/exception_handler_test.cc2
-rw-r--r--src/client/windows/unittests/minidump_test.cc3
-rw-r--r--src/common/string_conversion.cc2
-rw-r--r--src/common/windows/http_upload.cc26
-rw-r--r--src/google_breakpad/processor/minidump.h4
-rwxr-xr-xsrc/processor/minidump.cc124
12 files changed, 173 insertions, 124 deletions
diff --git a/src/client/windows/build/common.gypi b/src/client/windows/build/common.gypi
index dfd29bd0..60a24582 100644
--- a/src/client/windows/build/common.gypi
+++ b/src/client/windows/build/common.gypi
@@ -507,7 +507,7 @@
'msvs_disabled_warnings': [4800],
'msvs_settings': {
'VCCLCompilerTool': {
- 'WarnAsError': 'false',
+ 'WarnAsError': 'true',
'Detect64BitPortabilityProblems': 'false',
},
},
@@ -1174,7 +1174,7 @@
'$(VSInstallDir)/VC/atlmfc/include',
],
'msvs_cygwin_dirs': ['<(DEPTH)/third_party/cygwin'],
- 'msvs_disabled_warnings': [4396, 4503, 4819],
+ 'msvs_disabled_warnings': [4100, 4127, 4396, 4503, 4512, 4819, 4995],
'msvs_settings': {
'VCCLCompilerTool': {
'MinimalRebuild': 'false',
@@ -1182,7 +1182,7 @@
'BufferSecurityCheck': 'true',
'EnableFunctionLevelLinking': 'true',
'RuntimeTypeInfo': 'false',
- 'WarningLevel': '3',
+ 'WarningLevel': '4',
'WarnAsError': 'true',
'DebugInformationFormat': '3',
'conditions': [
diff --git a/src/client/windows/handler/exception_handler.cc b/src/client/windows/handler/exception_handler.cc
index 14c2cf86..3a2f824c 100644
--- a/src/client/windows/handler/exception_handler.cc
+++ b/src/client/windows/handler/exception_handler.cc
@@ -96,7 +96,7 @@ ExceptionHandler::ExceptionHandler(const wstring& dump_path,
pipe_handle,
NULL, // crash_generation_client
custom_info);
-}
+}
ExceptionHandler::ExceptionHandler(
const wstring& dump_path,
@@ -104,19 +104,19 @@ ExceptionHandler::ExceptionHandler(
MinidumpCallback callback,
void* callback_context,
int handler_types,
- MINIDUMP_TYPE dump_type,
- CrashGenerationClient* crash_generation_client,
- const CustomClientInfo* custom_info) {
+ CrashGenerationClient* crash_generation_client) {
+ // The dump_type, pipe_name and custom_info that are passed in to Initialize()
+ // are not used. The ones set in crash_generation_client are used instead.
Initialize(dump_path,
filter,
callback,
callback_context,
handler_types,
- MiniDumpNormal,
- NULL, // pipe_name
- NULL, // pipe_handle
+ MiniDumpNormal, // dump_type - not used
+ NULL, // pipe_name - not used
+ NULL, // pipe_handle
crash_generation_client,
- custom_info);
+ NULL); // custom_info - not used
}
ExceptionHandler::ExceptionHandler(const wstring &dump_path,
@@ -875,7 +875,7 @@ BOOL CALLBACK ExceptionHandler::MinidumpWriteDumpCallback(
callback_context->iter++;
return TRUE;
}
-
+
// Include all modules.
case IncludeModuleCallback:
case ModuleCallback:
diff --git a/src/client/windows/handler/exception_handler.h b/src/client/windows/handler/exception_handler.h
index 2c8ff7d9..539c6662 100644
--- a/src/client/windows/handler/exception_handler.h
+++ b/src/client/windows/handler/exception_handler.h
@@ -61,9 +61,9 @@
#include <DbgHelp.h>
#include <rpc.h>
-#pragma warning( push )
+#pragma warning(push)
// Disable exception handler warnings.
-#pragma warning( disable : 4530 )
+#pragma warning(disable:4530)
#include <list>
#include <string>
@@ -212,9 +212,7 @@ class ExceptionHandler {
MinidumpCallback callback,
void* callback_context,
int handler_types,
- MINIDUMP_TYPE dump_type,
- CrashGenerationClient* crash_generation_client,
- const CustomClientInfo* custom_info);
+ CrashGenerationClient* crash_generation_client);
~ExceptionHandler();
@@ -497,7 +495,7 @@ class ExceptionHandler {
static CRITICAL_SECTION handler_stack_critical_section_;
// The number of instances of this class.
- volatile static LONG instance_count_;
+ static volatile LONG instance_count_;
// disallow copy ctor and operator=
explicit ExceptionHandler(const ExceptionHandler &);
@@ -506,6 +504,6 @@ class ExceptionHandler {
} // namespace google_breakpad
-#pragma warning( pop )
+#pragma warning(pop)
#endif // CLIENT_WINDOWS_HANDLER_EXCEPTION_HANDLER_H__
diff --git a/src/client/windows/tests/crash_generation_app/crash_generation_app.cc b/src/client/windows/tests/crash_generation_app/crash_generation_app.cc
index e36c1d1e..12449ce9 100644
--- a/src/client/windows/tests/crash_generation_app/crash_generation_app.cc
+++ b/src/client/windows/tests/crash_generation_app/crash_generation_app.cc
@@ -345,9 +345,9 @@ void CleanUp() {
// Processes messages for the main window.
//
-// WM_COMMAND - process the application menu.
-// WM_PAINT - Paint the main window.
-// WM_DESTROY - post a quit message and return.
+// WM_COMMAND - process the application menu.
+// WM_PAINT - Paint the main window.
+// WM_DESTROY - post a quit message and return.
LRESULT CALLBACK WndProc(HWND wnd,
UINT message,
WPARAM w_param,
@@ -359,7 +359,7 @@ LRESULT CALLBACK WndProc(HWND wnd,
#pragma warning(push)
#pragma warning(disable:4312)
- // Disable warning C4312: 'type cast' : conversion from 'LONG' to
+ // Disable warning C4312: 'type cast' : conversion from 'LONG' to
// 'HINSTANCE' of greater size.
// The value returned by GetwindowLong in the case below returns unsigned.
HINSTANCE instance = (HINSTANCE)GetWindowLong(wnd, GWL_HINSTANCE);
@@ -415,16 +415,16 @@ LRESULT CALLBACK WndProc(HWND wnd,
instance,
NULL);
break;
- case WM_SIZE:
- // Make the edit control the size of the window's client area.
- MoveWindow(client_status_edit_box,
+ case WM_SIZE:
+ // Make the edit control the size of the window's client area.
+ MoveWindow(client_status_edit_box,
0,
0,
LOWORD(l_param), // width of client area.
HIWORD(l_param), // height of client area.
TRUE); // repaint window.
break;
- case WM_SETFOCUS:
+ case WM_SETFOCUS:
SetFocus(client_status_edit_box);
break;
case WM_PAINT:
@@ -501,7 +501,7 @@ int APIENTRY _tWinMain(HINSTANCE instance,
MyRegisterClass(instance);
// Perform application initialization.
- if (!InitInstance (instance, command_show)) {
+ if (!InitInstance(instance, command_show)) {
return FALSE;
}
@@ -518,5 +518,5 @@ int APIENTRY _tWinMain(HINSTANCE instance,
}
}
- return (int)msg.wParam;
+ return static_cast<int>(msg.wParam);
}
diff --git a/src/client/windows/unittests/exception_handler_death_test.cc b/src/client/windows/unittests/exception_handler_death_test.cc
index ba7be920..3a16e525 100644
--- a/src/client/windows/unittests/exception_handler_death_test.cc
+++ b/src/client/windows/unittests/exception_handler_death_test.cc
@@ -124,17 +124,19 @@ TEST_F(ExceptionHandlerDeathTest, InProcTest) {
// the semantics of the exception handler being inherited/not
// inherited across CreateProcess().
ASSERT_TRUE(DoesPathExist(temp_path_));
- google_breakpad::ExceptionHandler *exc =
- new google_breakpad::ExceptionHandler(
- temp_path_, NULL, &MinidumpWrittenCallback, NULL,
- google_breakpad::ExceptionHandler::HANDLER_ALL);
+ scoped_ptr<google_breakpad::ExceptionHandler> exc(
+ new google_breakpad::ExceptionHandler(
+ temp_path_,
+ NULL,
+ &MinidumpWrittenCallback,
+ NULL,
+ google_breakpad::ExceptionHandler::HANDLER_ALL));
// Disable GTest SEH handler
testing::DisableExceptionHandlerInScope disable_exception_handler;
int *i = NULL;
ASSERT_DEATH((*i)++, kSuccessIndicator);
- delete exc;
}
static bool gDumpCallbackCalled = false;
@@ -147,26 +149,24 @@ void clientDumpCallback(void *dump_context,
void ExceptionHandlerDeathTest::DoCrashAccessViolation(
const OutOfProcGuarantee out_of_proc_guarantee) {
- google_breakpad::ExceptionHandler *exc = NULL;
+ scoped_ptr<google_breakpad::ExceptionHandler> exc;
if (out_of_proc_guarantee == OUT_OF_PROC_GUARANTEED) {
- google_breakpad::CrashGenerationClient *client =
+ google_breakpad::CrashGenerationClient *client =
new google_breakpad::CrashGenerationClient(kPipeName,
MiniDumpNormal,
NULL); // custom_info
ASSERT_TRUE(client->Register());
- exc = new google_breakpad::ExceptionHandler(
+ exc.reset(new google_breakpad::ExceptionHandler(
temp_path_,
NULL, // filter
NULL, // callback
NULL, // callback_context
google_breakpad::ExceptionHandler::HANDLER_ALL,
- MiniDumpNormal,
- client,
- NULL); // custom_info
+ client));
} else {
ASSERT_TRUE(out_of_proc_guarantee == OUT_OF_PROC_BEST_EFFORT);
- exc = new google_breakpad::ExceptionHandler(
+ exc.reset(new google_breakpad::ExceptionHandler(
temp_path_,
NULL, // filter
NULL, // callback
@@ -174,7 +174,7 @@ void ExceptionHandlerDeathTest::DoCrashAccessViolation(
google_breakpad::ExceptionHandler::HANDLER_ALL,
MiniDumpNormal,
kPipeName,
- NULL); // custom_info
+ NULL)); // custom_info
}
// Disable GTest SEH handler
@@ -302,17 +302,20 @@ wstring find_minidump_in_directory(const wstring &directory) {
filename = directory + L"\\" + find_data.cFileName;
break;
}
- } while(FindNextFile(find_handle, &find_data));
+ } while (FindNextFile(find_handle, &find_data));
FindClose(find_handle);
return filename;
}
TEST_F(ExceptionHandlerDeathTest, InstructionPointerMemory) {
ASSERT_TRUE(DoesPathExist(temp_path_));
- google_breakpad::ExceptionHandler *exc =
+ scoped_ptr<google_breakpad::ExceptionHandler> exc(
new google_breakpad::ExceptionHandler(
- temp_path_, NULL, NULL, NULL,
- google_breakpad::ExceptionHandler::HANDLER_ALL);
+ temp_path_,
+ NULL,
+ NULL,
+ NULL,
+ google_breakpad::ExceptionHandler::HANDLER_ALL));
// Disable GTest SEH handler
testing::DisableExceptionHandlerInScope disable_exception_handler;
@@ -333,7 +336,7 @@ TEST_F(ExceptionHandlerDeathTest, InstructionPointerMemory) {
// minidump should contain 128 bytes on either side of the
// instruction pointer.
memcpy(memory + kOffset, instructions, sizeof(instructions));
-
+
// Now execute the instructions, which should crash.
typedef void (*void_function)(void);
void_function memory_function =
@@ -382,11 +385,10 @@ TEST_F(ExceptionHandlerDeathTest, InstructionPointerMemory) {
uint8_t suffix_bytes[kMemorySize - kOffset - sizeof(instructions)];
memset(prefix_bytes, 0, sizeof(prefix_bytes));
memset(suffix_bytes, 0, sizeof(suffix_bytes));
- EXPECT_TRUE(memcmp(bytes, prefix_bytes, sizeof(prefix_bytes)) == 0);
- EXPECT_TRUE(memcmp(bytes + kOffset, instructions,
- sizeof(instructions)) == 0);
- EXPECT_TRUE(memcmp(bytes + kOffset + sizeof(instructions),
- suffix_bytes, sizeof(suffix_bytes)) == 0);
+ EXPECT_EQ(0, memcmp(bytes, prefix_bytes, sizeof(prefix_bytes)));
+ EXPECT_EQ(0, memcmp(bytes + kOffset, instructions, sizeof(instructions)));
+ EXPECT_EQ(0, memcmp(bytes + kOffset + sizeof(instructions),
+ suffix_bytes, sizeof(suffix_bytes)));
}
DeleteFileW(minidump_filename_wide.c_str());
@@ -394,10 +396,13 @@ TEST_F(ExceptionHandlerDeathTest, InstructionPointerMemory) {
TEST_F(ExceptionHandlerDeathTest, InstructionPointerMemoryMinBound) {
ASSERT_TRUE(DoesPathExist(temp_path_));
- google_breakpad::ExceptionHandler *exc =
+ scoped_ptr<google_breakpad::ExceptionHandler> exc(
new google_breakpad::ExceptionHandler(
- temp_path_, NULL, NULL, NULL,
- google_breakpad::ExceptionHandler::HANDLER_ALL);
+ temp_path_,
+ NULL,
+ NULL,
+ NULL,
+ google_breakpad::ExceptionHandler::HANDLER_ALL));
// Disable GTest SEH handler
testing::DisableExceptionHandlerInScope disable_exception_handler;
@@ -426,7 +431,7 @@ TEST_F(ExceptionHandlerDeathTest, InstructionPointerMemoryMinBound) {
// minidump should contain 128 bytes on either side of the
// instruction pointer.
memcpy(memory + kOffset, instructions, sizeof(instructions));
-
+
// Now execute the instructions, which should crash.
typedef void (*void_function)(void);
void_function memory_function =
@@ -484,10 +489,13 @@ TEST_F(ExceptionHandlerDeathTest, InstructionPointerMemoryMinBound) {
TEST_F(ExceptionHandlerDeathTest, InstructionPointerMemoryMaxBound) {
ASSERT_TRUE(DoesPathExist(temp_path_));
- google_breakpad::ExceptionHandler *exc =
+ scoped_ptr<google_breakpad::ExceptionHandler> exc(
new google_breakpad::ExceptionHandler(
- temp_path_, NULL, NULL, NULL,
- google_breakpad::ExceptionHandler::HANDLER_ALL);
+ temp_path_,
+ NULL,
+ NULL,
+ NULL,
+ google_breakpad::ExceptionHandler::HANDLER_ALL));
// Disable GTest SEH handler
testing::DisableExceptionHandlerInScope disable_exception_handler;
@@ -511,7 +519,7 @@ TEST_F(ExceptionHandlerDeathTest, InstructionPointerMemoryMaxBound) {
// Write some instructions that will crash.
memcpy(memory + kOffset, instructions, sizeof(instructions));
-
+
// Now execute the instructions, which should crash.
typedef void (*void_function)(void);
void_function memory_function =
@@ -559,9 +567,9 @@ TEST_F(ExceptionHandlerDeathTest, InstructionPointerMemoryMaxBound) {
uint8_t prefix_bytes[kPrefixSize];
memset(prefix_bytes, 0, sizeof(prefix_bytes));
- EXPECT_TRUE(memcmp(bytes, prefix_bytes, sizeof(prefix_bytes)) == 0);
- EXPECT_TRUE(memcmp(bytes + kPrefixSize,
- instructions, sizeof(instructions)) == 0);
+ EXPECT_EQ(0, memcmp(bytes, prefix_bytes, sizeof(prefix_bytes)));
+ EXPECT_EQ(0, memcmp(bytes + kPrefixSize,
+ instructions, sizeof(instructions)));
}
DeleteFileW(minidump_filename_wide.c_str());
diff --git a/src/client/windows/unittests/exception_handler_nesting_test.cc b/src/client/windows/unittests/exception_handler_nesting_test.cc
index 0cf30013..3ae1d7cd 100755
--- a/src/client/windows/unittests/exception_handler_nesting_test.cc
+++ b/src/client/windows/unittests/exception_handler_nesting_test.cc
@@ -149,7 +149,7 @@ void InstallExceptionHandlerAndCrash(bool install_filter,
ASSERT_TRUE(DoesPathExist(temp_path));
google_breakpad::ExceptionHandler exc(
temp_path,
- install_filter ?
+ install_filter ?
(filter_return_value ?
&CrashHandlerFilter<true> :
&CrashHandlerFilter<false>) :
@@ -178,7 +178,7 @@ TEST(AssertDeathSanity, Regex) {
std::string(kFoo) +
std::string(kEndOfLine));
- ASSERT_DEATH(DoCrash(kBar),
+ ASSERT_DEATH(DoCrash(kBar),
std::string(kStartOfLine) +
std::string(kBar) +
std::string(kEndOfLine));
diff --git a/src/client/windows/unittests/exception_handler_test.cc b/src/client/windows/unittests/exception_handler_test.cc
index 7b50e301..55275323 100644
--- a/src/client/windows/unittests/exception_handler_test.cc
+++ b/src/client/windows/unittests/exception_handler_test.cc
@@ -390,7 +390,7 @@ TEST_F(ExceptionHandlerTest, WriteMinidumpTest) {
// Read the minidump and verify some info.
Minidump minidump(minidump_filename);
ASSERT_TRUE(minidump.Read());
- //TODO(ted): more comprehensive tests...
+ // TODO(ted): more comprehensive tests...
}
// Test that an additional memory region can be included in the minidump.
diff --git a/src/client/windows/unittests/minidump_test.cc b/src/client/windows/unittests/minidump_test.cc
index 62f212f8..e3097f28 100644
--- a/src/client/windows/unittests/minidump_test.cc
+++ b/src/client/windows/unittests/minidump_test.cc
@@ -161,7 +161,8 @@ bool HasFileInfo(const std::wstring& file_path) {
}
TEST_F(MinidumpTest, Version) {
- API_VERSION* version = ::ImagehlpApiVersion();
+ // Loads DbgHelp.dll in process
+ ImagehlpApiVersion();
HMODULE dbg_help = ::GetModuleHandle(L"dbghelp.dll");
ASSERT_TRUE(dbg_help != NULL);
diff --git a/src/common/string_conversion.cc b/src/common/string_conversion.cc
index c4107faf..9b06e86b 100644
--- a/src/common/string_conversion.cc
+++ b/src/common/string_conversion.cc
@@ -140,7 +140,7 @@ string UTF16ToUTF8(const vector<uint16_t> &in, bool swap) {
scoped_array<UTF8> target_buffer(new UTF8[target_capacity]);
UTF8 *target_ptr = target_buffer.get();
UTF8 *target_end_ptr = target_ptr + target_capacity;
- ConversionResult result = ConvertUTF16toUTF8(&source_ptr, source_end_ptr,
+ ConversionResult result = ConvertUTF16toUTF8(&source_ptr, source_end_ptr,
&target_ptr, target_end_ptr,
strictConversion);
diff --git a/src/common/windows/http_upload.cc b/src/common/windows/http_upload.cc
index aabb9a46..838185b7 100644
--- a/src/common/windows/http_upload.cc
+++ b/src/common/windows/http_upload.cc
@@ -30,7 +30,7 @@
#include <assert.h>
// Disable exception handler warnings.
-#pragma warning( disable : 4530 )
+#pragma warning(disable:4530)
#include <fstream>
@@ -163,7 +163,7 @@ bool HTTPUpload::SendRequest(const wstring &url,
fwprintf(stderr, L"Could not unset receive timeout, continuing...\n");
}
}
-
+
if (!HttpSendRequest(request.get(), NULL, 0,
const_cast<char *>(request_body.data()),
static_cast<DWORD>(request_body.size()))) {
@@ -215,8 +215,7 @@ bool HTTPUpload::ReadResponse(HINTERNET request, wstring *response) {
BOOL return_code;
while (((return_code = InternetQueryDataAvailable(request, &bytes_available,
- 0, 0)) != 0) && bytes_available > 0) {
-
+ 0, 0)) != 0) && bytes_available > 0) {
vector<char> response_buffer(bytes_available);
DWORD size_read;
@@ -323,6 +322,7 @@ bool HTTPUpload::GenerateRequestBody(const map<wstring, wstring> &parameters,
// static
bool HTTPUpload::GetFileContents(const wstring &filename,
vector<char> *contents) {
+ bool rv = false;
// The "open" method on pre-MSVC8 ifstream implementations doesn't accept a
// wchar_t* filename, so use _wfopen directly in that case. For VC8 and
// later, _wfopen has been deprecated in favor of _wfopen_s, which does
@@ -336,15 +336,21 @@ bool HTTPUpload::GetFileContents(const wstring &filename,
if (file.is_open()) {
file.seekg(0, ios::end);
std::streamoff length = file.tellg();
- contents->resize(length);
- if (length != 0) {
- file.seekg(0, ios::beg);
- file.read(&((*contents)[0]), length);
+ // Check for loss of data when converting lenght from std::streamoff into
+ // std::vector<char>::size_type
+ std::vector<char>::size_type vector_size =
+ static_cast<std::vector<char>::size_type>(length);
+ if (static_cast<std::streamoff>(vector_size) == length) {
+ contents->resize(vector_size);
+ if (length != 0) {
+ file.seekg(0, ios::beg);
+ file.read(&((*contents)[0]), length);
+ }
+ rv = true;
}
file.close();
- return true;
}
- return false;
+ return rv;
}
// static
diff --git a/src/google_breakpad/processor/minidump.h b/src/google_breakpad/processor/minidump.h
index 87c00276..8b2d0fe8 100644
--- a/src/google_breakpad/processor/minidump.h
+++ b/src/google_breakpad/processor/minidump.h
@@ -477,7 +477,7 @@ class MinidumpModule : public MinidumpObject,
// True after a successful Read. This is different from valid_, which is
// not set true until ReadAuxiliaryData also completes successfully.
// module_valid_ is only used by ReadAuxiliaryData and the functions it
- // calls to determine whether the object is ready for auxiliary data to
+ // calls to determine whether the object is ready for auxiliary data to
// be read.
bool module_valid_;
@@ -821,7 +821,7 @@ class MinidumpMemoryInfo : public MinidumpObject {
uint64_t GetBase() const { return valid_ ? memory_info_.base_address : 0; }
// The size, in bytes, of the memory region.
- uint32_t GetSize() const { return valid_ ? memory_info_.region_size : 0; }
+ uint64_t GetSize() const { return valid_ ? memory_info_.region_size : 0; }
// Return true if the memory protection allows execution.
bool IsExecutable() const;
diff --git a/src/processor/minidump.cc b/src/processor/minidump.cc
index 8d4bab77..4ad82053 100755
--- a/src/processor/minidump.cc
+++ b/src/processor/minidump.cc
@@ -65,8 +65,6 @@
#include "processor/basic_code_modules.h"
#include "processor/logging.h"
-
-
namespace google_breakpad {
@@ -226,19 +224,19 @@ static string* UTF16ToUTF8(const vector<uint16_t>& in,
// Convert the Unicode code point (unichar) into its UTF-8 representation,
// appending it to the out string.
if (unichar < 0x80) {
- (*out) += unichar;
+ (*out) += static_cast<char>(unichar);
} else if (unichar < 0x800) {
- (*out) += 0xc0 | (unichar >> 6);
- (*out) += 0x80 | (unichar & 0x3f);
+ (*out) += 0xc0 | static_cast<char>(unichar >> 6);
+ (*out) += 0x80 | static_cast<char>(unichar & 0x3f);
} else if (unichar < 0x10000) {
- (*out) += 0xe0 | (unichar >> 12);
- (*out) += 0x80 | ((unichar >> 6) & 0x3f);
- (*out) += 0x80 | (unichar & 0x3f);
+ (*out) += 0xe0 | static_cast<char>(unichar >> 12);
+ (*out) += 0x80 | static_cast<char>((unichar >> 6) & 0x3f);
+ (*out) += 0x80 | static_cast<char>(unichar & 0x3f);
} else if (unichar < 0x200000) {
- (*out) += 0xf0 | (unichar >> 18);
- (*out) += 0x80 | ((unichar >> 12) & 0x3f);
- (*out) += 0x80 | ((unichar >> 6) & 0x3f);
- (*out) += 0x80 | (unichar & 0x3f);
+ (*out) += 0xf0 | static_cast<char>(unichar >> 18);
+ (*out) += 0x80 | static_cast<char>((unichar >> 12) & 0x3f);
+ (*out) += 0x80 | static_cast<char>((unichar >> 6) & 0x3f);
+ (*out) += 0x80 | static_cast<char>(unichar & 0x3f);
} else {
BPLOG(ERROR) << "UTF16ToUTF8 cannot represent high value " <<
HexString(unichar) << " in UTF-8";
@@ -329,7 +327,7 @@ bool MinidumpContext::Read(uint32_t expected_size) {
}
if (cpu_type != MD_CONTEXT_AMD64) {
- //TODO: fall through to switch below?
+ // TODO: fall through to switch below?
// need a Tell method to be able to SeekSet back to beginning
// http://code.google.com/p/google-breakpad/issues/detail?id=224
BPLOG(ERROR) << "MinidumpContext not actually amd64 context";
@@ -388,7 +386,7 @@ bool MinidumpContext::Read(uint32_t expected_size) {
Swap(&context_amd64->r14);
Swap(&context_amd64->r15);
Swap(&context_amd64->rip);
- //FIXME: I'm not sure what actually determines
+ // FIXME: I'm not sure what actually determines
// which member of the union {flt_save, sse_registers}
// is valid. We're not currently using either,
// but it would be good to have them swapped properly.
@@ -408,10 +406,9 @@ bool MinidumpContext::Read(uint32_t expected_size) {
context_flags_ = context_amd64->context_flags;
context_.amd64 = context_amd64.release();
- }
- // |context_flags| of MDRawContextPPC64 is 64 bits, but other MDRawContext
- // in the else case have 32 bits |context_flags|, so special case it here.
- else if (expected_size == sizeof(MDRawContextPPC64)) {
+ } else if (expected_size == sizeof(MDRawContextPPC64)) {
+ // |context_flags| of MDRawContextPPC64 is 64 bits, but other MDRawContext
+ // in the else case have 32 bits |context_flags|, so special case it here.
uint64_t context_flags;
if (!minidump_->ReadBytes(&context_flags, sizeof(context_flags))) {
BPLOG(ERROR) << "MinidumpContext could not read context flags";
@@ -421,9 +418,9 @@ bool MinidumpContext::Read(uint32_t expected_size) {
Swap(&context_flags);
uint32_t cpu_type = context_flags & MD_CONTEXT_CPU_MASK;
-
scoped_ptr<MDRawContextPPC64> context_ppc64(new MDRawContextPPC64());
+
// Set the context_flags member, which has already been read, and
// read the rest of the structure beginning with the first member
// after context_flags.
@@ -477,11 +474,18 @@ bool MinidumpContext::Read(uint32_t expected_size) {
Swap(&context_ppc64->vector_save.save_vrvalid);
}
- context_flags_ = context_ppc64->context_flags;
- context_.ppc64 = context_ppc64.release();
- }
+ context_flags_ = static_cast<uint32_t>(context_ppc64->context_flags);
+
+ // Check for data loss when converting context flags from uint64_t into
+ // uint32_t
+ if (static_cast<uint64_t>(context_flags_) !=
+ context_ppc64->context_flags) {
+ BPLOG(ERROR) << "Data loss detected when converting PPC64 context_flags";
+ return false;
+ }
- else {
+ context_.ppc64 = context_ppc64.release();
+ } else {
uint32_t context_flags;
if (!minidump_->ReadBytes(&context_flags, sizeof(context_flags))) {
BPLOG(ERROR) << "MinidumpContext could not read context flags";
@@ -1205,7 +1209,7 @@ void MinidumpContext::Print() {
printf(" r14 = 0x%" PRIx64 "\n", context_amd64->r14);
printf(" r15 = 0x%" PRIx64 "\n", context_amd64->r15);
printf(" rip = 0x%" PRIx64 "\n", context_amd64->rip);
- //TODO: print xmm, vector, debug registers
+ // TODO: print xmm, vector, debug registers
printf("\n");
break;
}
@@ -1673,7 +1677,8 @@ bool MinidumpThreadList::Read(uint32_t expected_size) {
thread_count * sizeof(MDRawThread)) {
uint32_t useless;
if (!minidump_->ReadBytes(&useless, 4)) {
- BPLOG(ERROR) << "MinidumpThreadList cannot read threadlist padded bytes";
+ BPLOG(ERROR) << "MinidumpThreadList cannot read threadlist padded "
+ "bytes";
return false;
}
} else {
@@ -1950,7 +1955,7 @@ string MinidumpModule::code_identifier() const {
case MD_OS_IOS:
case MD_OS_SOLARIS:
case MD_OS_ANDROID:
- case MD_OS_LINUX:
+ case MD_OS_LINUX:
case MD_OS_PS3: {
// TODO(mmentovai): support uuid extension if present, otherwise fall
// back to version (from LC_ID_DYLIB?), otherwise fall back to something
@@ -2560,7 +2565,8 @@ bool MinidumpModuleList::Read(uint32_t expected_size) {
module_count * MD_MODULE_SIZE) {
uint32_t useless;
if (!minidump_->ReadBytes(&useless, 4)) {
- BPLOG(ERROR) << "MinidumpModuleList cannot read modulelist padded bytes";
+ BPLOG(ERROR) << "MinidumpModuleList cannot read modulelist padded "
+ "bytes";
return false;
}
} else {
@@ -2806,12 +2812,13 @@ bool MinidumpMemoryList::Read(uint32_t expected_size) {
region_count * sizeof(MDMemoryDescriptor)) {
uint32_t useless;
if (!minidump_->ReadBytes(&useless, 4)) {
- BPLOG(ERROR) << "MinidumpMemoryList cannot read memorylist padded bytes";
+ BPLOG(ERROR) << "MinidumpMemoryList cannot read memorylist padded "
+ "bytes";
return false;
}
} else {
BPLOG(ERROR) << "MinidumpMemoryList size mismatch, " << expected_size <<
- " != " << sizeof(region_count) +
+ " != " << sizeof(region_count) +
region_count * sizeof(MDMemoryDescriptor);
return false;
}
@@ -3142,7 +3149,7 @@ bool MinidumpAssertion::Read(uint32_t expected_size) {
if (new_expression.get())
expression_ = *new_expression;
}
-
+
// assertion
word_length = UTF16codeunits(assertion_.function,
sizeof(assertion_.function));
@@ -3791,7 +3798,7 @@ bool MinidumpMemoryInfoList::Read(uint32_t expected_size) {
}
// Sanity check that the header is the expected size.
- //TODO(ted): could possibly handle this more gracefully, assuming
+ // TODO(ted): could possibly handle this more gracefully, assuming
// that future versions of the structs would be backwards-compatible.
if (header.size_of_header != sizeof(MDRawMemoryInfoList)) {
BPLOG(ERROR) << "MinidumpMemoryInfoList header size mismatch, " <<
@@ -3824,9 +3831,20 @@ bool MinidumpMemoryInfoList::Read(uint32_t expected_size) {
return false;
}
+ // Check for data loss when converting header.number_of_entries from
+ // uint64_t into MinidumpMemoryInfos::size_type (uint32_t)
+ MinidumpMemoryInfos::size_type header_number_of_entries =
+ static_cast<unsigned int>(header.number_of_entries);
+ if (static_cast<uint64_t>(header_number_of_entries) !=
+ header.number_of_entries) {
+ BPLOG(ERROR) << "Data loss detected when converting "
+ "the header's number_of_entries";
+ return false;
+ }
+
if (header.number_of_entries != 0) {
scoped_ptr<MinidumpMemoryInfos> infos(
- new MinidumpMemoryInfos(header.number_of_entries,
+ new MinidumpMemoryInfos(header_number_of_entries,
MinidumpMemoryInfo(minidump_)));
for (unsigned int index = 0;
@@ -3842,7 +3860,7 @@ bool MinidumpMemoryInfoList::Read(uint32_t expected_size) {
}
uint64_t base_address = info->GetBase();
- uint32_t region_size = info->GetSize();
+ uint64_t region_size = info->GetSize();
if (!range_map_->StoreRange(base_address, region_size, index)) {
BPLOG(ERROR) << "MinidumpMemoryInfoList could not store"
@@ -3857,7 +3875,7 @@ bool MinidumpMemoryInfoList::Read(uint32_t expected_size) {
infos_ = infos.release();
}
- info_count_ = header.number_of_entries;
+ info_count_ = header_number_of_entries;
valid_ = true;
return true;
@@ -4312,17 +4330,27 @@ bool Minidump::ReadBytes(void* bytes, size_t count) {
return false;
}
stream_->read(static_cast<char*>(bytes), count);
- size_t bytes_read = stream_->gcount();
- if (bytes_read != count) {
- if (bytes_read == size_t(-1)) {
- string error_string;
- int error_code = ErrnoString(&error_string);
- BPLOG(ERROR) << "ReadBytes: error " << error_code << ": " << error_string;
- } else {
- BPLOG(ERROR) << "ReadBytes: read " << bytes_read << "/" << count;
- }
+ std::streamsize bytes_read = stream_->gcount();
+ if (bytes_read == -1) {
+ string error_string;
+ int error_code = ErrnoString(&error_string);
+ BPLOG(ERROR) << "ReadBytes: error " << error_code << ": " << error_string;
+ return false;
+ }
+
+ // Convert to size_t and check for data loss
+ size_t bytes_read_converted = static_cast<size_t>(bytes_read);
+ if (static_cast<std::streamsize>(bytes_read_converted) != bytes_read) {
+ BPLOG(ERROR) << "ReadBytes: conversion data loss detected when converting "
+ << bytes_read << " to " << bytes_read_converted;
return false;
}
+
+ if (bytes_read_converted != count) {
+ BPLOG(ERROR) << "ReadBytes: read " << bytes_read_converted << "/" << count;
+ return false;
+ }
+
return true;
}
@@ -4348,7 +4376,15 @@ off_t Minidump::Tell() {
return (off_t)-1;
}
- return stream_->tellg();
+ // Check for conversion data loss
+ std::streamoff std_streamoff = stream_->tellg();
+ off_t rv = static_cast<off_t>(std_streamoff);
+ if (static_cast<std::streamoff>(rv) == std_streamoff) {
+ return rv;
+ } else {
+ BPLOG(ERROR) << "Data loss detected";
+ return (off_t)-1;
+ }
}