Improve CPDF_CMapParser::HandleCid() performance
Send the entire range of codes to write to CPDF_CMap in one go. Then
CPDF_CMap can create a single span and write all the values, instead of
creating one span per value. While spans are not expensive to create,
creating 64K spans in a loop does add up. This makes pdf_cmap_fuzzer run
3X as fast for the problematic input.
Bug: chromium:1478569
Change-Id: I3322de8aeaff23c5e562d4acc55ade57c0cc03ad
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/111730
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
diff --git a/core/fpdfapi/font/cpdf_cmap.cpp b/core/fpdfapi/font/cpdf_cmap.cpp
index d5fa61b..a38eab4 100644
--- a/core/fpdfapi/font/cpdf_cmap.cpp
+++ b/core/fpdfapi/font/cpdf_cmap.cpp
@@ -515,3 +515,12 @@
void CPDF_CMap::SetMixedFourByteLeadingRanges(std::vector<CodeRange> ranges) {
m_MixedFourByteLeadingRanges = std::move(ranges);
}
+
+void CPDF_CMap::SetDirectCharcodeToCIDTableRange(uint32_t start_code,
+ uint32_t end_code,
+ uint16_t start_cid) {
+ pdfium::span<uint16_t> span = m_DirectCharcodeToCIDTable.writable_span();
+ for (uint32_t code = start_code; code <= end_code; ++code) {
+ span[code] = static_cast<uint16_t>(start_cid + code - start_code);
+ }
+}
diff --git a/core/fpdfapi/font/cpdf_cmap.h b/core/fpdfapi/font/cpdf_cmap.h
index 416010a..5469979 100644
--- a/core/fpdfapi/font/cpdf_cmap.h
+++ b/core/fpdfapi/font/cpdf_cmap.h
@@ -77,9 +77,9 @@
CIDSet GetCharset() const { return m_Charset; }
void SetCharset(CIDSet set) { m_Charset = set; }
- void SetDirectCharcodeToCIDTable(size_t idx, uint16_t val) {
- m_DirectCharcodeToCIDTable.writable_span()[idx] = val;
- }
+ void SetDirectCharcodeToCIDTableRange(uint32_t start_code,
+ uint32_t end_code,
+ uint16_t start_cid);
bool IsDirectCharcodeToCIDTableIsEmpty() const {
return m_DirectCharcodeToCIDTable.empty();
}
diff --git a/core/fpdfapi/font/cpdf_cmapparser.cpp b/core/fpdfapi/font/cpdf_cmapparser.cpp
index 87a5907..465b6fc 100644
--- a/core/fpdfapi/font/cpdf_cmapparser.cpp
+++ b/core/fpdfapi/font/cpdf_cmapparser.cpp
@@ -100,10 +100,7 @@
StartCID = static_cast<uint16_t>(m_CodePoints[2]);
}
if (EndCode < CPDF_CMap::kDirectMapTableSize) {
- for (uint32_t code = StartCode; code <= EndCode; code++) {
- m_pCMap->SetDirectCharcodeToCIDTable(
- code, static_cast<uint16_t>(StartCID + code - StartCode));
- }
+ m_pCMap->SetDirectCharcodeToCIDTableRange(StartCode, EndCode, StartCID);
} else {
m_AdditionalCharcodeToCIDMappings.push_back({StartCode, EndCode, StartCID});
}