mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-08-29 08:40:40 +02:00
* Added breakpad support for Linux.
This commit is contained in:
76
thirdparty/breakpad/common/windows/guid_string.cc
vendored
Normal file
76
thirdparty/breakpad/common/windows/guid_string.cc
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
// Copyright (c) 2006, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// guid_string.cc: Convert GUIDs to strings.
|
||||
//
|
||||
// See guid_string.h for documentation.
|
||||
|
||||
#include <wchar.h>
|
||||
|
||||
#include "common/windows/string_utils-inl.h"
|
||||
|
||||
#include "common/windows/guid_string.h"
|
||||
|
||||
namespace google_breakpad {
|
||||
|
||||
// static
|
||||
wstring GUIDString::GUIDToWString(GUID *guid) {
|
||||
wchar_t guid_string[37];
|
||||
swprintf(
|
||||
guid_string, sizeof(guid_string) / sizeof(guid_string[0]),
|
||||
L"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
|
||||
guid->Data1, guid->Data2, guid->Data3,
|
||||
guid->Data4[0], guid->Data4[1], guid->Data4[2],
|
||||
guid->Data4[3], guid->Data4[4], guid->Data4[5],
|
||||
guid->Data4[6], guid->Data4[7]);
|
||||
|
||||
// remove when VC++7.1 is no longer supported
|
||||
guid_string[sizeof(guid_string) / sizeof(guid_string[0]) - 1] = L'\0';
|
||||
|
||||
return wstring(guid_string);
|
||||
}
|
||||
|
||||
// static
|
||||
wstring GUIDString::GUIDToSymbolServerWString(GUID *guid) {
|
||||
wchar_t guid_string[33];
|
||||
swprintf(
|
||||
guid_string, sizeof(guid_string) / sizeof(guid_string[0]),
|
||||
L"%08X%04X%04X%02X%02X%02X%02X%02X%02X%02X%02X",
|
||||
guid->Data1, guid->Data2, guid->Data3,
|
||||
guid->Data4[0], guid->Data4[1], guid->Data4[2],
|
||||
guid->Data4[3], guid->Data4[4], guid->Data4[5],
|
||||
guid->Data4[6], guid->Data4[7]);
|
||||
|
||||
// remove when VC++7.1 is no longer supported
|
||||
guid_string[sizeof(guid_string) / sizeof(guid_string[0]) - 1] = L'\0';
|
||||
|
||||
return wstring(guid_string);
|
||||
}
|
||||
|
||||
} // namespace google_breakpad
|
58
thirdparty/breakpad/common/windows/guid_string.h
vendored
Normal file
58
thirdparty/breakpad/common/windows/guid_string.h
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
// Copyright (c) 2006, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// guid_string.cc: Convert GUIDs to strings.
|
||||
|
||||
#ifndef COMMON_WINDOWS_GUID_STRING_H__
|
||||
#define COMMON_WINDOWS_GUID_STRING_H__
|
||||
|
||||
#include <Guiddef.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace google_breakpad {
|
||||
|
||||
using std::wstring;
|
||||
|
||||
class GUIDString {
|
||||
public:
|
||||
// Converts guid to a string in the format recommended by RFC 4122 and
|
||||
// returns the string.
|
||||
static wstring GUIDToWString(GUID *guid);
|
||||
|
||||
// Converts guid to a string formatted as uppercase hexadecimal, with
|
||||
// no separators, and returns the string. This is the format used for
|
||||
// symbol server identifiers, although identifiers have an age tacked
|
||||
// on to the string.
|
||||
static wstring GUIDToSymbolServerWString(GUID *guid);
|
||||
};
|
||||
|
||||
} // namespace google_breakpad
|
||||
|
||||
#endif // COMMON_WINDOWS_GUID_STRING_H__
|
412
thirdparty/breakpad/common/windows/http_upload.cc
vendored
Normal file
412
thirdparty/breakpad/common/windows/http_upload.cc
vendored
Normal file
@@ -0,0 +1,412 @@
|
||||
// Copyright (c) 2006, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
// Disable exception handler warnings.
|
||||
#pragma warning( disable : 4530 )
|
||||
|
||||
#include <fstream>
|
||||
|
||||
#include "common/windows/string_utils-inl.h"
|
||||
|
||||
#include "common/windows/http_upload.h"
|
||||
|
||||
namespace google_breakpad {
|
||||
|
||||
using std::ifstream;
|
||||
using std::ios;
|
||||
|
||||
static const wchar_t kUserAgent[] = L"Breakpad/1.0 (Windows)";
|
||||
|
||||
// Helper class which closes an internet handle when it goes away
|
||||
class HTTPUpload::AutoInternetHandle {
|
||||
public:
|
||||
explicit AutoInternetHandle(HINTERNET handle) : handle_(handle) {}
|
||||
~AutoInternetHandle() {
|
||||
if (handle_) {
|
||||
InternetCloseHandle(handle_);
|
||||
}
|
||||
}
|
||||
|
||||
HINTERNET get() { return handle_; }
|
||||
|
||||
private:
|
||||
HINTERNET handle_;
|
||||
};
|
||||
|
||||
// static
|
||||
bool HTTPUpload::SendRequest(const wstring &url,
|
||||
const map<wstring, wstring> ¶meters,
|
||||
const wstring &upload_file,
|
||||
const wstring &file_part_name,
|
||||
int *timeout,
|
||||
wstring *response_body,
|
||||
int *response_code) {
|
||||
if (response_code) {
|
||||
*response_code = 0;
|
||||
}
|
||||
|
||||
// TODO(bryner): support non-ASCII parameter names
|
||||
if (!CheckParameters(parameters)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Break up the URL and make sure we can handle it
|
||||
wchar_t scheme[16], host[256], path[256];
|
||||
URL_COMPONENTS components;
|
||||
memset(&components, 0, sizeof(components));
|
||||
components.dwStructSize = sizeof(components);
|
||||
components.lpszScheme = scheme;
|
||||
components.dwSchemeLength = sizeof(scheme) / sizeof(scheme[0]);
|
||||
components.lpszHostName = host;
|
||||
components.dwHostNameLength = sizeof(host) / sizeof(host[0]);
|
||||
components.lpszUrlPath = path;
|
||||
components.dwUrlPathLength = sizeof(path) / sizeof(path[0]);
|
||||
if (!InternetCrackUrl(url.c_str(), static_cast<DWORD>(url.size()),
|
||||
0, &components)) {
|
||||
return false;
|
||||
}
|
||||
bool secure = false;
|
||||
if (wcscmp(scheme, L"https") == 0) {
|
||||
secure = true;
|
||||
} else if (wcscmp(scheme, L"http") != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
AutoInternetHandle internet(InternetOpen(kUserAgent,
|
||||
INTERNET_OPEN_TYPE_PRECONFIG,
|
||||
NULL, // proxy name
|
||||
NULL, // proxy bypass
|
||||
0)); // flags
|
||||
if (!internet.get()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
AutoInternetHandle connection(InternetConnect(internet.get(),
|
||||
host,
|
||||
components.nPort,
|
||||
NULL, // user name
|
||||
NULL, // password
|
||||
INTERNET_SERVICE_HTTP,
|
||||
0, // flags
|
||||
NULL)); // context
|
||||
if (!connection.get()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
DWORD http_open_flags = secure ? INTERNET_FLAG_SECURE : 0;
|
||||
http_open_flags |= INTERNET_FLAG_NO_COOKIES;
|
||||
AutoInternetHandle request(HttpOpenRequest(connection.get(),
|
||||
L"POST",
|
||||
path,
|
||||
NULL, // version
|
||||
NULL, // referer
|
||||
NULL, // agent type
|
||||
http_open_flags,
|
||||
NULL)); // context
|
||||
if (!request.get()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
wstring boundary = GenerateMultipartBoundary();
|
||||
wstring content_type_header = GenerateRequestHeader(boundary);
|
||||
HttpAddRequestHeaders(request.get(),
|
||||
content_type_header.c_str(),
|
||||
static_cast<DWORD>(-1),
|
||||
HTTP_ADDREQ_FLAG_ADD);
|
||||
|
||||
string request_body;
|
||||
if (!GenerateRequestBody(parameters, upload_file,
|
||||
file_part_name, boundary, &request_body)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (timeout) {
|
||||
if (!InternetSetOption(request.get(),
|
||||
INTERNET_OPTION_SEND_TIMEOUT,
|
||||
timeout,
|
||||
sizeof(timeout))) {
|
||||
fwprintf(stderr, L"Could not unset send timeout, continuing...\n");
|
||||
}
|
||||
|
||||
if (!InternetSetOption(request.get(),
|
||||
INTERNET_OPTION_RECEIVE_TIMEOUT,
|
||||
timeout,
|
||||
sizeof(timeout))) {
|
||||
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()))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// The server indicates a successful upload with HTTP status 200.
|
||||
wchar_t http_status[4];
|
||||
DWORD http_status_size = sizeof(http_status);
|
||||
if (!HttpQueryInfo(request.get(), HTTP_QUERY_STATUS_CODE,
|
||||
static_cast<LPVOID>(&http_status), &http_status_size,
|
||||
0)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int http_response = wcstol(http_status, NULL, 10);
|
||||
if (response_code) {
|
||||
*response_code = http_response;
|
||||
}
|
||||
|
||||
bool result = (http_response == 200);
|
||||
|
||||
if (result) {
|
||||
result = ReadResponse(request.get(), response_body);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// static
|
||||
bool HTTPUpload::ReadResponse(HINTERNET request, wstring *response) {
|
||||
bool has_content_length_header = false;
|
||||
wchar_t content_length[32];
|
||||
DWORD content_length_size = sizeof(content_length);
|
||||
DWORD claimed_size = 0;
|
||||
string response_body;
|
||||
|
||||
if (HttpQueryInfo(request, HTTP_QUERY_CONTENT_LENGTH,
|
||||
static_cast<LPVOID>(&content_length),
|
||||
&content_length_size, 0)) {
|
||||
has_content_length_header = true;
|
||||
claimed_size = wcstol(content_length, NULL, 10);
|
||||
response_body.reserve(claimed_size);
|
||||
}
|
||||
|
||||
|
||||
DWORD bytes_available;
|
||||
DWORD total_read = 0;
|
||||
BOOL return_code;
|
||||
|
||||
while (((return_code = InternetQueryDataAvailable(request, &bytes_available,
|
||||
0, 0)) != 0) && bytes_available > 0) {
|
||||
|
||||
vector<char> response_buffer(bytes_available);
|
||||
DWORD size_read;
|
||||
|
||||
return_code = InternetReadFile(request,
|
||||
&response_buffer[0],
|
||||
bytes_available, &size_read);
|
||||
|
||||
if (return_code && size_read > 0) {
|
||||
total_read += size_read;
|
||||
response_body.append(&response_buffer[0], size_read);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool succeeded = return_code && (!has_content_length_header ||
|
||||
(total_read == claimed_size));
|
||||
if (succeeded && response) {
|
||||
*response = UTF8ToWide(response_body);
|
||||
}
|
||||
|
||||
return succeeded;
|
||||
}
|
||||
|
||||
// static
|
||||
wstring HTTPUpload::GenerateMultipartBoundary() {
|
||||
// The boundary has 27 '-' characters followed by 16 hex digits
|
||||
static const wchar_t kBoundaryPrefix[] = L"---------------------------";
|
||||
static const int kBoundaryLength = 27 + 16 + 1;
|
||||
|
||||
// Generate some random numbers to fill out the boundary
|
||||
int r0 = rand();
|
||||
int r1 = rand();
|
||||
|
||||
wchar_t temp[kBoundaryLength];
|
||||
swprintf(temp, kBoundaryLength, L"%s%08X%08X", kBoundaryPrefix, r0, r1);
|
||||
|
||||
// remove when VC++7.1 is no longer supported
|
||||
temp[kBoundaryLength - 1] = L'\0';
|
||||
|
||||
return wstring(temp);
|
||||
}
|
||||
|
||||
// static
|
||||
wstring HTTPUpload::GenerateRequestHeader(const wstring &boundary) {
|
||||
wstring header = L"Content-Type: multipart/form-data; boundary=";
|
||||
header += boundary;
|
||||
return header;
|
||||
}
|
||||
|
||||
// static
|
||||
bool HTTPUpload::GenerateRequestBody(const map<wstring, wstring> ¶meters,
|
||||
const wstring &upload_file,
|
||||
const wstring &file_part_name,
|
||||
const wstring &boundary,
|
||||
string *request_body) {
|
||||
vector<char> contents;
|
||||
if (!GetFileContents(upload_file, &contents)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
string boundary_str = WideToUTF8(boundary);
|
||||
if (boundary_str.empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
request_body->clear();
|
||||
|
||||
// Append each of the parameter pairs as a form-data part
|
||||
for (map<wstring, wstring>::const_iterator pos = parameters.begin();
|
||||
pos != parameters.end(); ++pos) {
|
||||
request_body->append("--" + boundary_str + "\r\n");
|
||||
request_body->append("Content-Disposition: form-data; name=\"" +
|
||||
WideToUTF8(pos->first) + "\"\r\n\r\n" +
|
||||
WideToUTF8(pos->second) + "\r\n");
|
||||
}
|
||||
|
||||
// Now append the upload file as a binary (octet-stream) part
|
||||
string filename_utf8 = WideToUTF8(upload_file);
|
||||
if (filename_utf8.empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
string file_part_name_utf8 = WideToUTF8(file_part_name);
|
||||
if (file_part_name_utf8.empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
request_body->append("--" + boundary_str + "\r\n");
|
||||
request_body->append("Content-Disposition: form-data; "
|
||||
"name=\"" + file_part_name_utf8 + "\"; "
|
||||
"filename=\"" + filename_utf8 + "\"\r\n");
|
||||
request_body->append("Content-Type: application/octet-stream\r\n");
|
||||
request_body->append("\r\n");
|
||||
|
||||
if (!contents.empty()) {
|
||||
request_body->append(&(contents[0]), contents.size());
|
||||
}
|
||||
request_body->append("\r\n");
|
||||
request_body->append("--" + boundary_str + "--\r\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
// static
|
||||
bool HTTPUpload::GetFileContents(const wstring &filename,
|
||||
vector<char> *contents) {
|
||||
// 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
|
||||
// not exist in earlier versions, so let the ifstream open the file itself.
|
||||
#if _MSC_VER >= 1400 // MSVC 2005/8
|
||||
ifstream file;
|
||||
file.open(filename.c_str(), ios::binary);
|
||||
#else // _MSC_VER >= 1400
|
||||
ifstream file(_wfopen(filename.c_str(), L"rb"));
|
||||
#endif // _MSC_VER >= 1400
|
||||
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);
|
||||
}
|
||||
file.close();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// static
|
||||
wstring HTTPUpload::UTF8ToWide(const string &utf8) {
|
||||
if (utf8.length() == 0) {
|
||||
return wstring();
|
||||
}
|
||||
|
||||
// compute the length of the buffer we'll need
|
||||
int charcount = MultiByteToWideChar(CP_UTF8, 0, utf8.c_str(), -1, NULL, 0);
|
||||
|
||||
if (charcount == 0) {
|
||||
return wstring();
|
||||
}
|
||||
|
||||
// convert
|
||||
wchar_t* buf = new wchar_t[charcount];
|
||||
MultiByteToWideChar(CP_UTF8, 0, utf8.c_str(), -1, buf, charcount);
|
||||
wstring result(buf);
|
||||
delete[] buf;
|
||||
return result;
|
||||
}
|
||||
|
||||
// static
|
||||
string HTTPUpload::WideToUTF8(const wstring &wide) {
|
||||
if (wide.length() == 0) {
|
||||
return string();
|
||||
}
|
||||
|
||||
// compute the length of the buffer we'll need
|
||||
int charcount = WideCharToMultiByte(CP_UTF8, 0, wide.c_str(), -1,
|
||||
NULL, 0, NULL, NULL);
|
||||
if (charcount == 0) {
|
||||
return string();
|
||||
}
|
||||
|
||||
// convert
|
||||
char *buf = new char[charcount];
|
||||
WideCharToMultiByte(CP_UTF8, 0, wide.c_str(), -1, buf, charcount,
|
||||
NULL, NULL);
|
||||
|
||||
string result(buf);
|
||||
delete[] buf;
|
||||
return result;
|
||||
}
|
||||
|
||||
// static
|
||||
bool HTTPUpload::CheckParameters(const map<wstring, wstring> ¶meters) {
|
||||
for (map<wstring, wstring>::const_iterator pos = parameters.begin();
|
||||
pos != parameters.end(); ++pos) {
|
||||
const wstring &str = pos->first;
|
||||
if (str.size() == 0) {
|
||||
return false; // disallow empty parameter names
|
||||
}
|
||||
for (unsigned int i = 0; i < str.size(); ++i) {
|
||||
wchar_t c = str[i];
|
||||
if (c < 32 || c == '"' || c > 127) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace google_breakpad
|
126
thirdparty/breakpad/common/windows/http_upload.h
vendored
Normal file
126
thirdparty/breakpad/common/windows/http_upload.h
vendored
Normal file
@@ -0,0 +1,126 @@
|
||||
// Copyright (c) 2006, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// HTTPUpload provides a "nice" API to send a multipart HTTP(S) POST
|
||||
// request using wininet. It currently supports requests that contain
|
||||
// a set of string parameters (key/value pairs), and a file to upload.
|
||||
|
||||
#ifndef COMMON_WINDOWS_HTTP_UPLOAD_H__
|
||||
#define COMMON_WINDOWS_HTTP_UPLOAD_H__
|
||||
|
||||
#pragma warning( push )
|
||||
// Disable exception handler warnings.
|
||||
#pragma warning( disable : 4530 )
|
||||
|
||||
#include <Windows.h>
|
||||
#include <WinInet.h>
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace google_breakpad {
|
||||
|
||||
using std::string;
|
||||
using std::wstring;
|
||||
using std::map;
|
||||
using std::vector;
|
||||
|
||||
class HTTPUpload {
|
||||
public:
|
||||
// Sends the given set of parameters, along with the contents of
|
||||
// upload_file, as a multipart POST request to the given URL.
|
||||
// file_part_name contains the name of the file part of the request
|
||||
// (i.e. it corresponds to the name= attribute on an <input type="file">.
|
||||
// Parameter names must contain only printable ASCII characters,
|
||||
// and may not contain a quote (") character.
|
||||
// Only HTTP(S) URLs are currently supported. Returns true on success.
|
||||
// If the request is successful and response_body is non-NULL,
|
||||
// the response body will be returned in response_body.
|
||||
// If response_code is non-NULL, it will be set to the HTTP response code
|
||||
// received (or 0 if the request failed before getting an HTTP response).
|
||||
static bool SendRequest(const wstring &url,
|
||||
const map<wstring, wstring> ¶meters,
|
||||
const wstring &upload_file,
|
||||
const wstring &file_part_name,
|
||||
int *timeout,
|
||||
wstring *response_body,
|
||||
int *response_code);
|
||||
|
||||
private:
|
||||
class AutoInternetHandle;
|
||||
|
||||
// Retrieves the HTTP response. If NULL is passed in for response,
|
||||
// this merely checks (via the return value) that we were successfully
|
||||
// able to retrieve exactly as many bytes of content in the response as
|
||||
// were specified in the Content-Length header.
|
||||
static bool HTTPUpload::ReadResponse(HINTERNET request, wstring* response);
|
||||
|
||||
// Generates a new multipart boundary for a POST request
|
||||
static wstring GenerateMultipartBoundary();
|
||||
|
||||
// Generates a HTTP request header for a multipart form submit.
|
||||
static wstring GenerateRequestHeader(const wstring &boundary);
|
||||
|
||||
// Given a set of parameters, an upload filename, and a file part name,
|
||||
// generates a multipart request body string with these parameters
|
||||
// and minidump contents. Returns true on success.
|
||||
static bool GenerateRequestBody(const map<wstring, wstring> ¶meters,
|
||||
const wstring &upload_file,
|
||||
const wstring &file_part_name,
|
||||
const wstring &boundary,
|
||||
string *request_body);
|
||||
|
||||
// Fills the supplied vector with the contents of filename.
|
||||
static bool GetFileContents(const wstring &filename, vector<char> *contents);
|
||||
|
||||
// Converts a UTF8 string to UTF16.
|
||||
static wstring UTF8ToWide(const string &utf8);
|
||||
|
||||
// Converts a UTF16 string to UTF8.
|
||||
static string WideToUTF8(const wstring &wide);
|
||||
|
||||
// Checks that the given list of parameters has only printable
|
||||
// ASCII characters in the parameter name, and does not contain
|
||||
// any quote (") characters. Returns true if so.
|
||||
static bool CheckParameters(const map<wstring, wstring> ¶meters);
|
||||
|
||||
// No instances of this class should be created.
|
||||
// Disallow all constructors, destructors, and operator=.
|
||||
HTTPUpload();
|
||||
explicit HTTPUpload(const HTTPUpload &);
|
||||
void operator=(const HTTPUpload &);
|
||||
~HTTPUpload();
|
||||
};
|
||||
|
||||
} // namespace google_breakpad
|
||||
|
||||
#pragma warning( pop )
|
||||
|
||||
#endif // COMMON_WINDOWS_HTTP_UPLOAD_H__
|
1001
thirdparty/breakpad/common/windows/pdb_source_line_writer.cc
vendored
Normal file
1001
thirdparty/breakpad/common/windows/pdb_source_line_writer.cc
vendored
Normal file
File diff suppressed because it is too large
Load Diff
238
thirdparty/breakpad/common/windows/pdb_source_line_writer.h
vendored
Normal file
238
thirdparty/breakpad/common/windows/pdb_source_line_writer.h
vendored
Normal file
@@ -0,0 +1,238 @@
|
||||
// Copyright (c) 2006, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// PDBSourceLineWriter uses a pdb file produced by Visual C++ to output
|
||||
// a line/address map for use with BasicSourceLineResolver.
|
||||
|
||||
#ifndef _PDB_SOURCE_LINE_WRITER_H__
|
||||
#define _PDB_SOURCE_LINE_WRITER_H__
|
||||
|
||||
#include <atlcomcli.h>
|
||||
|
||||
#include <hash_map>
|
||||
#include <string>
|
||||
|
||||
struct IDiaEnumLineNumbers;
|
||||
struct IDiaSession;
|
||||
struct IDiaSymbol;
|
||||
|
||||
namespace google_breakpad {
|
||||
|
||||
using std::wstring;
|
||||
using stdext::hash_map;
|
||||
|
||||
// A structure that carries information that identifies a pdb file.
|
||||
struct PDBModuleInfo {
|
||||
public:
|
||||
// The basename of the pdb file from which information was loaded.
|
||||
wstring debug_file;
|
||||
|
||||
// The pdb's identifier. For recent pdb files, the identifier consists
|
||||
// of the pdb's guid, in uppercase hexadecimal form without any dashes
|
||||
// or separators, followed immediately by the pdb's age, also in
|
||||
// uppercase hexadecimal form. For older pdb files which have no guid,
|
||||
// the identifier is the pdb's 32-bit signature value, in zero-padded
|
||||
// hexadecimal form, followed immediately by the pdb's age, in lowercase
|
||||
// hexadecimal form.
|
||||
wstring debug_identifier;
|
||||
|
||||
// A string identifying the cpu that the pdb is associated with.
|
||||
// Currently, this may be "x86" or "unknown".
|
||||
wstring cpu;
|
||||
};
|
||||
|
||||
// A structure that carries information that identifies a PE file,
|
||||
// either an EXE or a DLL.
|
||||
struct PEModuleInfo {
|
||||
// The basename of the PE file.
|
||||
wstring code_file;
|
||||
|
||||
// The PE file's code identifier, which consists of its timestamp
|
||||
// and file size concatenated together into a single hex string.
|
||||
// (The fields IMAGE_OPTIONAL_HEADER::SizeOfImage and
|
||||
// IMAGE_FILE_HEADER::TimeDateStamp, as defined in the ImageHlp
|
||||
// documentation.) This is not well documented, if it's documented
|
||||
// at all, but it's what symstore does and what DbgHelp supports.
|
||||
wstring code_identifier;
|
||||
};
|
||||
|
||||
class PDBSourceLineWriter {
|
||||
public:
|
||||
enum FileFormat {
|
||||
PDB_FILE, // a .pdb file containing debug symbols
|
||||
EXE_FILE, // a .exe or .dll file
|
||||
ANY_FILE // try PDB_FILE and then EXE_FILE
|
||||
};
|
||||
|
||||
explicit PDBSourceLineWriter();
|
||||
~PDBSourceLineWriter();
|
||||
|
||||
// Opens the given file. For executable files, the corresponding pdb
|
||||
// file must be available; Open will be if it is not.
|
||||
// If there is already a pdb file open, it is automatically closed.
|
||||
// Returns true on success.
|
||||
bool Open(const wstring &file, FileFormat format);
|
||||
|
||||
// Locates the pdb file for the given executable (exe or dll) file,
|
||||
// and opens it. If there is already a pdb file open, it is automatically
|
||||
// closed. Returns true on success.
|
||||
bool OpenExecutable(const wstring &exe_file);
|
||||
|
||||
// Writes a map file from the current pdb file to the given file stream.
|
||||
// Returns true on success.
|
||||
bool WriteMap(FILE *map_file);
|
||||
|
||||
// Closes the current pdb file and its associated resources.
|
||||
void Close();
|
||||
|
||||
// Retrieves information about the module's debugging file. Returns
|
||||
// true on success and false on failure.
|
||||
bool GetModuleInfo(PDBModuleInfo *info);
|
||||
|
||||
// Retrieves information about the module's PE file. Returns
|
||||
// true on success and false on failure.
|
||||
bool GetPEInfo(PEModuleInfo *info);
|
||||
|
||||
// Sets uses_guid to true if the opened file uses a new-style CodeView
|
||||
// record with a 128-bit GUID, or false if the opened file uses an old-style
|
||||
// CodeView record. When no GUID is available, a 32-bit signature should be
|
||||
// used to identify the module instead. If the information cannot be
|
||||
// determined, this method returns false.
|
||||
bool UsesGUID(bool *uses_guid);
|
||||
|
||||
private:
|
||||
// Outputs the line/address pairs for each line in the enumerator.
|
||||
// Returns true on success.
|
||||
bool PrintLines(IDiaEnumLineNumbers *lines);
|
||||
|
||||
// Outputs a function address and name, followed by its source line list.
|
||||
// block can be the same object as function, or it can be a reference
|
||||
// to a code block that is lexically part of this function, but
|
||||
// resides at a separate address.
|
||||
// Returns true on success.
|
||||
bool PrintFunction(IDiaSymbol *function, IDiaSymbol *block);
|
||||
|
||||
// Outputs all functions as described above. Returns true on success.
|
||||
bool PrintFunctions();
|
||||
|
||||
// Outputs all of the source files in the session's pdb file.
|
||||
// Returns true on success.
|
||||
bool PrintSourceFiles();
|
||||
|
||||
// Outputs all of the frame information necessary to construct stack
|
||||
// backtraces in the absence of frame pointers. Returns true on success.
|
||||
bool PrintFrameData();
|
||||
|
||||
// Outputs a single public symbol address and name, if the symbol corresponds
|
||||
// to a code address. Returns true on success. If symbol is does not
|
||||
// correspond to code, returns true without outputting anything.
|
||||
bool PrintCodePublicSymbol(IDiaSymbol *symbol);
|
||||
|
||||
// Outputs a line identifying the PDB file that is being dumped, along with
|
||||
// its uuid and age.
|
||||
bool PrintPDBInfo();
|
||||
|
||||
// Outputs a line identifying the PE file corresponding to the PDB
|
||||
// file that is being dumped, along with its code identifier,
|
||||
// which consists of its timestamp and file size.
|
||||
bool PrintPEInfo();
|
||||
|
||||
// Returns true if this filename has already been seen,
|
||||
// and an ID is stored for it, or false if it has not.
|
||||
bool FileIDIsCached(const wstring &file) {
|
||||
return unique_files_.find(file) != unique_files_.end();
|
||||
};
|
||||
|
||||
// Cache this filename and ID for later reuse.
|
||||
void CacheFileID(const wstring &file, DWORD id) {
|
||||
unique_files_[file] = id;
|
||||
};
|
||||
|
||||
// Store this ID in the cache as a duplicate for this filename.
|
||||
void StoreDuplicateFileID(const wstring &file, DWORD id) {
|
||||
hash_map<wstring, DWORD>::iterator iter = unique_files_.find(file);
|
||||
if (iter != unique_files_.end()) {
|
||||
// map this id to the previously seen one
|
||||
file_ids_[id] = iter->second;
|
||||
}
|
||||
};
|
||||
|
||||
// Given a file's unique ID, return the ID that should be used to
|
||||
// reference it. There may be multiple files with identical filenames
|
||||
// but different unique IDs. The cache attempts to coalesce these into
|
||||
// one ID per unique filename.
|
||||
DWORD GetRealFileID(DWORD id) {
|
||||
hash_map<DWORD, DWORD>::iterator iter = file_ids_.find(id);
|
||||
if (iter == file_ids_.end())
|
||||
return id;
|
||||
return iter->second;
|
||||
};
|
||||
|
||||
// Find the PE file corresponding to the loaded PDB file, and
|
||||
// set the code_file_ member. Returns false on failure.
|
||||
bool FindPEFile();
|
||||
|
||||
// Returns the function name for a symbol. If possible, the name is
|
||||
// undecorated. If the symbol's decorated form indicates the size of
|
||||
// parameters on the stack, this information is returned in stack_param_size.
|
||||
// Returns true on success. If the symbol doesn't encode parameter size
|
||||
// information, stack_param_size is set to -1.
|
||||
static bool GetSymbolFunctionName(IDiaSymbol *function, BSTR *name,
|
||||
int *stack_param_size);
|
||||
|
||||
// Returns the number of bytes of stack space used for a function's
|
||||
// parameters. function must have the tag SymTagFunction. In the event of
|
||||
// a failure, returns 0, which is also a valid number of bytes.
|
||||
static int GetFunctionStackParamSize(IDiaSymbol *function);
|
||||
|
||||
// The filename of the PE file corresponding to the currently-open
|
||||
// pdb file.
|
||||
wstring code_file_;
|
||||
|
||||
// The session for the currently-open pdb file.
|
||||
CComPtr<IDiaSession> session_;
|
||||
|
||||
// The current output file for this WriteMap invocation.
|
||||
FILE *output_;
|
||||
|
||||
// There may be many duplicate filenames with different IDs.
|
||||
// This maps from the DIA "unique ID" to a single ID per unique
|
||||
// filename.
|
||||
hash_map<DWORD, DWORD> file_ids_;
|
||||
// This maps unique filenames to file IDs.
|
||||
hash_map<wstring, DWORD> unique_files_;
|
||||
|
||||
// Disallow copy ctor and operator=
|
||||
PDBSourceLineWriter(const PDBSourceLineWriter&);
|
||||
void operator=(const PDBSourceLineWriter&);
|
||||
};
|
||||
|
||||
} // namespace google_breakpad
|
||||
|
||||
#endif // _PDB_SOURCE_LINE_WRITER_H__
|
142
thirdparty/breakpad/common/windows/string_utils-inl.h
vendored
Normal file
142
thirdparty/breakpad/common/windows/string_utils-inl.h
vendored
Normal file
@@ -0,0 +1,142 @@
|
||||
// Copyright (c) 2006, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// string_utils-inl.h: Safer string manipulation on Windows, supporting
|
||||
// pre-MSVC8 environments.
|
||||
|
||||
#ifndef COMMON_WINDOWS_STRING_UTILS_INL_H__
|
||||
#define COMMON_WINDOWS_STRING_UTILS_INL_H__
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <wchar.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
// The "ll" printf format size specifier corresponding to |long long| was
|
||||
// intrudced in MSVC8. Earlier versions did not provide this size specifier,
|
||||
// but "I64" can be used to print 64-bit types. Don't use "I64" where "ll"
|
||||
// is available, in the event of oddball systems where |long long| is not
|
||||
// 64 bits wide.
|
||||
#if _MSC_VER >= 1400 // MSVC 2005/8
|
||||
#define WIN_STRING_FORMAT_LL "ll"
|
||||
#else // MSC_VER >= 1400
|
||||
#define WIN_STRING_FORMAT_LL "I64"
|
||||
#endif // MSC_VER >= 1400
|
||||
|
||||
// A nonconforming version of swprintf, without the length argument, was
|
||||
// included with the CRT prior to MSVC8. Although a conforming version was
|
||||
// also available via an overload, it is not reliably chosen. _snwprintf
|
||||
// behaves as a standards-confirming swprintf should, so force the use of
|
||||
// _snwprintf when using older CRTs.
|
||||
#if _MSC_VER < 1400 // MSVC 2005/8
|
||||
#define swprintf _snwprintf
|
||||
#else
|
||||
// For MSVC8 and newer, swprintf_s is the recommended method. Conveniently,
|
||||
// it takes the same argument list as swprintf.
|
||||
#define swprintf swprintf_s
|
||||
#endif // MSC_VER < 1400
|
||||
|
||||
namespace google_breakpad {
|
||||
|
||||
using std::string;
|
||||
using std::wstring;
|
||||
|
||||
class WindowsStringUtils {
|
||||
public:
|
||||
// Roughly equivalent to MSVC8's wcscpy_s, except pre-MSVC8, this does
|
||||
// not fail if source is longer than destination_size. The destination
|
||||
// buffer is always 0-terminated.
|
||||
static void safe_wcscpy(wchar_t *destination, size_t destination_size,
|
||||
const wchar_t *source);
|
||||
|
||||
// Roughly equivalent to MSVC8's wcsncpy_s, except that _TRUNCATE cannot
|
||||
// be passed directly, and pre-MSVC8, this will not fail if source or count
|
||||
// are longer than destination_size. The destination buffer is always
|
||||
// 0-terminated.
|
||||
static void safe_wcsncpy(wchar_t *destination, size_t destination_size,
|
||||
const wchar_t *source, size_t count);
|
||||
|
||||
// Performs multi-byte to wide character conversion on C++ strings, using
|
||||
// mbstowcs_s (MSVC8) or mbstowcs (pre-MSVC8). Returns false on failure,
|
||||
// without setting wcs.
|
||||
static bool safe_mbstowcs(const string &mbs, wstring *wcs);
|
||||
|
||||
// The inverse of safe_mbstowcs.
|
||||
static bool safe_wcstombs(const wstring &wcs, string *mbs);
|
||||
|
||||
// Returns the base name of a file, e.g. strips off the path.
|
||||
static wstring GetBaseName(const wstring &filename);
|
||||
|
||||
private:
|
||||
// Disallow instantiation and other object-based operations.
|
||||
WindowsStringUtils();
|
||||
WindowsStringUtils(const WindowsStringUtils&);
|
||||
~WindowsStringUtils();
|
||||
void operator=(const WindowsStringUtils&);
|
||||
};
|
||||
|
||||
// static
|
||||
inline void WindowsStringUtils::safe_wcscpy(wchar_t *destination,
|
||||
size_t destination_size,
|
||||
const wchar_t *source) {
|
||||
#if _MSC_VER >= 1400 // MSVC 2005/8
|
||||
wcscpy_s(destination, destination_size, source);
|
||||
#else // _MSC_VER >= 1400
|
||||
// Pre-MSVC 2005/8 doesn't have wcscpy_s. Simulate it with wcsncpy.
|
||||
// wcsncpy doesn't 0-terminate the destination buffer if the source string
|
||||
// is longer than size. Ensure that the destination is 0-terminated.
|
||||
wcsncpy(destination, source, destination_size);
|
||||
if (destination && destination_size)
|
||||
destination[destination_size - 1] = 0;
|
||||
#endif // _MSC_VER >= 1400
|
||||
}
|
||||
|
||||
// static
|
||||
inline void WindowsStringUtils::safe_wcsncpy(wchar_t *destination,
|
||||
size_t destination_size,
|
||||
const wchar_t *source,
|
||||
size_t count) {
|
||||
#if _MSC_VER >= 1400 // MSVC 2005/8
|
||||
wcsncpy_s(destination, destination_size, source, count);
|
||||
#else // _MSC_VER >= 1400
|
||||
// Pre-MSVC 2005/8 doesn't have wcsncpy_s. Simulate it with wcsncpy.
|
||||
// wcsncpy doesn't 0-terminate the destination buffer if the source string
|
||||
// is longer than size. Ensure that the destination is 0-terminated.
|
||||
if (destination_size < count)
|
||||
count = destination_size;
|
||||
|
||||
wcsncpy(destination, source, count);
|
||||
if (destination && count)
|
||||
destination[count - 1] = 0;
|
||||
#endif // _MSC_VER >= 1400
|
||||
}
|
||||
|
||||
} // namespace google_breakpad
|
||||
|
||||
#endif // COMMON_WINDOWS_STRING_UTILS_INL_H__
|
133
thirdparty/breakpad/common/windows/string_utils.cc
vendored
Normal file
133
thirdparty/breakpad/common/windows/string_utils.cc
vendored
Normal file
@@ -0,0 +1,133 @@
|
||||
// Copyright (c) 2006, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include <cassert>
|
||||
#include <vector>
|
||||
|
||||
#include "common/windows/string_utils-inl.h"
|
||||
|
||||
namespace google_breakpad {
|
||||
|
||||
// static
|
||||
wstring WindowsStringUtils::GetBaseName(const wstring &filename) {
|
||||
wstring base_name(filename);
|
||||
size_t slash_pos = base_name.find_last_of(L"/\\");
|
||||
if (slash_pos != wstring::npos) {
|
||||
base_name.erase(0, slash_pos + 1);
|
||||
}
|
||||
return base_name;
|
||||
}
|
||||
|
||||
// static
|
||||
bool WindowsStringUtils::safe_mbstowcs(const string &mbs, wstring *wcs) {
|
||||
assert(wcs);
|
||||
|
||||
// First, determine the length of the destination buffer.
|
||||
size_t wcs_length;
|
||||
|
||||
#if _MSC_VER >= 1400 // MSVC 2005/8
|
||||
errno_t err;
|
||||
if ((err = mbstowcs_s(&wcs_length, NULL, 0, mbs.c_str(), _TRUNCATE)) != 0) {
|
||||
return false;
|
||||
}
|
||||
assert(wcs_length > 0);
|
||||
#else // _MSC_VER >= 1400
|
||||
if ((wcs_length = mbstowcs(NULL, mbs.c_str(), mbs.length())) < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Leave space for the 0-terminator.
|
||||
++wcs_length;
|
||||
#endif // _MSC_VER >= 1400
|
||||
|
||||
std::vector<wchar_t> wcs_v(wcs_length);
|
||||
|
||||
// Now, convert.
|
||||
#if _MSC_VER >= 1400 // MSVC 2005/8
|
||||
if ((err = mbstowcs_s(NULL, &wcs_v[0], wcs_length, mbs.c_str(),
|
||||
_TRUNCATE)) != 0) {
|
||||
return false;
|
||||
}
|
||||
#else // _MSC_VER >= 1400
|
||||
if (mbstowcs(&wcs_v[0], mbs.c_str(), mbs.length()) < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Ensure presence of 0-terminator.
|
||||
wcs_v[wcs_length - 1] = '\0';
|
||||
#endif // _MSC_VER >= 1400
|
||||
|
||||
*wcs = &wcs_v[0];
|
||||
return true;
|
||||
}
|
||||
|
||||
// static
|
||||
bool WindowsStringUtils::safe_wcstombs(const wstring &wcs, string *mbs) {
|
||||
assert(mbs);
|
||||
|
||||
// First, determine the length of the destination buffer.
|
||||
size_t mbs_length;
|
||||
|
||||
#if _MSC_VER >= 1400 // MSVC 2005/8
|
||||
errno_t err;
|
||||
if ((err = wcstombs_s(&mbs_length, NULL, 0, wcs.c_str(), _TRUNCATE)) != 0) {
|
||||
return false;
|
||||
}
|
||||
assert(mbs_length > 0);
|
||||
#else // _MSC_VER >= 1400
|
||||
if ((mbs_length = wcstombs(NULL, wcs.c_str(), wcs.length())) < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Leave space for the 0-terminator.
|
||||
++mbs_length;
|
||||
#endif // _MSC_VER >= 1400
|
||||
|
||||
std::vector<char> mbs_v(mbs_length);
|
||||
|
||||
// Now, convert.
|
||||
#if _MSC_VER >= 1400 // MSVC 2005/8
|
||||
if ((err = wcstombs_s(NULL, &mbs_v[0], mbs_length, wcs.c_str(),
|
||||
_TRUNCATE)) != 0) {
|
||||
return false;
|
||||
}
|
||||
#else // _MSC_VER >= 1400
|
||||
if (wcstombs(&mbs_v[0], wcs.c_str(), wcs.length()) < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Ensure presence of 0-terminator.
|
||||
mbs_v[mbs_length - 1] = '\0';
|
||||
#endif // _MSC_VER >= 1400
|
||||
|
||||
*mbs = &mbs_v[0];
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace google_breakpad
|
Reference in New Issue
Block a user