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}); }