Avoid a few UNSAFE_TODO()s in CPDF_CIDFont.
Create structs of ints rather than referencing ints within an array
at magic offsets.
Bug: 42271776
Change-Id: I89147b764e25e963d20a554ec9ff7f6f3b1cfc29
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/120290
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Thomas Sepez <tsepez@google.com>
diff --git a/core/fpdfapi/font/cpdf_cidfont.cpp b/core/fpdfapi/font/cpdf_cidfont.cpp
index 8e11285..f90d972 100644
--- a/core/fpdfapi/font/cpdf_cidfont.cpp
+++ b/core/fpdfapi/font/cpdf_cidfont.cpp
@@ -31,11 +31,26 @@
#include "core/fxcrt/fx_safe_types.h"
#include "core/fxcrt/fx_unicode.h"
#include "core/fxcrt/span.h"
+#include "core/fxcrt/span_util.h"
#include "core/fxcrt/stl_util.h"
#include "core/fxge/fx_font.h"
namespace {
+struct LowHighVal {
+ int low;
+ int high;
+ int val;
+};
+
+struct LowHighValXY {
+ int low;
+ int high;
+ int val;
+ int x;
+ int y;
+};
+
constexpr FX_CodePage kCharsetCodePages[CIDSET_NUM_SETS] = {
FX_CodePage::kDefANSI,
FX_CodePage::kChineseSimplified,
@@ -201,10 +216,6 @@
}
}
-bool IsMetricForCID(const int* pEntry, uint16_t cid) {
- return UNSAFE_TODO(pEntry[0] <= cid && pEntry[1] >= cid);
-}
-
void LoadMetricsArray(RetainPtr<const CPDF_Array> pArray,
std::vector<int>* result,
int nElements) {
@@ -531,65 +542,48 @@
}
int CPDF_CIDFont::GetCharWidthF(uint32_t charcode) {
- if (charcode < 0x80 && m_bAnsiWidthsFixed)
+ if (charcode < 0x80 && m_bAnsiWidthsFixed) {
return (charcode >= 32 && charcode < 127) ? 500 : 0;
-
+ }
uint16_t cid = CIDFromCharCode(charcode);
- size_t size = m_WidthList.size();
- const int* pList = m_WidthList.data();
- UNSAFE_TODO({
- for (size_t i = 0; i < size; i += 3) {
- const int* pEntry = pList + i;
- if (IsMetricForCID(pEntry, cid)) {
- return pEntry[2];
- }
+ auto lhv_span = fxcrt::truncating_reinterpret_span<const LowHighVal>(
+ pdfium::make_span(m_WidthList));
+ for (const auto& lhv : lhv_span) {
+ if (lhv.low <= cid && cid <= lhv.high) {
+ return lhv.val;
}
- });
+ }
return m_DefaultWidth;
}
int16_t CPDF_CIDFont::GetVertWidth(uint16_t cid) const {
- size_t vertsize = m_VertMetrics.size() / 5;
- if (vertsize) {
- const int* pTable = m_VertMetrics.data();
- UNSAFE_TODO({
- for (size_t i = 0; i < vertsize; i++) {
- const int* pEntry = pTable + (i * 5);
- if (IsMetricForCID(pEntry, cid)) {
- return static_cast<int16_t>(pEntry[2]);
- }
- }
- });
+ auto lhvxy_span = fxcrt::truncating_reinterpret_span<const LowHighValXY>(
+ pdfium::make_span(m_VertMetrics));
+ for (const auto& lhvxy : lhvxy_span) {
+ if (lhvxy.low <= cid && cid <= lhvxy.high) {
+ return lhvxy.val;
+ }
}
return m_DefaultW1;
}
CFX_Point16 CPDF_CIDFont::GetVertOrigin(uint16_t cid) const {
- size_t vertsize = m_VertMetrics.size() / 5;
- if (vertsize) {
- const int* pTable = m_VertMetrics.data();
- UNSAFE_TODO({
- for (size_t i = 0; i < vertsize; i++) {
- const int* pEntry = pTable + (i * 5);
- if (IsMetricForCID(pEntry, cid)) {
- return {static_cast<int16_t>(pEntry[3]),
- static_cast<int16_t>(pEntry[4])};
- }
- }
- });
+ auto lhvxy_span = fxcrt::truncating_reinterpret_span<const LowHighValXY>(
+ pdfium::make_span(m_VertMetrics));
+ for (const auto& lhvxy : lhvxy_span) {
+ if (lhvxy.low <= cid & cid <= lhvxy.high) {
+ return {static_cast<int16_t>(lhvxy.x), static_cast<int16_t>(lhvxy.y)};
+ }
}
int width = m_DefaultWidth;
- size_t size = m_WidthList.size();
- const int* pList = m_WidthList.data();
- UNSAFE_TODO({
- for (size_t i = 0; i < size; i += 3) {
- const int* pEntry = pList + i;
- if (IsMetricForCID(pEntry, cid)) {
- width = pEntry[2];
- break;
- }
+ auto lhv_span = fxcrt::truncating_reinterpret_span<const LowHighVal>(
+ pdfium::make_span(m_WidthList));
+ for (const auto& lhv : lhv_span) {
+ if (lhv.low <= cid && cid <= lhv.high) {
+ width = lhv.val;
+ break;
}
- });
+ }
return {static_cast<int16_t>(width / 2), m_DefaultVY};
}