Get rid of pointer arithmetic in *MSBFIRST() and *LSBFIRST() macros.
Replace the macros with inline functions taking spans as arguments.
-- Rework byteorder.h to be self-consistent about #ifdef endian.
-- Add From{16,32}{BE,LE}() functions that read better to me.
Change-Id: I446c4e5202f6cb5d4d4f8ee2e1b2f61513ed521c
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/116530
Reviewed-by: Lei Zhang <thestig@chromium.org>
Reviewed-by: Thomas Sepez <tsepez@google.com>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/core/fdrm/fx_crypt_aes.cpp b/core/fdrm/fx_crypt_aes.cpp
index 104c9f1..eb644a3 100644
--- a/core/fdrm/fx_crypt_aes.cpp
+++ b/core/fdrm/fx_crypt_aes.cpp
@@ -8,18 +8,11 @@
#include <string.h>
-#include "core/fxcrt/fx_system.h"
+#include "core/fxcrt/byteorder.h"
#include "third_party/base/check.h"
#include "third_party/base/check_op.h"
#define mulby2(x) (((x & 0x7F) << 1) ^ (x & 0x80 ? 0x1B : 0))
-#define PUT_32BIT_MSB_FIRST(cp, value) \
- do { \
- (cp)[3] = (value); \
- (cp)[2] = (value) >> 8; \
- (cp)[1] = (value) >> 16; \
- (cp)[0] = (value) >> 24; \
- } while (0)
namespace {
@@ -528,13 +521,14 @@
const uint8_t* key,
uint32_t keylen) {
DCHECK(keylen == 16 || keylen == 24 || keylen == 32);
+ auto keyspan = pdfium::make_span(key, keylen);
int Nk = keylen / 4;
ctx->Nb = 4;
ctx->Nr = 6 + (ctx->Nb > Nk ? ctx->Nb : Nk);
int rconst = 1;
for (int i = 0; i < (ctx->Nr + 1) * ctx->Nb; i++) {
if (i < Nk) {
- ctx->keysched[i] = FXSYS_UINT32_GET_MSBFIRST(key + 4 * i);
+ ctx->keysched[i] = fxcrt::GetUInt32MSBFirst(keyspan.subspan(4 * i));
} else {
unsigned int temp = ctx->keysched[i - 1];
if (i % Nk == 0) {
@@ -581,7 +575,8 @@
void CRYPT_AESSetIV(CRYPT_aes_context* ctx, const uint8_t* iv) {
for (int i = 0; i < ctx->Nb; i++) {
- ctx->iv[i] = FXSYS_UINT32_GET_MSBFIRST(iv + 4 * i);
+ // TODO(tsepez): Pass actual span.
+ ctx->iv[i] = fxcrt::GetUInt32MSBFirst(pdfium::make_span(iv + 4 * i, 4u));
}
}
@@ -597,11 +592,13 @@
memcpy(iv, ctx->iv, sizeof(iv));
while (size != 0) {
for (i = 0; i < 4; i++) {
- x[i] = ct[i] = FXSYS_UINT32_GET_MSBFIRST(src + 4 * i);
+ // TODO(tsepez): Create actual span.
+ x[i] = ct[i] = fxcrt::GetUInt32MSBFirst(pdfium::span(src + 4 * i, 4u));
}
aes_decrypt_nb_4(ctx, x);
for (i = 0; i < 4; i++) {
- PUT_32BIT_MSB_FIRST(dest + 4 * i, iv[i] ^ x[i]);
+ // TODO(tsepez): Create actual span.
+ fxcrt::PutUInt32MSBFirst(iv[i] ^ x[i], pdfium::span(dest + 4 * i, 4u));
iv[i] = ct[i];
}
dest += 16;
@@ -621,11 +618,13 @@
memcpy(iv, ctx->iv, sizeof(iv));
while (size != 0) {
for (i = 0; i < 4; i++) {
- iv[i] ^= FXSYS_UINT32_GET_MSBFIRST(src + 4 * i);
+ // TODO(tsepez): use an actual span.
+ iv[i] ^= fxcrt::GetUInt32MSBFirst(pdfium::span(src + 4 * i, 4u));
}
aes_encrypt_nb_4(ctx, iv);
for (i = 0; i < 4; i++) {
- PUT_32BIT_MSB_FIRST(dest + 4 * i, iv[i]);
+ // TODO(tsepez): use an actual span.
+ fxcrt::PutUInt32MSBFirst(iv[i], pdfium::span(dest + 4 * i, 4u));
}
dest += 16;
src += 16;
diff --git a/core/fpdfapi/font/cfx_cttgsubtable.cpp b/core/fpdfapi/font/cfx_cttgsubtable.cpp
index bf9566c..651faf0 100644
--- a/core/fpdfapi/font/cfx_cttgsubtable.cpp
+++ b/core/fpdfapi/font/cfx_cttgsubtable.cpp
@@ -10,8 +10,8 @@
#include <utility>
+#include "core/fxcrt/byteorder.h"
#include "core/fxcrt/data_vector.h"
-#include "core/fxcrt/fx_system.h"
#include "core/fxcrt/stl_util.h"
#include "core/fxge/cfx_fontmapper.h"
@@ -56,15 +56,16 @@
CFX_CTTGSUBTable::~CFX_CTTGSUBTable() = default;
bool CFX_CTTGSUBTable::LoadGSUBTable(pdfium::span<const uint8_t> gsub) {
- if (FXSYS_UINT32_GET_MSBFIRST(gsub) != 0x00010000)
+ if (fxcrt::GetUInt32MSBFirst(gsub) != 0x00010000) {
return false;
+ }
auto scriptlist_span = gsub.subspan(4, 2);
auto featurelist_span = gsub.subspan(6, 2);
auto lookuplist_span = gsub.subspan(8, 2);
- size_t scriptlist_index = FXSYS_UINT16_GET_MSBFIRST(scriptlist_span);
- size_t featurelist_index = FXSYS_UINT16_GET_MSBFIRST(featurelist_span);
- size_t lookuplist_index = FXSYS_UINT16_GET_MSBFIRST(lookuplist_span);
+ size_t scriptlist_index = fxcrt::GetUInt16MSBFirst(scriptlist_span);
+ size_t featurelist_index = fxcrt::GetUInt16MSBFirst(featurelist_span);
+ size_t lookuplist_index = fxcrt::GetUInt16MSBFirst(lookuplist_span);
Parse(gsub.subspan(scriptlist_index), gsub.subspan(featurelist_index),
gsub.subspan(lookuplist_index));
return true;
@@ -158,25 +159,29 @@
}
int16_t CFX_CTTGSUBTable::GetInt16(const uint8_t*& p) const {
- uint16_t ret = FXSYS_UINT16_GET_MSBFIRST(p);
+ // TODO(tsepez): pass actual span.
+ uint16_t ret = fxcrt::GetUInt16MSBFirst(pdfium::make_span(p, 2u));
p += 2;
- return *reinterpret_cast<int16_t*>(&ret);
+ return static_cast<int16_t>(ret);
}
uint16_t CFX_CTTGSUBTable::GetUInt16(const uint8_t*& p) const {
- uint16_t ret = FXSYS_UINT16_GET_MSBFIRST(p);
+ // TODO(tsepez): pass actual span.
+ uint16_t ret = fxcrt::GetUInt16MSBFirst(pdfium::make_span(p, 2u));
p += 2;
return ret;
}
int32_t CFX_CTTGSUBTable::GetInt32(const uint8_t*& p) const {
- uint32_t ret = FXSYS_UINT32_GET_MSBFIRST(p);
+ // TODO(tsepez): pass actual span.
+ uint32_t ret = fxcrt::GetUInt32MSBFirst(pdfium::make_span(p, 4u));
p += 4;
- return *reinterpret_cast<int32_t*>(&ret);
+ return static_cast<int32_t>(ret);
}
uint32_t CFX_CTTGSUBTable::GetUInt32(const uint8_t*& p) const {
- uint32_t ret = FXSYS_UINT32_GET_MSBFIRST(p);
+ // TODO(tsepez): pass actual span.
+ uint32_t ret = fxcrt::GetUInt32MSBFirst(pdfium::make_span(p, 4u));
p += 4;
return ret;
}
diff --git a/core/fpdfapi/parser/cpdf_security_handler.cpp b/core/fpdfapi/parser/cpdf_security_handler.cpp
index 96da9c4..175fd9d 100644
--- a/core/fpdfapi/parser/cpdf_security_handler.cpp
+++ b/core/fpdfapi/parser/cpdf_security_handler.cpp
@@ -18,6 +18,7 @@
#include "core/fpdfapi/parser/cpdf_dictionary.h"
#include "core/fpdfapi/parser/cpdf_object.h"
#include "core/fpdfapi/parser/cpdf_string.h"
+#include "core/fxcrt/byteorder.h"
#include "core/fxcrt/data_vector.h"
#include "core/fxcrt/fx_memcpy_wrappers.h"
#include "core/fxcrt/fx_random.h"
@@ -388,8 +389,9 @@
if (buf[9] != 'a' || buf[10] != 'd' || buf[11] != 'b')
return false;
- if (FXSYS_UINT32_GET_LSBFIRST(buf) != m_Permissions)
+ if (fxcrt::GetUInt32LSBFirst(buf) != m_Permissions) {
return false;
+ }
// Relax this check as there appear to be some non-conforming documents
// in the wild. The value in the buffer is the truth; if it requires us
diff --git a/core/fxcodec/basic/basicmodule.cpp b/core/fxcodec/basic/basicmodule.cpp
index 07fc896..aeddee9 100644
--- a/core/fxcodec/basic/basicmodule.cpp
+++ b/core/fxcodec/basic/basicmodule.cpp
@@ -10,10 +10,10 @@
#include <utility>
#include "core/fxcodec/scanlinedecoder.h"
+#include "core/fxcrt/byteorder.h"
#include "core/fxcrt/data_vector.h"
#include "core/fxcrt/fx_memory_wrappers.h"
#include "core/fxcrt/fx_safe_types.h"
-#include "core/fxcrt/fx_system.h"
#include "core/fxcrt/span_util.h"
#include "third_party/base/check.h"
#include "third_party/base/numerics/safe_conversions.h"
@@ -331,7 +331,7 @@
uint32_t line_length = 0;
while (src_span.size() >= 4 && pos < src_span.size() - 3) {
auto val_span = src_span.subspan(pos, 4);
- uint32_t val = FXSYS_UINT32_GET_MSBFIRST(val_span);
+ uint32_t val = fxcrt::GetUInt32MSBFirst(val_span);
pos += 4;
if (val == 0) { // All zero special case
result_span[0] = 'z';
diff --git a/core/fxcodec/bmp/cfx_bmpdecompressor.cpp b/core/fxcodec/bmp/cfx_bmpdecompressor.cpp
index 1566038..2f0a3e9 100644
--- a/core/fxcodec/bmp/cfx_bmpdecompressor.cpp
+++ b/core/fxcodec/bmp/cfx_bmpdecompressor.cpp
@@ -14,9 +14,9 @@
#include "core/fxcodec/bmp/cfx_bmpcontext.h"
#include "core/fxcodec/cfx_codec_memory.h"
+#include "core/fxcrt/byteorder.h"
#include "core/fxcrt/data_vector.h"
#include "core/fxcrt/fx_safe_types.h"
-#include "core/fxcrt/fx_system.h"
#include "core/fxcrt/span_util.h"
#include "core/fxge/calculate_pitch.h"
#include "third_party/base/numerics/safe_math.h"
@@ -94,12 +94,9 @@
return BmpDecoder::Status::kContinue;
}
- bmp_header.bfType =
- FXSYS_UINT16_GET_LSBFIRST(reinterpret_cast<uint8_t*>(&bmp_header.bfType));
- data_offset_ = FXSYS_UINT32_GET_LSBFIRST(
- reinterpret_cast<uint8_t*>(&bmp_header.bfOffBits));
- data_size_ =
- FXSYS_UINT32_GET_LSBFIRST(reinterpret_cast<uint8_t*>(&bmp_header.bfSize));
+ bmp_header.bfType = fxcrt::FromLE16(bmp_header.bfType);
+ data_offset_ = fxcrt::FromLE32(bmp_header.bfOffBits);
+ data_size_ = fxcrt::FromLE32(bmp_header.bfSize);
if (bmp_header.bfType != kBmpSignature)
return BmpDecoder::Status::kFail;
@@ -111,8 +108,7 @@
if (!input_buffer_->Seek(pos))
return BmpDecoder::Status::kFail;
- img_ifh_size_ =
- FXSYS_UINT32_GET_LSBFIRST(reinterpret_cast<uint8_t*>(&img_ifh_size_));
+ img_ifh_size_ = fxcrt::FromLE32(img_ifh_size_);
pal_type_ = PalType::kNew;
BmpDecoder::Status status = ReadBmpHeaderIfh();
if (status != BmpDecoder::Status::kSuccess)
@@ -130,12 +126,9 @@
return BmpDecoder::Status::kContinue;
}
- width_ = FXSYS_UINT16_GET_LSBFIRST(
- reinterpret_cast<uint8_t*>(&bmp_core_header.bcWidth));
- height_ = FXSYS_UINT16_GET_LSBFIRST(
- reinterpret_cast<uint8_t*>(&bmp_core_header.bcHeight));
- bit_counts_ = FXSYS_UINT16_GET_LSBFIRST(
- reinterpret_cast<uint8_t*>(&bmp_core_header.bcBitCount));
+ width_ = fxcrt::FromLE16(bmp_core_header.bcWidth);
+ height_ = fxcrt::FromLE16(bmp_core_header.bcHeight);
+ bit_counts_ = fxcrt::FromLE16(bmp_core_header.bcBitCount);
compress_flag_ = kBmpRgb;
img_tb_flag_ = false;
return BmpDecoder::Status::kSuccess;
@@ -148,22 +141,19 @@
return BmpDecoder::Status::kContinue;
}
- width_ = FXSYS_UINT32_GET_LSBFIRST(
- reinterpret_cast<uint8_t*>(&bmp_info_header.biWidth));
- int32_t signed_height = FXSYS_UINT32_GET_LSBFIRST(
- reinterpret_cast<uint8_t*>(&bmp_info_header.biHeight));
- bit_counts_ = FXSYS_UINT16_GET_LSBFIRST(
- reinterpret_cast<uint8_t*>(&bmp_info_header.biBitCount));
- compress_flag_ = FXSYS_UINT32_GET_LSBFIRST(
- reinterpret_cast<uint8_t*>(&bmp_info_header.biCompression));
- color_used_ = FXSYS_UINT32_GET_LSBFIRST(
- reinterpret_cast<uint8_t*>(&bmp_info_header.biClrUsed));
- dpi_x_ = static_cast<int32_t>(FXSYS_UINT32_GET_LSBFIRST(
- reinterpret_cast<uint8_t*>(&bmp_info_header.biXPelsPerMeter)));
- dpi_y_ = static_cast<int32_t>(FXSYS_UINT32_GET_LSBFIRST(
- reinterpret_cast<uint8_t*>(&bmp_info_header.biYPelsPerMeter)));
- if (!SetHeight(signed_height))
+ width_ = fxcrt::FromLE32(bmp_info_header.biWidth);
+ bit_counts_ = fxcrt::FromLE16(bmp_info_header.biBitCount);
+ compress_flag_ = fxcrt::FromLE32(bmp_info_header.biCompression);
+ color_used_ = fxcrt::FromLE32(bmp_info_header.biClrUsed);
+ dpi_x_ =
+ static_cast<int32_t>(fxcrt::FromLE32(bmp_info_header.biXPelsPerMeter));
+ dpi_y_ =
+ static_cast<int32_t>(fxcrt::FromLE32(bmp_info_header.biYPelsPerMeter));
+
+ int32_t signed_height = fxcrt::FromLE32(bmp_info_header.biHeight);
+ if (!SetHeight(signed_height)) {
return BmpDecoder::Status::kFail;
+ }
return BmpDecoder::Status::kSuccess;
}
@@ -184,27 +174,21 @@
if (!input_buffer_->Seek(new_pos.ValueOrDie()))
return BmpDecoder::Status::kContinue;
- uint16_t bi_planes;
- width_ = FXSYS_UINT32_GET_LSBFIRST(
- reinterpret_cast<uint8_t*>(&bmp_info_header.biWidth));
- int32_t signed_height = FXSYS_UINT32_GET_LSBFIRST(
- reinterpret_cast<uint8_t*>(&bmp_info_header.biHeight));
- bit_counts_ = FXSYS_UINT16_GET_LSBFIRST(
- reinterpret_cast<uint8_t*>(&bmp_info_header.biBitCount));
- compress_flag_ = FXSYS_UINT32_GET_LSBFIRST(
- reinterpret_cast<uint8_t*>(&bmp_info_header.biCompression));
- color_used_ = FXSYS_UINT32_GET_LSBFIRST(
- reinterpret_cast<uint8_t*>(&bmp_info_header.biClrUsed));
- bi_planes = FXSYS_UINT16_GET_LSBFIRST(
- reinterpret_cast<uint8_t*>(&bmp_info_header.biPlanes));
- dpi_x_ = FXSYS_UINT32_GET_LSBFIRST(
- reinterpret_cast<uint8_t*>(&bmp_info_header.biXPelsPerMeter));
- dpi_y_ = FXSYS_UINT32_GET_LSBFIRST(
- reinterpret_cast<uint8_t*>(&bmp_info_header.biYPelsPerMeter));
- if (!SetHeight(signed_height))
+ width_ = fxcrt::FromLE32(bmp_info_header.biWidth);
+ bit_counts_ = fxcrt::FromLE16(bmp_info_header.biBitCount);
+ compress_flag_ = fxcrt::FromLE32(bmp_info_header.biCompression);
+ color_used_ = fxcrt::FromLE32(bmp_info_header.biClrUsed);
+ dpi_x_ = fxcrt::FromLE32(bmp_info_header.biXPelsPerMeter);
+ dpi_y_ = fxcrt::FromLE32(bmp_info_header.biYPelsPerMeter);
+
+ int32_t signed_height = fxcrt::FromLE32(bmp_info_header.biHeight);
+ if (!SetHeight(signed_height)) {
return BmpDecoder::Status::kFail;
- if (compress_flag_ != kBmpRgb || bi_planes != 1 || color_used_ != 0)
+ }
+ uint16_t bi_planes = fxcrt::FromLE16(bmp_info_header.biPlanes);
+ if (compress_flag_ != kBmpRgb || bi_planes != 1 || color_used_ != 0) {
return BmpDecoder::Status::kFail;
+ }
return BmpDecoder::Status::kSuccess;
}
@@ -275,10 +259,9 @@
if (!ReadAllOrNone(pdfium::as_writable_bytes(pdfium::make_span(masks))))
return BmpDecoder::Status::kContinue;
- mask_red_ = FXSYS_UINT32_GET_LSBFIRST(reinterpret_cast<uint8_t*>(&masks[0]));
- mask_green_ =
- FXSYS_UINT32_GET_LSBFIRST(reinterpret_cast<uint8_t*>(&masks[1]));
- mask_blue_ = FXSYS_UINT32_GET_LSBFIRST(reinterpret_cast<uint8_t*>(&masks[2]));
+ mask_red_ = fxcrt::FromLE32(masks[0]);
+ mask_green_ = fxcrt::FromLE32(masks[1]);
+ mask_blue_ = fxcrt::FromLE32(masks[2]);
if (mask_red_ & mask_green_ || mask_red_ & mask_blue_ ||
mask_green_ & mask_blue_) {
return BmpDecoder::Status::kFail;
@@ -413,7 +396,8 @@
break;
}
case 16: {
- uint16_t* buf = reinterpret_cast<uint16_t*>(dest_buf.data());
+ auto buf =
+ fxcrt::reinterpret_span<uint16_t>(pdfium::make_span(dest_buf));
uint8_t blue_bits = 0;
uint8_t green_bits = 0;
uint8_t red_bits = 0;
@@ -433,13 +417,14 @@
green_bits -= 8;
red_bits -= 8;
for (uint32_t col = 0; col < width_; ++col) {
- *buf = FXSYS_UINT16_GET_LSBFIRST(reinterpret_cast<uint8_t*>(buf));
+ buf.front() = fxcrt::FromLE16(buf.front());
out_row_buffer_[idx++] =
- static_cast<uint8_t>((*buf & mask_blue_) << blue_bits);
+ static_cast<uint8_t>((buf.front() & mask_blue_) << blue_bits);
out_row_buffer_[idx++] =
- static_cast<uint8_t>((*buf & mask_green_) >> green_bits);
+ static_cast<uint8_t>((buf.front() & mask_green_) >> green_bits);
out_row_buffer_[idx++] =
- static_cast<uint8_t>((*buf++ & mask_red_) >> red_bits);
+ static_cast<uint8_t>((buf.front() & mask_red_) >> red_bits);
+ buf = buf.subspan(1);
}
break;
}
diff --git a/core/fxcodec/gif/cfx_gifcontext.cpp b/core/fxcodec/gif/cfx_gifcontext.cpp
index c094f84..6fa2bc8 100644
--- a/core/fxcodec/gif/cfx_gifcontext.cpp
+++ b/core/fxcodec/gif/cfx_gifcontext.cpp
@@ -14,8 +14,8 @@
#include <utility>
#include "core/fxcodec/cfx_codec_memory.h"
+#include "core/fxcrt/byteorder.h"
#include "core/fxcrt/data_vector.h"
-#include "core/fxcrt/fx_system.h"
#include "core/fxcrt/stl_util.h"
namespace fxcodec {
@@ -384,10 +384,8 @@
std::swap(global_palette_, palette);
}
- width_ = static_cast<int>(
- FXSYS_UINT16_GET_LSBFIRST(reinterpret_cast<uint8_t*>(&lsd.width)));
- height_ = static_cast<int>(
- FXSYS_UINT16_GET_LSBFIRST(reinterpret_cast<uint8_t*>(&lsd.height)));
+ width_ = fxcrt::FromLE16(lsd.width);
+ height_ = fxcrt::FromLE16(lsd.height);
return GifDecoder::Status::kSuccess;
}
@@ -429,8 +427,8 @@
std::make_unique<CFX_GifGraphicControlExtension>();
graphic_control_extension_->block_size = gif_gce.block_size;
graphic_control_extension_->gce_flags = gif_gce.gce_flags;
- graphic_control_extension_->delay_time = FXSYS_UINT16_GET_LSBFIRST(
- reinterpret_cast<uint8_t*>(&gif_gce.delay_time));
+ graphic_control_extension_->delay_time =
+ fxcrt::FromLE16(gif_gce.delay_time);
graphic_control_extension_->trans_index = gif_gce.trans_index;
break;
}
@@ -458,14 +456,10 @@
return GifDecoder::Status::kUnfinished;
auto gif_image = std::make_unique<CFX_GifImage>();
- gif_image->image_info.left =
- FXSYS_UINT16_GET_LSBFIRST(reinterpret_cast<uint8_t*>(&img_info.left));
- gif_image->image_info.top =
- FXSYS_UINT16_GET_LSBFIRST(reinterpret_cast<uint8_t*>(&img_info.top));
- gif_image->image_info.width =
- FXSYS_UINT16_GET_LSBFIRST(reinterpret_cast<uint8_t*>(&img_info.width));
- gif_image->image_info.height =
- FXSYS_UINT16_GET_LSBFIRST(reinterpret_cast<uint8_t*>(&img_info.height));
+ gif_image->image_info.left = fxcrt::FromLE16(img_info.left);
+ gif_image->image_info.top = fxcrt::FromLE16(img_info.top);
+ gif_image->image_info.width = fxcrt::FromLE16(img_info.width);
+ gif_image->image_info.height = fxcrt::FromLE16(img_info.height);
gif_image->image_info.local_flags = img_info.local_flags;
if (gif_image->image_info.left + gif_image->image_info.width > width_ ||
gif_image->image_info.top + gif_image->image_info.height > height_)
diff --git a/core/fxcrt/byteorder.h b/core/fxcrt/byteorder.h
index b6c7a64..b830b56 100644
--- a/core/fxcrt/byteorder.h
+++ b/core/fxcrt/byteorder.h
@@ -6,18 +6,29 @@
#define CORE_FXCRT_BYTEORDER_H_
#include "build/build_config.h"
+#include "third_party/base/containers/span.h"
#include "third_party/base/sys_byteorder.h"
namespace fxcrt {
+// NOTE: Prefer *Swap*() methods when data is known to be aligned.
+
// Converts the bytes in |x| from host order (endianness) to little endian, and
// returns the result.
inline uint16_t ByteSwapToLE16(uint16_t x) {
- return pdfium::base::ByteSwapToLE16(x);
+#if defined(ARCH_CPU_LITTLE_ENDIAN)
+ return x;
+#else
+ return pdfium::base::ByteSwap(x);
+#endif
}
inline uint32_t ByteSwapToLE32(uint32_t x) {
- return pdfium::base::ByteSwapToLE32(x);
+#if defined(ARCH_CPU_LITTLE_ENDIAN)
+ return x;
+#else
+ return pdfium::base::ByteSwap(x);
+#endif
}
// Converts the bytes in |x| from host order (endianness) to big endian, and
@@ -38,6 +49,67 @@
#endif
}
+// NOTE: These methods exist to improve readability by putting the word "From"
+// into the name, otherwise it is less clear that `x = ByteSwapToLE16(y)` gives
+// `x` in the native representation when `y` is in a LE representation.
+inline uint16_t FromLE16(uint16_t x) {
+ return ByteSwapToLE16(x);
+}
+inline uint32_t FromLE32(uint16_t x) {
+ return ByteSwapToLE32(x);
+}
+inline uint16_t FromBE16(uint16_t x) {
+ return ByteSwapToBE16(x);
+}
+inline uint32_t FromBE32(uint16_t x) {
+ return ByteSwapToBE32(x);
+}
+
+// Transfer to/from spans irrespective of alignments.
+inline uint16_t GetUInt16MSBFirst(pdfium::span<const uint8_t> span) {
+ return (static_cast<uint32_t>(span[0]) << 8) | static_cast<uint32_t>(span[1]);
+}
+
+inline uint32_t GetUInt32MSBFirst(pdfium::span<const uint8_t> span) {
+ return (static_cast<uint32_t>(span[0]) << 24) |
+ (static_cast<uint32_t>(span[1]) << 16) |
+ (static_cast<uint32_t>(span[2]) << 8) | static_cast<uint32_t>(span[3]);
+}
+
+inline uint16_t GetUInt16LSBFirst(pdfium::span<const uint8_t> span) {
+ return (static_cast<uint32_t>(span[1]) << 8) | static_cast<uint32_t>(span[0]);
+}
+
+inline uint32_t GetUInt32LSBFirst(pdfium::span<const uint8_t> span) {
+ return (static_cast<uint32_t>(span[3]) << 24) |
+ (static_cast<uint32_t>(span[2]) << 16) |
+ (static_cast<uint32_t>(span[1]) << 8) | static_cast<uint32_t>(span[0]);
+}
+
+inline void PutUInt16MSBFirst(uint16_t value, pdfium::span<uint8_t> span) {
+ span[0] = value >> 8;
+ span[1] = value & 0xff;
+}
+
+inline void PutUInt32MSBFirst(uint32_t value, pdfium::span<uint8_t> span) {
+ span[0] = value >> 24;
+ span[1] = (value >> 16) & 0xff;
+ span[2] = (value >> 8) & 0xff;
+ span[3] = value & 0xff;
+}
+
+inline void PutUInt16LSBFirst(uint16_t value, pdfium::span<uint8_t> span) {
+ span[1] = value >> 8;
+ span[0] = value & 0xff;
+}
+
+inline void PutUInt32LSBFirst(uint32_t value, pdfium::span<uint8_t> span) {
+ span[3] = value >> 24;
+ span[2] = (value >> 16) & 0xff;
+ span[1] = (value >> 8) & 0xff;
+ span[0] = value & 0xff;
+}
+
} // namespace fxcrt
#endif // CORE_FXCRT_BYTEORDER_H_
diff --git a/core/fxcrt/byteorder_unittest.cpp b/core/fxcrt/byteorder_unittest.cpp
index 6688934..d71ae61 100644
--- a/core/fxcrt/byteorder_unittest.cpp
+++ b/core/fxcrt/byteorder_unittest.cpp
@@ -5,6 +5,7 @@
#include "core/fxcrt/byteorder.h"
#include "core/fxcrt/fx_system.h"
+#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace {
@@ -22,24 +23,14 @@
// Since there are so few values, test them all.
for (uint32_t v = 0; v < 0x10000; ++v) {
const uint16_t v16 = v;
- uint16_t expected =
- FXSYS_UINT16_GET_LSBFIRST(reinterpret_cast<const uint8_t*>(&v16));
- EXPECT_EQ(expected, ByteSwapToLE16(v16)) << v;
-
- // Check safety against unexpectedly signed bytes.
- expected = FXSYS_UINT16_GET_LSBFIRST(reinterpret_cast<const int8_t*>(&v16));
+ uint16_t expected = GetUInt16LSBFirst(pdfium::byte_span_from_ref(v16));
EXPECT_EQ(expected, ByteSwapToLE16(v16)) << v;
}
}
TEST(ByteOrder, ByteSwapToLE32) {
for (uint32_t v : kTestValues32) {
- uint32_t expected =
- FXSYS_UINT32_GET_LSBFIRST(reinterpret_cast<const uint8_t*>(&v));
- EXPECT_EQ(expected, ByteSwapToLE32(v)) << v;
-
- // Check safety against unexpectedly signed bytes.
- expected = FXSYS_UINT32_GET_LSBFIRST(reinterpret_cast<const int8_t*>(&v));
+ uint32_t expected = GetUInt32LSBFirst(pdfium::byte_span_from_ref(v));
EXPECT_EQ(expected, ByteSwapToLE32(v)) << v;
}
}
@@ -48,26 +39,60 @@
// Since there are so few values, test them all.
for (uint32_t v = 0; v < 0x10000; ++v) {
const uint16_t v16 = v;
- uint16_t expected =
- FXSYS_UINT16_GET_MSBFIRST(reinterpret_cast<const uint8_t*>(&v16));
- EXPECT_EQ(expected, ByteSwapToBE16(v16)) << v;
-
- // Check safety against unexpectedly signed bytes.
- expected = FXSYS_UINT16_GET_MSBFIRST(reinterpret_cast<const int8_t*>(&v16));
+ uint16_t expected = GetUInt16MSBFirst(pdfium::byte_span_from_ref(v16));
EXPECT_EQ(expected, ByteSwapToBE16(v16)) << v;
}
}
TEST(ByteOrder, ByteSwapToBE32) {
for (uint32_t v : kTestValues32) {
- uint32_t expected =
- FXSYS_UINT32_GET_MSBFIRST(reinterpret_cast<const uint8_t*>(&v));
- EXPECT_EQ(expected, ByteSwapToBE32(v)) << v;
-
- // Check safety against unexpectedly signed bytes.
- expected = FXSYS_UINT32_GET_MSBFIRST(reinterpret_cast<const int8_t*>(&v));
+ uint32_t expected = GetUInt32MSBFirst(pdfium::byte_span_from_ref(v));
EXPECT_EQ(expected, ByteSwapToBE32(v)) << v;
}
}
+TEST(ByteOrder, GetUInt16LSBFirst) {
+ const uint8_t kBuf[2] = {0xff, 0xfe};
+ EXPECT_EQ(0xfeff, GetUInt16LSBFirst(kBuf));
+}
+
+TEST(ByteOrder, GetUInt16MSBFirst) {
+ const uint8_t kBuf[2] = {0xff, 0xfe};
+ EXPECT_EQ(0xfffe, GetUInt16MSBFirst(kBuf));
+}
+
+TEST(ByteOrder, GetUInt32LSBFirst) {
+ const uint8_t kBuf[4] = {0xff, 0xfe, 0xfd, 0xfc};
+ EXPECT_EQ(0xfcfdfeff, GetUInt32LSBFirst(kBuf));
+}
+
+TEST(ByteOrder, GetUInt32MSBFirst) {
+ const uint8_t kBuf[4] = {0xff, 0xfe, 0xfd, 0xfc};
+ EXPECT_EQ(0xfffefdfc, GetUInt32MSBFirst(kBuf));
+}
+
+TEST(ByteOrder, PutUInt16LSBFirst) {
+ uint8_t buf[2];
+ PutUInt16LSBFirst(0xfffe, buf);
+ EXPECT_THAT(buf, testing::ElementsAre(0xfe, 0xff));
+}
+
+TEST(ByteOrder, PutUInt16MSBFirst) {
+ uint8_t buf[2];
+ PutUInt16MSBFirst(0xfffe, buf);
+ EXPECT_THAT(buf, testing::ElementsAre(0xff, 0xfe));
+}
+
+TEST(ByteOrder, PutUInt32LSBFirst) {
+ uint8_t buf[4];
+ PutUInt32LSBFirst(0xfffefdfc, buf);
+ EXPECT_THAT(buf, testing::ElementsAre(0xfc, 0xfd, 0xfe, 0xff));
+}
+
+TEST(ByteOrder, PutUInt32MSBFirst) {
+ uint8_t buf[4];
+ PutUInt32MSBFirst(0xfffefdfc, buf);
+ EXPECT_THAT(buf, testing::ElementsAre(0xff, 0xfe, 0xfd, 0xfc));
+}
+
} // namespace fxcrt
diff --git a/core/fxcrt/fx_system.h b/core/fxcrt/fx_system.h
index ca910f8..19c3449 100644
--- a/core/fxcrt/fx_system.h
+++ b/core/fxcrt/fx_system.h
@@ -88,28 +88,6 @@
#ifdef __cplusplus
} // extern "C"
-
-// C++-only section
-
-// Could be C, but uses C++-style casting.
-#define FXSYS_UINT16_GET_LSBFIRST(p) \
- (static_cast<uint16_t>( \
- (static_cast<uint32_t>(static_cast<uint8_t>((p)[1])) << 8) | \
- (static_cast<uint32_t>(static_cast<uint8_t>((p)[0])))))
-#define FXSYS_UINT16_GET_MSBFIRST(p) \
- (static_cast<uint16_t>( \
- (static_cast<uint32_t>(static_cast<uint8_t>((p)[0])) << 8) | \
- (static_cast<uint32_t>(static_cast<uint8_t>((p)[1])))))
-#define FXSYS_UINT32_GET_LSBFIRST(p) \
- ((static_cast<uint32_t>(static_cast<uint8_t>((p)[3])) << 24) | \
- (static_cast<uint32_t>(static_cast<uint8_t>((p)[2])) << 16) | \
- (static_cast<uint32_t>(static_cast<uint8_t>((p)[1])) << 8) | \
- (static_cast<uint32_t>(static_cast<uint8_t>((p)[0]))))
-#define FXSYS_UINT32_GET_MSBFIRST(p) \
- ((static_cast<uint32_t>(static_cast<uint8_t>((p)[0])) << 24) | \
- (static_cast<uint32_t>(static_cast<uint8_t>((p)[1])) << 16) | \
- (static_cast<uint32_t>(static_cast<uint8_t>((p)[2])) << 8) | \
- (static_cast<uint32_t>(static_cast<uint8_t>((p)[3]))))
#endif // __cplusplus
#endif // CORE_FXCRT_FX_SYSTEM_H_
diff --git a/core/fxge/cfx_folderfontinfo.cpp b/core/fxge/cfx_folderfontinfo.cpp
index 3a4f41b..324f6e5 100644
--- a/core/fxge/cfx_folderfontinfo.cpp
+++ b/core/fxge/cfx_folderfontinfo.cpp
@@ -11,6 +11,7 @@
#include <utility>
#include "build/build_config.h"
+#include "core/fxcrt/byteorder.h"
#include "core/fxcrt/fx_codepage.h"
#include "core/fxcrt/fx_extension.h"
#include "core/fxcrt/fx_folder.h"
@@ -86,10 +87,11 @@
uint32_t tag,
FX_FILESIZE fileSize) {
for (uint32_t i = 0; i < nTables; i++) {
- const uint8_t* p = pTables + i * 16;
- if (FXSYS_UINT32_GET_MSBFIRST(p) == tag) {
- uint32_t offset = FXSYS_UINT32_GET_MSBFIRST(p + 8);
- uint32_t size = FXSYS_UINT32_GET_MSBFIRST(p + 12);
+ // TODO(tsepez): use actual span.
+ auto p = pdfium::make_span(pTables + i * 16, 16u);
+ if (fxcrt::GetUInt32MSBFirst(p) == tag) {
+ uint32_t offset = fxcrt::GetUInt32MSBFirst(p.subspan(8));
+ uint32_t size = fxcrt::GetUInt32MSBFirst(p.subspan(12));
if (offset > std::numeric_limits<uint32_t>::max() - size ||
static_cast<FX_FILESIZE>(offset + size) > fileSize ||
fseek(pFile, offset, SEEK_SET) < 0) {
@@ -206,12 +208,13 @@
if (readCnt != 1)
return;
- if (FXSYS_UINT32_GET_MSBFIRST(buffer) != kTableTTCF) {
+ if (fxcrt::GetUInt32MSBFirst(buffer) != kTableTTCF) {
ReportFace(path, pFile.get(), filesize, 0);
return;
}
- uint32_t nFaces = FXSYS_UINT32_GET_MSBFIRST(buffer + 8);
+ uint32_t nFaces =
+ fxcrt::GetUInt32MSBFirst(pdfium::make_span(buffer).subspan(8));
FX_SAFE_SIZE_T safe_face_bytes = nFaces;
safe_face_bytes *= 4;
if (!safe_face_bytes.IsValid())
@@ -227,7 +230,7 @@
auto offsets_span = pdfium::make_span(offsets.get(), face_bytes);
for (uint32_t i = 0; i < nFaces; i++) {
ReportFace(path, pFile.get(), filesize,
- FXSYS_UINT32_GET_MSBFIRST(&offsets_span[i * 4]));
+ fxcrt::GetUInt32MSBFirst(offsets_span.subspan(i * 4)));
}
}
@@ -239,7 +242,8 @@
if (fseek(pFile, offset, SEEK_SET) < 0 || !fread(buffer, 12, 1, pFile))
return;
- uint32_t nTables = FXSYS_UINT16_GET_MSBFIRST(buffer + 4);
+ uint32_t nTables =
+ fxcrt::GetUInt16MSBFirst(pdfium::as_byte_span(buffer).subspan(4));
ByteString tables = ReadStringFromFile(pFile, nTables * 16);
if (tables.IsEmpty())
return;
@@ -269,8 +273,8 @@
ByteString os2 =
LoadTableFromTT(pFile, tables.raw_str(), nTables, kOs2Tag, filesize);
if (os2.GetLength() >= 86) {
- const uint8_t* p = os2.raw_str() + 78;
- uint32_t codepages = FXSYS_UINT32_GET_MSBFIRST(p);
+ pdfium::span<const uint8_t> p = os2.raw_span().subspan(78);
+ uint32_t codepages = fxcrt::GetUInt32MSBFirst(p);
if (codepages & (1U << 17)) {
m_pMapper->AddInstalledFont(facename, FX_Charset::kShiftJIS);
pInfo->m_Charsets |= CHARSET_FLAG_SHIFTJIS;
@@ -384,10 +388,12 @@
} else {
size_t nTables = pFont->m_FontTables.GetLength() / 16;
for (size_t i = 0; i < nTables; i++) {
- const uint8_t* p = pFont->m_FontTables.raw_str() + i * 16;
- if (FXSYS_UINT32_GET_MSBFIRST(p) == table) {
- offset = FXSYS_UINT32_GET_MSBFIRST(p + 8);
- datasize = FXSYS_UINT32_GET_MSBFIRST(p + 12);
+ // TODO(tsepez): iterate over span.
+ pdfium::span<const uint8_t> p =
+ pFont->m_FontTables.raw_span().subspan(i * 16);
+ if (fxcrt::GetUInt32MSBFirst(p) == table) {
+ offset = fxcrt::GetUInt32MSBFirst(p.subspan(8));
+ datasize = fxcrt::GetUInt32MSBFirst(p.subspan(12));
}
}
}
diff --git a/core/fxge/fx_font.cpp b/core/fxge/fx_font.cpp
index c5d7076..52010d0 100644
--- a/core/fxge/fx_font.cpp
+++ b/core/fxge/fx_font.cpp
@@ -8,8 +8,8 @@
#include <algorithm>
+#include "core/fxcrt/byteorder.h"
#include "core/fxcrt/fx_safe_types.h"
-#include "core/fxcrt/fx_system.h"
#include "core/fxcrt/widestring.h"
#include "core/fxge/cfx_glyphbitmap.h"
#include "core/fxge/dib/cfx_dibitmap.h"
@@ -84,8 +84,8 @@
if (name_table.size() < 6)
return ByteString();
- uint32_t name_count = FXSYS_UINT16_GET_MSBFIRST(&name_table[2]);
- uint32_t string_offset = FXSYS_UINT16_GET_MSBFIRST(&name_table[4]);
+ uint32_t name_count = fxcrt::GetUInt16MSBFirst(name_table.subspan(2));
+ uint32_t string_offset = fxcrt::GetUInt16MSBFirst(name_table.subspan(4));
// We will ignore the possibility of overlap of structures and
// string table as if it's all corrupt there's not a lot we can do.
if (name_table.size() < string_offset)
@@ -98,24 +98,23 @@
for (uint32_t i = 0; i < name_count;
i++, name_table = name_table.subspan(12)) {
- if (FXSYS_UINT16_GET_MSBFIRST(&name_table[6]) == name_id) {
- const uint16_t platform_identifier =
- FXSYS_UINT16_GET_MSBFIRST(name_table);
+ if (fxcrt::GetUInt16MSBFirst(name_table.subspan(6)) == name_id) {
+ const uint16_t platform_identifier = fxcrt::GetUInt16MSBFirst(name_table);
const uint16_t platform_encoding =
- FXSYS_UINT16_GET_MSBFIRST(&name_table[2]);
+ fxcrt::GetUInt16MSBFirst(name_table.subspan(2));
if (platform_identifier == kNamePlatformMac &&
platform_encoding == kNameMacEncodingRoman) {
- return GetStringFromTable(string_span,
- FXSYS_UINT16_GET_MSBFIRST(&name_table[10]),
- FXSYS_UINT16_GET_MSBFIRST(&name_table[8]));
+ return GetStringFromTable(
+ string_span, fxcrt::GetUInt16MSBFirst(name_table.subspan(10)),
+ fxcrt::GetUInt16MSBFirst(name_table.subspan(8)));
}
if (platform_identifier == kNamePlatformWindows &&
platform_encoding == kNameWindowsEncodingUnicode) {
// This name is always UTF16-BE and we have to convert it to UTF8.
ByteString utf16_be = GetStringFromTable(
- string_span, FXSYS_UINT16_GET_MSBFIRST(&name_table[10]),
- FXSYS_UINT16_GET_MSBFIRST(&name_table[8]));
+ string_span, fxcrt::GetUInt16MSBFirst(name_table.subspan(10)),
+ fxcrt::GetUInt16MSBFirst(name_table.subspan(8)));
if (utf16_be.IsEmpty() || utf16_be.GetLength() % 2 != 0) {
return ByteString();
}
@@ -129,11 +128,12 @@
size_t GetTTCIndex(pdfium::span<const uint8_t> pFontData, size_t font_offset) {
pdfium::span<const uint8_t> p = pFontData.subspan(8);
- size_t nfont = FXSYS_UINT32_GET_MSBFIRST(p.data());
+ size_t nfont = fxcrt::GetUInt32MSBFirst(p);
for (size_t index = 0; index < nfont; index++) {
p = pFontData.subspan(12 + index * 4);
- if (FXSYS_UINT32_GET_MSBFIRST(p.data()) == font_offset)
+ if (fxcrt::GetUInt32MSBFirst(p) == font_offset) {
return index;
+ }
}
return 0;
}
diff --git a/core/fxge/win32/cwin32_platform.cpp b/core/fxge/win32/cwin32_platform.cpp
index 50aae40..885cac4 100644
--- a/core/fxge/win32/cwin32_platform.cpp
+++ b/core/fxge/win32/cwin32_platform.cpp
@@ -10,7 +10,9 @@
#include <memory>
#include <utility>
+#include "core/fxcrt/byteorder.h"
#include "core/fxcrt/fx_codepage.h"
+#include "core/fxcrt/fx_system.h"
#include "core/fxge/cfx_folderfontinfo.h"
#include "core/fxge/cfx_gemodule.h"
#include "third_party/base/check.h"
@@ -161,7 +163,7 @@
uint32_t header;
auto span = pdfium::as_writable_bytes(pdfium::span_from_ref(header));
GetFontData(hFont, 0, span);
- header = FXSYS_UINT32_GET_MSBFIRST(span);
+ header = fxcrt::GetUInt32MSBFirst(span);
ret = header == FXBSTR_ID('O', 'T', 'T', 'O') ||
header == FXBSTR_ID('t', 't', 'c', 'f') ||
header == FXBSTR_ID('t', 'r', 'u', 'e') || header == 0x00010000 ||
@@ -419,7 +421,7 @@
uint32_t table,
pdfium::span<uint8_t> buffer) {
ScopedSelectObject select_object(m_hDC, static_cast<HFONT>(hFont));
- table = FXSYS_UINT32_GET_MSBFIRST(reinterpret_cast<uint8_t*>(&table));
+ table = fxcrt::FromBE32(table);
size_t size = ::GetFontData(m_hDC, table, 0, buffer.data(),
pdfium::base::checked_cast<DWORD>(buffer.size()));
return size != GDI_ERROR ? size : 0;
diff --git a/xfa/fgas/font/cfgas_fontmgr.cpp b/xfa/fgas/font/cfgas_fontmgr.cpp
index c1f516d..cdf8d0d 100644
--- a/xfa/fgas/font/cfgas_fontmgr.cpp
+++ b/xfa/fgas/font/cfgas_fontmgr.cpp
@@ -14,6 +14,7 @@
#include <utility>
#include "build/build_config.h"
+#include "core/fxcrt/byteorder.h"
#include "core/fxcrt/cfx_read_only_vector_stream.h"
#include "core/fxcrt/data_vector.h"
#include "core/fxcrt/fixed_size_data_vector.h"
@@ -370,8 +371,7 @@
uint16_t ReadUInt16FromSpanAtOffset(pdfium::span<const uint8_t> data,
size_t offset) {
- const uint8_t* p = &data[offset];
- return FXSYS_UINT16_GET_MSBFIRST(p);
+ return fxcrt::GetUInt16MSBFirst(data.subspan(offset));
}
extern "C" {