crashpad/util/misc/reinterpret_bytes.cc
Mark Mentovai 6278690abe Update copyright boilerplate, 2022 edition (Crashpad)
sed -i '' -E -e 's/Copyright (.+) The Crashpad Authors\. All rights reserved\.$/Copyright \1 The Crashpad Authors/' $(git grep -El 'Copyright (.+) The Crashpad Authors\. All rights reserved\.$')

Bug: chromium:1098010
Change-Id: I8d6138469ddbe3d281a5d83f64cf918ec2491611
Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/3878262
Reviewed-by: Joshua Peraza <jperaza@chromium.org>
Commit-Queue: Mark Mentovai <mark@chromium.org>
2022-09-06 23:54:07 +00:00

71 lines
2.2 KiB
C++

// Copyright 2017 The Crashpad Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "util/misc/reinterpret_bytes.h"
#include <string.h>
#include <algorithm>
#include "base/logging.h"
namespace crashpad {
namespace internal {
bool ReinterpretBytesImpl(const char* data,
size_t data_size,
char* dest,
size_t dest_size) {
// Verify that any unused bytes from data are zero.
// The unused bytes are at the start of the data buffer for big-endian and the
// end of the buffer for little-endian.
if (dest_size < data_size) {
auto extra_bytes = data;
#if defined(ARCH_CPU_LITTLE_ENDIAN)
extra_bytes += dest_size;
#endif // ARCH_CPU_LITTLE_ENDIAN
uint64_t zero = 0;
size_t extra_bytes_size = data_size - dest_size;
while (extra_bytes_size > 0) {
size_t to_check = std::min(extra_bytes_size, sizeof(zero));
if (memcmp(extra_bytes, &zero, to_check) != 0) {
LOG(ERROR) << "information loss";
return false;
}
extra_bytes += to_check;
extra_bytes_size -= to_check;
}
}
// Zero out the destination, in case it is larger than data.
memset(dest, 0, dest_size);
#if defined(ARCH_CPU_LITTLE_ENDIAN)
// Copy a prefix of data to a prefix of dest for little-endian
memcpy(dest, data, std::min(dest_size, data_size));
#else
// or the suffix of data to the suffix of dest for big-endian
if (data_size >= dest_size) {
memcpy(dest, data + data_size - dest_size, dest_size);
} else {
memcpy(dest + dest_size - data_size, data, data_size);
}
#endif // ARCH_CPU_LITTLE_ENDIAN
return true;
}
} // namespace internal
} // namespace crashpad