From 81ec24c0fe046dcb7006ce69682c731a09205231 Mon Sep 17 00:00:00 2001 From: Lei Zhang Date: Wed, 13 Jan 2016 17:15:59 -0800 Subject: Merge to XFA: Do not use invalidated std::map::iterators in PDF_ReplaceAbbr(). Avoid invalidating iterators by deferring the std::map operations. Also remove unused PDF_ReplaceFull(). BUG=577030 TBR=ochang@chromium.org Review URL: https://codereview.chromium.org/1581963004 . (cherry picked from commit 5d1070dc642800242ec2e9d9d74aa1e5715d2b62) Review URL: https://codereview.chromium.org/1585853002 . --- core/src/fpdfapi/fpdf_page/fpdf_page_parser.cpp | 83 +++++++------------------ 1 file changed, 23 insertions(+), 60 deletions(-) (limited to 'core/src/fpdfapi') diff --git a/core/src/fpdfapi/fpdf_page/fpdf_page_parser.cpp b/core/src/fpdfapi/fpdf_page/fpdf_page_parser.cpp index d3e3807046..4ac9de9e95 100644 --- a/core/src/fpdfapi/fpdf_page/fpdf_page_parser.cpp +++ b/core/src/fpdfapi/fpdf_page/fpdf_page_parser.cpp @@ -50,6 +50,12 @@ const PDF_AbbrPairs PDF_InlineValueAbbr[] = { {_FX_BSTRC("DCTDecode"), _FX_BSTRC("DCT")}, }; +struct AbbrReplacementOp { + bool is_replace_key; + CFX_ByteString key; + CFX_ByteStringC replacement; +}; + CFX_ByteStringC PDF_FindFullName(const PDF_AbbrPairs* table, size_t count, const CFX_ByteStringC& abbr) { @@ -63,19 +69,6 @@ CFX_ByteStringC PDF_FindFullName(const PDF_AbbrPairs* table, return CFX_ByteStringC(); } -CFX_ByteStringC PDF_FindAbbrName(const PDF_AbbrPairs* table, - size_t count, - const CFX_ByteStringC& name) { - for (size_t i = 0; i < count; ++i) { - if (name.GetLength() != table[i].full_name.m_Size) - continue; - if (memcmp(name.GetPtr(), table[i].full_name.m_Ptr, name.GetLength())) - continue; - return CFX_ByteStringC(table[i].abbr.m_Ptr, table[i].abbr.m_Size); - } - return CFX_ByteStringC(); -} - } // namespace CPDF_StreamContentParser::CPDF_StreamContentParser( @@ -496,13 +489,18 @@ void PDF_ReplaceAbbr(CPDF_Object* pObj) { switch (pObj->GetType()) { case PDFOBJ_DICTIONARY: { CPDF_Dictionary* pDict = pObj->AsDictionary(); + std::vector replacements; for (const auto& it : *pDict) { CFX_ByteString key = it.first; CPDF_Object* value = it.second; CFX_ByteStringC fullname = PDF_FindFullName( PDF_InlineKeyAbbr, FX_ArraySize(PDF_InlineKeyAbbr), key); if (!fullname.IsEmpty()) { - pDict->ReplaceKey(key, fullname); + AbbrReplacementOp op; + op.is_replace_key = true; + op.key = key; + op.replacement = fullname; + replacements.push_back(op); key = fullname; } @@ -511,12 +509,22 @@ void PDF_ReplaceAbbr(CPDF_Object* pObj) { fullname = PDF_FindFullName(PDF_InlineValueAbbr, FX_ArraySize(PDF_InlineValueAbbr), name); if (!fullname.IsEmpty()) { - pDict->SetAtName(key, fullname); + AbbrReplacementOp op; + op.is_replace_key = false; + op.key = key; + op.replacement = fullname; + replacements.push_back(op); } } else { PDF_ReplaceAbbr(value); } } + for (const auto& op : replacements) { + if (op.is_replace_key) + pDict->ReplaceKey(op.key, op.replacement); + else + pDict->SetAtName(op.key, op.replacement); + } break; } case PDFOBJ_ARRAY: { @@ -539,51 +547,6 @@ void PDF_ReplaceAbbr(CPDF_Object* pObj) { } } -void PDF_ReplaceFull(CPDF_Object* pObj) { - switch (pObj->GetType()) { - case PDFOBJ_DICTIONARY: { - CPDF_Dictionary* pDict = pObj->AsDictionary(); - for (const auto& it : *pDict) { - CFX_ByteString key = it.first; - CPDF_Object* value = it.second; - CFX_ByteStringC abbrName = PDF_FindAbbrName( - PDF_InlineKeyAbbr, FX_ArraySize(PDF_InlineKeyAbbr), key); - if (!abbrName.IsEmpty()) { - pDict->ReplaceKey(key, abbrName); - key = abbrName; - } - if (value->IsName()) { - CFX_ByteString name = value->GetString(); - abbrName = PDF_FindAbbrName(PDF_InlineValueAbbr, - FX_ArraySize(PDF_InlineValueAbbr), name); - if (!abbrName.IsEmpty()) { - pDict->SetAtName(key, abbrName); - } - } else { - PDF_ReplaceFull(value); - } - } - break; - } - case PDFOBJ_ARRAY: { - CPDF_Array* pArray = pObj->AsArray(); - for (FX_DWORD i = 0; i < pArray->GetCount(); i++) { - CPDF_Object* pElement = pArray->GetElement(i); - if (pElement->IsName()) { - CFX_ByteString name = pElement->GetString(); - CFX_ByteStringC abbrName = PDF_FindAbbrName( - PDF_InlineValueAbbr, FX_ArraySize(PDF_InlineValueAbbr), name); - if (!abbrName.IsEmpty()) { - pArray->SetAt(i, new CPDF_Name(abbrName)); - } - } else { - PDF_ReplaceFull(pElement); - } - } - break; - } - } -} void CPDF_StreamContentParser::Handle_BeginText() { m_pCurStates->m_TextMatrix.Set(1.0f, 0, 0, 1.0f, 0, 0); OnChangeTextMatrix(); -- cgit v1.2.3