Use CIDToGIDMap to fill font widths in FPDFText_LoadCidType2Font() FPDFText_LoadCidType2Font() generates a font dictionary that contains various font characteristics. Use the caller-provided CIDToGIDMap to fill the font widths array, instead of traversing the font's character codes. This way, the widths array is only populated for the relevant CIDs. Bug: 376781381 Change-Id: Iae39b26bb18a8aa64f404570a8e557ef811a37ec Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/127950 Reviewed-by: Tom Sepez <tsepez@chromium.org> Reviewed-by: Thomas Sepez <tsepez@google.com> Commit-Queue: Lei Zhang <thestig@chromium.org>
diff --git a/fpdfsdk/fpdf_edit_embeddertest.cpp b/fpdfsdk/fpdf_edit_embeddertest.cpp index cf5cb1b..fdec13a 100644 --- a/fpdfsdk/fpdf_edit_embeddertest.cpp +++ b/fpdfsdk/fpdf_edit_embeddertest.cpp
@@ -3802,7 +3802,7 @@ RetainPtr<const CPDF_Array> widths_array = GetWidthsArrayForCidFont(typed_font); ASSERT_TRUE(widths_array); - CheckCompositeFontWidths(widths_array, typed_font, testing::Eq(9)); + CheckCompositeFontWidths(widths_array, typed_font, testing::Eq(10)); FPDF_PAGEOBJECT text_object = FPDFPageObj_CreateTextObj(document(), font.get(), 20.0f); @@ -3869,9 +3869,7 @@ RetainPtr<const CPDF_Array> widths_array = GetWidthsArrayForCidFont(typed_font); ASSERT_TRUE(widths_array); - // TODO(crbug.com/376781381): Reduce `widths_array` size, given the smaller - // `kCidToGidMap`. - CheckCompositeFontWidths(widths_array, typed_font, testing::Eq(9)); + CheckCompositeFontWidths(widths_array, typed_font, testing::Eq(5)); } TEST_F(FPDFEditEmbedderTest, LoadCidType2FontWithBadParameters) {
diff --git a/fpdfsdk/fpdf_edittext.cpp b/fpdfsdk/fpdf_edittext.cpp index 63ed5c2..17c81dd 100644 --- a/fpdfsdk/fpdf_edittext.cpp +++ b/fpdfsdk/fpdf_edittext.cpp
@@ -3,6 +3,7 @@ // found in the LICENSE file. #include <algorithm> +#include <limits> #include <map> #include <memory> #include <sstream> @@ -28,6 +29,7 @@ #include "core/fpdfapi/render/cpdf_renderstatus.h" #include "core/fpdfapi/render/cpdf_textrenderer.h" #include "core/fpdftext/cpdf_textpage.h" +#include "core/fxcrt/byteorder.h" #include "core/fxcrt/check.h" #include "core/fxcrt/check_op.h" #include "core/fxcrt/compiler_specific.h" @@ -537,18 +539,14 @@ pdfium::span<const uint8_t> font_span, const char* to_unicode_cmap, pdfium::span<const uint8_t> cid_to_gid_map_span) { + CHECK_LE(cid_to_gid_map_span.size(), std::numeric_limits<uint32_t>::max()); + // If it doesn't have a single char, just fail. RetainPtr<CFX_Face> face = font->GetFace(); if (face->GetGlyphCount() <= 0) { return nullptr; } - auto char_codes_and_indices = - face->GetCharCodesAndIndices(pdfium::kMaximumSupplementaryCodePoint); - if (char_codes_and_indices.empty()) { - return nullptr; - } - const ByteString name = BaseFontNameForType(font.get(), FPDF_FONT_TRUETYPE); RetainPtr<CPDF_Dictionary> font_dict = CreateCompositeFontDict(doc, font.get(), FPDF_FONT_TRUETYPE, name); @@ -562,11 +560,13 @@ font_descriptor->GetObjNum()); std::map<uint32_t, uint32_t> widths; - for (const auto& item : char_codes_and_indices) { - if (!pdfium::Contains(widths, item.glyph_index)) { - widths[item.glyph_index] = font->GetGlyphWidth(item.glyph_index); - } + for (size_t i = 0; i < cid_to_gid_map_span.size(); i += 2) { + uint16_t glyph_index = + fxcrt::GetUInt16MSBFirst(cid_to_gid_map_span.subspan(i, 2)); + // Safe to cast since `cid_to_gid_map_span` has a size limit. + widths[static_cast<uint32_t>(i) / 2] = font->GetGlyphWidth(glyph_index); } + RetainPtr<CPDF_Array> widths_array = CreateWidthsArray(doc, widths); cid_font_dict->SetNewFor<CPDF_Reference>("W", doc, widths_array->GetObjNum());