Consolidate UNSAFE_BUFFERS usage in fpdf_cmaps.cpp
Add helper functions to create spans for the CMaps data, to consolidate
all the UNSAFE_BUFFERS usage in this file.
Change-Id: I01f7a183940a02adb8c30fb9d14bf8864140bdcb
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/134572
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
diff --git a/core/fpdfapi/cmaps/fpdf_cmaps.cpp b/core/fpdfapi/cmaps/fpdf_cmaps.cpp
index 7ba8435..35dc01d 100644
--- a/core/fpdfapi/cmaps/fpdf_cmaps.cpp
+++ b/core/fpdfapi/cmaps/fpdf_cmaps.cpp
@@ -26,6 +26,23 @@
uint16_t cid;
};
+pdfium::span<const SingleCmap> GetSingleCmapSpan(const CMap* cmap) {
+ // SAFETY: `CMap` uses manually audited constexpr data.
+ return UNSAFE_BUFFERS(pdfium::span(
+ reinterpret_cast<const SingleCmap*>(cmap->word_map_), cmap->word_count_));
+}
+
+pdfium::span<const RangeCmap> GetRangeCmapSpan(const CMap* cmap) {
+ // SAFETY: `CMap` uses manually audited constexpr data.
+ return UNSAFE_BUFFERS(pdfium::span(
+ reinterpret_cast<const RangeCmap*>(cmap->word_map_), cmap->word_count_));
+}
+
+pdfium::span<const DWordCIDMap> GetDWordCIDMapCmapSpan(const CMap* cmap) {
+ // SAFETY: `CMap` uses manually audited constexpr data.
+ return UNSAFE_BUFFERS(pdfium::span(cmap->dword_map_, cmap->dword_count_));
+}
+
const CMap* FindNextCMap(const CMap* cmap) {
if (cmap->use_offset_ == 0) {
return nullptr;
@@ -39,11 +56,9 @@
const uint16_t loword = static_cast<uint16_t>(charcode);
while (cmap) {
if (cmap->dword_map_) {
- const DWordCIDMap* begin = cmap->dword_map_;
- // SAFETY: `CMap` uses manually audited constexpr data.
- const auto* end = UNSAFE_BUFFERS(begin + cmap->dword_count_);
+ auto dword_span = GetDWordCIDMapCmapSpan(cmap);
const auto* found = std::lower_bound(
- begin, end, charcode,
+ dword_span.begin(), dword_span.end(), charcode,
[](const DWordCIDMap& element, uint32_t charcode) {
uint16_t hiword = static_cast<uint16_t>(charcode >> 16);
if (element.hi_word_ != hiword) {
@@ -51,7 +66,7 @@
}
return element.lo_word_high_ < static_cast<uint16_t>(charcode);
});
- if (found != end && loword >= found->lo_word_low_ &&
+ if (found != dword_span.end() && loword >= found->lo_word_low_ &&
loword <= found->lo_word_high_) {
return found->cid_ + loword - found->lo_word_low_;
}
@@ -74,28 +89,26 @@
CHECK(cmap->word_map_);
switch (cmap->word_map_type_) {
case CMap::Type::kSingle: {
- const auto* begin =
- reinterpret_cast<const SingleCmap*>(cmap->word_map_);
- // SAFETY: `CMap` uses manually audited constexpr data.
- const auto* end = UNSAFE_BUFFERS(begin + cmap->word_count_);
- const auto* found = std::lower_bound(
- begin, end, loword, [](const SingleCmap& element, uint16_t code) {
- return element.code < code;
- });
- if (found != end && found->code == loword) {
+ auto single_span = GetSingleCmapSpan(cmap);
+ const auto* found =
+ std::lower_bound(single_span.begin(), single_span.end(), loword,
+ [](const SingleCmap& element, uint16_t code) {
+ return element.code < code;
+ });
+ if (found != single_span.end() && found->code == loword) {
return found->cid;
}
break;
}
case CMap::Type::kRange: {
- const auto* begin = reinterpret_cast<const RangeCmap*>(cmap->word_map_);
- // SAFETY: `CMap` uses manually audited constexpr data.
- const auto* end = UNSAFE_BUFFERS(begin + cmap->word_count_);
- const auto* found = std::lower_bound(
- begin, end, loword, [](const RangeCmap& element, uint16_t code) {
- return element.high < code;
- });
- if (found != end && loword >= found->low && loword <= found->high) {
+ auto range_span = GetRangeCmapSpan(cmap);
+ const auto* found =
+ std::lower_bound(range_span.begin(), range_span.end(), loword,
+ [](const RangeCmap& element, uint16_t code) {
+ return element.high < code;
+ });
+ if (found != range_span.end() && loword >= found->low &&
+ loword <= found->high) {
return found->cid + loword - found->low;
}
break;
@@ -118,11 +131,7 @@
while (cmap) {
switch (cmap->word_map_type_) {
case CMap::Type::kSingle: {
- // SAFETY: `CMap` uses manually audited constexpr data.
- auto single_span = UNSAFE_BUFFERS(
- pdfium::span(reinterpret_cast<const SingleCmap*>(cmap->word_map_),
- cmap->word_count_));
- for (const auto& single : single_span) {
+ for (const auto& single : GetSingleCmapSpan(cmap)) {
if (single.cid == cid) {
return single.code;
}
@@ -130,11 +139,7 @@
break;
}
case CMap::Type::kRange: {
- // SAFETY: `CMap` uses manually audited constexpr data.
- auto range_span = UNSAFE_BUFFERS(
- pdfium::span(reinterpret_cast<const RangeCmap*>(cmap->word_map_),
- cmap->word_count_));
- for (const auto& range : range_span) {
+ for (const auto& range : GetRangeCmapSpan(cmap)) {
if (cid >= range.cid && cid <= range.cid + range.high - range.low) {
return range.low + cid - range.cid;
}