From 698c5716d005860360527e4cfe15b4a185589117 Mon Sep 17 00:00:00 2001 From: tsepez Date: Wed, 28 Sep 2016 16:47:07 -0700 Subject: Use string pools in some dictionaries, names, and strings. BUG=pdfium:597 Review-Url: https://codereview.chromium.org/2345063002 --- .../fpdf_edit/cpdf_pagecontentgenerator.cpp | 8 ++-- core/fpdfapi/fpdf_font/cpdf_font.cpp | 2 +- core/fpdfapi/fpdf_font/cpdf_fontencoding.cpp | 10 ++--- core/fpdfapi/fpdf_font/include/cpdf_fontencoding.h | 4 +- core/fpdfapi/fpdf_page/cpdf_image.cpp | 17 +++++--- core/fpdfapi/fpdf_page/fpdf_page_doc.cpp | 5 ++- core/fpdfapi/fpdf_page/fpdf_page_parser.cpp | 12 +++--- core/fpdfapi/fpdf_page/fpdf_page_parser_old.cpp | 35 +++++++++++----- core/fpdfapi/fpdf_page/pageint.h | 16 ++++---- core/fpdfapi/fpdf_parser/cfdf_document.cpp | 9 +++-- core/fpdfapi/fpdf_parser/cpdf_dictionary.cpp | 17 +++++--- core/fpdfapi/fpdf_parser/cpdf_document.cpp | 34 +++++++++------- core/fpdfapi/fpdf_parser/cpdf_object_unittest.cpp | 22 +++++----- core/fpdfapi/fpdf_parser/cpdf_stream.cpp | 2 +- core/fpdfapi/fpdf_parser/cpdf_syntax_parser.cpp | 32 +++++++++------ core/fpdfapi/fpdf_parser/cpdf_syntax_parser.h | 7 +++- core/fpdfapi/fpdf_parser/include/cfdf_document.h | 6 +++ core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h | 8 +++- core/fpdfapi/fpdf_parser/include/cpdf_document.h | 6 +++ core/fpdfdoc/cpdf_annotlist.cpp | 3 +- core/fpdfdoc/cpdf_filespec.cpp | 4 +- core/fpdfdoc/cpdf_filespec_unittest.cpp | 4 +- core/fpdfdoc/cpdf_formfield_unittest.cpp | 12 ++++-- core/fpdfdoc/cpdf_interform.cpp | 11 ++--- core/fpdfdoc/cpvt_generateap.cpp | 47 ++++++++++++---------- core/fpdfdoc/include/cpdf_annot.h | 3 ++ core/fpdfdoc/include/cpdf_filespec.h | 4 +- core/fxge/dib/fx_dib_engine_unittest.cpp | 2 +- core/fxge/include/cfx_renderdevice.h | 20 ++++----- 29 files changed, 225 insertions(+), 137 deletions(-) (limited to 'core') diff --git a/core/fpdfapi/fpdf_edit/cpdf_pagecontentgenerator.cpp b/core/fpdfapi/fpdf_edit/cpdf_pagecontentgenerator.cpp index 29c5940f5e..45d40170d6 100644 --- a/core/fpdfapi/fpdf_edit/cpdf_pagecontentgenerator.cpp +++ b/core/fpdfapi/fpdf_edit/cpdf_pagecontentgenerator.cpp @@ -63,14 +63,15 @@ CFX_ByteString CPDF_PageContentGenerator::RealizeResource( CPDF_Object* pResourceObj, const CFX_ByteString& bsType) { if (!m_pPage->m_pResources) { - m_pPage->m_pResources = new CPDF_Dictionary; + m_pPage->m_pResources = + new CPDF_Dictionary(m_pDocument->GetByteStringPool()); m_pPage->m_pFormDict->SetReferenceFor( "Resources", m_pDocument, m_pDocument->AddIndirectObject(m_pPage->m_pResources)); } CPDF_Dictionary* pResList = m_pPage->m_pResources->GetDictFor(bsType); if (!pResList) { - pResList = new CPDF_Dictionary; + pResList = new CPDF_Dictionary(m_pDocument->GetByteStringPool()); m_pPage->m_pResources->SetFor(bsType, pResList); } CFX_ByteString name; @@ -113,7 +114,8 @@ void CPDF_PageContentGenerator::ProcessForm(CFX_ByteTextBuf& buf, if (!data || !size) return; - CPDF_Dictionary* pFormDict = new CPDF_Dictionary; + CPDF_Dictionary* pFormDict = + new CPDF_Dictionary(m_pDocument->GetByteStringPool()); pFormDict->SetNameFor("Type", "XObject"); pFormDict->SetNameFor("Subtype", "Form"); diff --git a/core/fpdfapi/fpdf_font/cpdf_font.cpp b/core/fpdfapi/fpdf_font/cpdf_font.cpp index e2eb2e567e..5d89752714 100644 --- a/core/fpdfapi/fpdf_font/cpdf_font.cpp +++ b/core/fpdfapi/fpdf_font/cpdf_font.cpp @@ -308,7 +308,7 @@ CPDF_Font* CPDF_Font::GetStockFont(CPDF_Document* pDoc, if (pFont) return pFont; - CPDF_Dictionary* pDict = new CPDF_Dictionary; + CPDF_Dictionary* pDict = new CPDF_Dictionary(pDoc->GetByteStringPool()); pDict->SetNameFor("Type", "Font"); pDict->SetNameFor("Subtype", "Type1"); pDict->SetNameFor("BaseFont", fontname); diff --git a/core/fpdfapi/fpdf_font/cpdf_fontencoding.cpp b/core/fpdfapi/fpdf_font/cpdf_fontencoding.cpp index 29587927bc..d0e5f16aea 100644 --- a/core/fpdfapi/fpdf_font/cpdf_fontencoding.cpp +++ b/core/fpdfapi/fpdf_font/cpdf_fontencoding.cpp @@ -1670,7 +1670,7 @@ FX_BOOL CPDF_FontEncoding::IsIdentical(CPDF_FontEncoding* pAnother) const { 0; } -CPDF_Object* CPDF_FontEncoding::Realize() { +CPDF_Object* CPDF_FontEncoding::Realize(CFX_WeakPtr pPool) { int predefined = 0; for (int cs = PDFFONT_ENCODING_WINANSI; cs < PDFFONT_ENCODING_ZAPFDINGBATS; cs++) { @@ -1689,13 +1689,13 @@ CPDF_Object* CPDF_FontEncoding::Realize() { } if (predefined) { if (predefined == PDFFONT_ENCODING_WINANSI) { - return new CPDF_Name("WinAnsiEncoding"); + return new CPDF_Name(pPool->Intern("WinAnsiEncoding")); } if (predefined == PDFFONT_ENCODING_MACROMAN) { - return new CPDF_Name("MacRomanEncoding"); + return new CPDF_Name(pPool->Intern("MacRomanEncoding")); } if (predefined == PDFFONT_ENCODING_MACEXPERT) { - return new CPDF_Name("MacExpertEncoding"); + return new CPDF_Name(pPool->Intern("MacExpertEncoding")); } return nullptr; } @@ -1710,7 +1710,7 @@ CPDF_Object* CPDF_FontEncoding::Realize() { pDiff->Add(new CPDF_Name(PDF_AdobeNameFromUnicode(m_Unicodes[i]))); } - CPDF_Dictionary* pDict = new CPDF_Dictionary; + CPDF_Dictionary* pDict = new CPDF_Dictionary(pPool); pDict->SetNameFor("BaseEncoding", "WinAnsiEncoding"); pDict->SetFor("Differences", pDiff); return pDict; diff --git a/core/fpdfapi/fpdf_font/include/cpdf_fontencoding.h b/core/fpdfapi/fpdf_font/include/cpdf_fontencoding.h index 6d6ff43814..8ded0ac708 100644 --- a/core/fpdfapi/fpdf_font/include/cpdf_fontencoding.h +++ b/core/fpdfapi/fpdf_font/include/cpdf_fontencoding.h @@ -7,6 +7,8 @@ #ifndef CORE_FPDFAPI_FPDF_FONT_INCLUDE_CPDF_FONTENCODING_H_ #define CORE_FPDFAPI_FPDF_FONT_INCLUDE_CPDF_FONTENCODING_H_ +#include "core/fxcrt/include/cfx_string_pool_template.h" +#include "core/fxcrt/include/cfx_weak_ptr.h" #include "core/fxcrt/include/fx_string.h" #define PDFFONT_ENCODING_BUILTIN 0 @@ -50,7 +52,7 @@ class CPDF_FontEncoding { m_Unicodes[charcode] = unicode; } - CPDF_Object* Realize(); + CPDF_Object* Realize(CFX_WeakPtr pPool); public: FX_WCHAR m_Unicodes[256]; diff --git a/core/fpdfapi/fpdf_page/cpdf_image.cpp b/core/fpdfapi/fpdf_page/cpdf_image.cpp index 4112ad86ee..91f1268eae 100644 --- a/core/fpdfapi/fpdf_page/cpdf_image.cpp +++ b/core/fpdfapi/fpdf_page/cpdf_image.cpp @@ -85,7 +85,8 @@ CPDF_Dictionary* CPDF_Image::InitJPEG(uint8_t* pData, uint32_t size) { return nullptr; } - CPDF_Dictionary* pDict = new CPDF_Dictionary; + CPDF_Dictionary* pDict = + new CPDF_Dictionary(m_pDocument->GetByteStringPool()); pDict->SetNameFor("Type", "XObject"); pDict->SetNameFor("Subtype", "Image"); pDict->SetIntegerFor("Width", width); @@ -108,7 +109,8 @@ CPDF_Dictionary* CPDF_Image::InitJPEG(uint8_t* pData, uint32_t size) { pDict->SetIntegerFor("BitsPerComponent", bits); pDict->SetNameFor("Filter", "DCTDecode"); if (!color_trans) { - CPDF_Dictionary* pParms = new CPDF_Dictionary; + CPDF_Dictionary* pParms = + new CPDF_Dictionary(m_pDocument->GetByteStringPool()); pDict->SetFor("DecodeParms", pParms); pParms->SetIntegerFor("ColorTransform", 0); } @@ -150,7 +152,8 @@ void CPDF_Image::SetImage(const CFX_DIBitmap* pBitmap, int32_t iCompress) { int32_t src_pitch = pBitmap->GetPitch(); int32_t bpp = pBitmap->GetBPP(); - CPDF_Dictionary* pDict = new CPDF_Dictionary; + CPDF_Dictionary* pDict = + new CPDF_Dictionary(m_pDocument->GetByteStringPool()); pDict->SetNameFor("Type", "XObject"); pDict->SetNameFor("Subtype", "Image"); pDict->SetIntegerFor("Width", BitmapWidth); @@ -213,8 +216,9 @@ void CPDF_Image::SetImage(const CFX_DIBitmap* pBitmap, int32_t iCompress) { ptr[2] = (uint8_t)argb; ptr += 3; } - CPDF_Stream* pCTS = - new CPDF_Stream(pColorTable, iPalette * 3, new CPDF_Dictionary); + CPDF_Stream* pCTS = new CPDF_Stream( + pColorTable, iPalette * 3, + new CPDF_Dictionary(m_pDocument->GetByteStringPool())); pCS->AddReference(m_pDocument, m_pDocument->AddIndirectObject(pCTS)); pDict->SetReferenceFor("ColorSpace", m_pDocument, m_pDocument->AddIndirectObject(pCS)); @@ -249,7 +253,8 @@ void CPDF_Image::SetImage(const CFX_DIBitmap* pBitmap, int32_t iCompress) { int32_t maskHeight = pMaskBitmap->GetHeight(); uint8_t* mask_buf = nullptr; FX_STRSIZE mask_size = 0; - CPDF_Dictionary* pMaskDict = new CPDF_Dictionary; + CPDF_Dictionary* pMaskDict = + new CPDF_Dictionary(m_pDocument->GetByteStringPool()); pMaskDict->SetNameFor("Type", "XObject"); pMaskDict->SetNameFor("Subtype", "Image"); pMaskDict->SetIntegerFor("Width", maskWidth); diff --git a/core/fpdfapi/fpdf_page/fpdf_page_doc.cpp b/core/fpdfapi/fpdf_page/fpdf_page_doc.cpp index c4e2a24424..192e0947bc 100644 --- a/core/fpdfapi/fpdf_page/fpdf_page_doc.cpp +++ b/core/fpdfapi/fpdf_page/fpdf_page_doc.cpp @@ -184,12 +184,13 @@ CPDF_Font* CPDF_DocPageData::GetStandardFont(const CFX_ByteString& fontName, return fontData->AddRef(); } - CPDF_Dictionary* pDict = new CPDF_Dictionary; + CPDF_Dictionary* pDict = new CPDF_Dictionary(m_pPDFDoc->GetByteStringPool()); pDict->SetNameFor("Type", "Font"); pDict->SetNameFor("Subtype", "Type1"); pDict->SetNameFor("BaseFont", fontName); if (pEncoding) { - pDict->SetFor("Encoding", pEncoding->Realize()); + pDict->SetFor("Encoding", + pEncoding->Realize(m_pPDFDoc->GetByteStringPool())); } m_pPDFDoc->AddIndirectObject(pDict); std::unique_ptr pFont = CPDF_Font::Create(m_pPDFDoc, pDict); diff --git a/core/fpdfapi/fpdf_page/fpdf_page_parser.cpp b/core/fpdfapi/fpdf_page/fpdf_page_parser.cpp index 46ab067b3e..881f9eed25 100644 --- a/core/fpdfapi/fpdf_page/fpdf_page_parser.cpp +++ b/core/fpdfapi/fpdf_page/fpdf_page_parser.cpp @@ -281,7 +281,8 @@ void CPDF_StreamContentParser::AddNameParam(const FX_CHAR* name, int len) { ContentParam& param = m_ParamBuf[GetNextParamPos()]; if (len > 32) { param.m_Type = ContentParam::OBJECT; - param.m_pObject = new CPDF_Name(PDF_NameDecode(bsName)); + param.m_pObject = new CPDF_Name( + m_pDocument->GetByteStringPool()->Intern(PDF_NameDecode(bsName))); } else { param.m_Type = ContentParam::NAME; if (bsName.Find('#') == -1) { @@ -343,8 +344,8 @@ CPDF_Object* CPDF_StreamContentParser::GetObject(uint32_t index) { return pNumber; } if (param.m_Type == ContentParam::NAME) { - CPDF_Name* pName = new CPDF_Name( - CFX_ByteString(param.m_Name.m_Buffer, param.m_Name.m_Len)); + CPDF_Name* pName = new CPDF_Name(m_pDocument->GetByteStringPool()->Intern( + CFX_ByteString(param.m_Name.m_Buffer, param.m_Name.m_Len))); param.m_Type = ContentParam::OBJECT; param.m_pObject = pName; return pName; @@ -589,7 +590,8 @@ void CPDF_StreamContentParser::Handle_BeginMarkedContent_Dictionary() { void CPDF_StreamContentParser::Handle_BeginImage() { FX_FILESIZE savePos = m_pSyntax->GetPos(); - CPDF_Dictionary* pDict = new CPDF_Dictionary; + CPDF_Dictionary* pDict = + new CPDF_Dictionary(m_pDocument->GetByteStringPool()); while (1) { CPDF_StreamParser::SyntaxType type = m_pSyntax->ParseNextElement(); if (type == CPDF_StreamParser::Keyword) { @@ -1499,7 +1501,7 @@ uint32_t CPDF_StreamContentParser::Parse(const uint8_t* pData, return dwSize; } uint32_t InitObjCount = m_pObjectHolder->GetPageObjectList()->size(); - CPDF_StreamParser syntax(pData, dwSize); + CPDF_StreamParser syntax(pData, dwSize, m_pDocument->GetByteStringPool()); CPDF_StreamParserAutoClearer auto_clearer(&m_pSyntax, &syntax); while (1) { uint32_t cost = m_pObjectHolder->GetPageObjectList()->size() - InitObjCount; diff --git a/core/fpdfapi/fpdf_page/fpdf_page_parser_old.cpp b/core/fpdfapi/fpdf_page/fpdf_page_parser_old.cpp index eab0ee595b..0e9cd3b55d 100644 --- a/core/fpdfapi/fpdf_page/fpdf_page_parser_old.cpp +++ b/core/fpdfapi/fpdf_page/fpdf_page_parser_old.cpp @@ -41,12 +41,22 @@ const FX_STRSIZE kMaxStringLength = 32767; } // namespace -CPDF_StreamParser::CPDF_StreamParser(const uint8_t* pData, uint32_t dwSize) { - m_pBuf = pData; - m_Size = dwSize; - m_Pos = 0; - m_pLastObj = nullptr; -} +CPDF_StreamParser::CPDF_StreamParser(const uint8_t* pData, uint32_t dwSize) + : m_pBuf(pData), + m_Size(dwSize), + m_Pos(0), + m_pLastObj(nullptr), + m_pPool(nullptr) {} + +CPDF_StreamParser::CPDF_StreamParser( + const uint8_t* pData, + uint32_t dwSize, + const CFX_WeakPtr& pPool) + : m_pBuf(pData), + m_Size(dwSize), + m_Pos(0), + m_pLastObj(nullptr), + m_pPool(pPool) {} CPDF_StreamParser::~CPDF_StreamParser() { if (m_pLastObj) { @@ -336,18 +346,21 @@ CPDF_Object* CPDF_StreamParser::ReadNextObject(bool bAllowNestedArray, int first_char = m_WordBuffer[0]; if (first_char == '/') { - return new CPDF_Name( - PDF_NameDecode(CFX_ByteStringC(m_WordBuffer + 1, m_WordSize - 1))); + CFX_ByteString name = + PDF_NameDecode(CFX_ByteStringC(m_WordBuffer + 1, m_WordSize - 1)); + return new CPDF_Name(m_pPool ? m_pPool->Intern(name) : name); } - if (first_char == '(') - return new CPDF_String(ReadString(), FALSE); + if (first_char == '(') { + CFX_ByteString str = ReadString(); + return new CPDF_String(m_pPool ? m_pPool->Intern(str) : str, FALSE); + } if (first_char == '<') { if (m_WordSize == 1) return new CPDF_String(ReadHexString(), TRUE); - CPDF_Dictionary* pDict = new CPDF_Dictionary; + CPDF_Dictionary* pDict = new CPDF_Dictionary(m_pPool); while (1) { GetNextWord(bIsNumber); if (m_WordSize == 2 && m_WordBuffer[0] == '>') diff --git a/core/fpdfapi/fpdf_page/pageint.h b/core/fpdfapi/fpdf_page/pageint.h index 427a363e8e..c5b80aa550 100644 --- a/core/fpdfapi/fpdf_page/pageint.h +++ b/core/fpdfapi/fpdf_page/pageint.h @@ -16,6 +16,8 @@ #include "core/fpdfapi/fpdf_page/cpdf_contentmark.h" #include "core/fpdfapi/fpdf_page/cpdf_countedobject.h" #include "core/fpdfapi/fpdf_page/include/cpdf_pageobjectholder.h" +#include "core/fxcrt/include/cfx_string_pool_template.h" +#include "core/fxcrt/include/cfx_weak_ptr.h" #include "core/fxge/include/cfx_pathdata.h" #include "core/fxge/include/cfx_renderdevice.h" @@ -43,6 +45,9 @@ class CPDF_StreamParser { enum SyntaxType { EndOfData, Number, Keyword, Name, Others }; CPDF_StreamParser(const uint8_t* pData, uint32_t dwSize); + CPDF_StreamParser(const uint8_t* pData, + uint32_t dwSize, + const CFX_WeakPtr& pPool); ~CPDF_StreamParser(); CPDF_Stream* ReadInlineStream(CPDF_Document* pDoc, @@ -66,17 +71,14 @@ class CPDF_StreamParser { void GetNextWord(FX_BOOL& bIsNumber); CFX_ByteString ReadString(); CFX_ByteString ReadHexString(); - const uint8_t* m_pBuf; - - // Length in bytes of m_pBuf. - uint32_t m_Size; - - // Current byte position within m_pBuf. - uint32_t m_Pos; + const uint8_t* m_pBuf; + uint32_t m_Size; // Length in bytes of m_pBuf. + uint32_t m_Pos; // Current byte position within m_pBuf. uint8_t m_WordBuffer[256]; uint32_t m_WordSize; CPDF_Object* m_pLastObj; + CFX_WeakPtr m_pPool; private: bool PositionIsInBounds() const; diff --git a/core/fpdfapi/fpdf_parser/cfdf_document.cpp b/core/fpdfapi/fpdf_parser/cfdf_document.cpp index c602f634ad..128c513c60 100644 --- a/core/fpdfapi/fpdf_parser/cfdf_document.cpp +++ b/core/fpdfapi/fpdf_parser/cfdf_document.cpp @@ -14,18 +14,21 @@ CFDF_Document::CFDF_Document() : CPDF_IndirectObjectHolder(), m_pRootDict(nullptr), m_pFile(nullptr), - m_bOwnFile(FALSE) {} + m_bOwnFile(FALSE), + m_pByteStringPool(WrapUnique(new CFX_ByteStringPool)) {} CFDF_Document::~CFDF_Document() { if (m_bOwnFile && m_pFile) m_pFile->Release(); + m_pByteStringPool.Clear(); // Make weak. } CFDF_Document* CFDF_Document::CreateNewDoc() { CFDF_Document* pDoc = new CFDF_Document; - pDoc->m_pRootDict = new CPDF_Dictionary; + pDoc->m_pRootDict = new CPDF_Dictionary(pDoc->GetByteStringPool()); pDoc->AddIndirectObject(pDoc->m_pRootDict); - pDoc->m_pRootDict->SetFor("FDF", new CPDF_Dictionary); + pDoc->m_pRootDict->SetFor("FDF", + new CPDF_Dictionary(pDoc->GetByteStringPool())); return pDoc; } diff --git a/core/fpdfapi/fpdf_parser/cpdf_dictionary.cpp b/core/fpdfapi/fpdf_parser/cpdf_dictionary.cpp index 1a84fcb142..0b415d370d 100644 --- a/core/fpdfapi/fpdf_parser/cpdf_dictionary.cpp +++ b/core/fpdfapi/fpdf_parser/cpdf_dictionary.cpp @@ -19,7 +19,8 @@ #include "third_party/base/stl_util.h" #include "third_party/base/logging.h" -CPDF_Dictionary::CPDF_Dictionary() {} +CPDF_Dictionary::CPDF_Dictionary(const CFX_WeakPtr& pPool) + : m_pPool(pPool) {} CPDF_Dictionary::~CPDF_Dictionary() { // Mark the object as deleted so that it will not be deleted again @@ -61,7 +62,7 @@ CPDF_Object* CPDF_Dictionary::CloneNonCyclic( bool bDirect, std::set* pVisited) const { pVisited->insert(this); - CPDF_Dictionary* pCopy = new CPDF_Dictionary(); + CPDF_Dictionary* pCopy = new CPDF_Dictionary(m_pPool); for (const auto& it : *this) { CPDF_Object* value = it.second; if (!pdfium::ContainsKey(*pVisited, value)) { @@ -174,7 +175,7 @@ void CPDF_Dictionary::SetFor(const CFX_ByteString& key, CPDF_Object* pObj) { auto it = m_Map.find(key); if (it == m_Map.end()) { if (pObj) - m_Map.insert(std::make_pair(key, pObj)); + m_Map.insert(std::make_pair(MaybeIntern(key), pObj)); return; } @@ -211,7 +212,7 @@ void CPDF_Dictionary::ReplaceKey(const CFX_ByteString& oldkey, new_it->second->Release(); new_it->second = old_it->second; } else { - m_Map.insert(std::make_pair(newkey, old_it->second)); + m_Map.insert(std::make_pair(MaybeIntern(newkey), old_it->second)); } m_Map.erase(old_it); } @@ -222,12 +223,12 @@ void CPDF_Dictionary::SetIntegerFor(const CFX_ByteString& key, int i) { void CPDF_Dictionary::SetNameFor(const CFX_ByteString& key, const CFX_ByteString& name) { - SetFor(key, new CPDF_Name(name)); + SetFor(key, new CPDF_Name(MaybeIntern(name))); } void CPDF_Dictionary::SetStringFor(const CFX_ByteString& key, const CFX_ByteString& str) { - SetFor(key, new CPDF_String(str, FALSE)); + SetFor(key, new CPDF_String(MaybeIntern(str), FALSE)); } void CPDF_Dictionary::SetReferenceFor(const CFX_ByteString& key, @@ -265,3 +266,7 @@ void CPDF_Dictionary::SetMatrixFor(const CFX_ByteString& key, pArray->AddNumber(matrix.f); SetFor(key, pArray); } + +CFX_ByteString CPDF_Dictionary::MaybeIntern(const CFX_ByteString& str) { + return m_pPool ? m_pPool->Intern(str) : str; +} diff --git a/core/fpdfapi/fpdf_parser/cpdf_document.cpp b/core/fpdfapi/fpdf_parser/cpdf_document.cpp index 1694566f1b..7e75a437a8 100644 --- a/core/fpdfapi/fpdf_parser/cpdf_document.cpp +++ b/core/fpdfapi/fpdf_parser/cpdf_document.cpp @@ -383,14 +383,15 @@ void ProcessNonbCJK(CPDF_Dictionary* pBaseDict, pBaseDict->SetFor("Widths", pWidths); } -CPDF_Dictionary* CalculateFontDesc(CFX_ByteString basefont, +CPDF_Dictionary* CalculateFontDesc(CPDF_Document* pDoc, + CFX_ByteString basefont, int flags, int italicangle, int ascend, int descend, CPDF_Array* bbox, int32_t stemV) { - CPDF_Dictionary* pFontDesc = new CPDF_Dictionary; + CPDF_Dictionary* pFontDesc = new CPDF_Dictionary(pDoc->GetByteStringPool()); pFontDesc->SetNameFor("Type", "FontDescriptor"); pFontDesc->SetNameFor("FontName", basefont); pFontDesc->SetIntegerFor("Flags", flags); @@ -413,7 +414,8 @@ CPDF_Document::CPDF_Document(std::unique_ptr pParser) m_iFirstPageNo(0), m_dwFirstPageObjNum(0), m_pDocPage(new CPDF_DocPageData(this)), - m_pDocRender(new CPDF_DocRenderData(this)) { + m_pDocRender(new CPDF_DocRenderData(this)), + m_pByteStringPool(WrapUnique(new CFX_ByteStringPool)) { if (pParser) SetLastObjNum(m_pParser->GetLastObjNum()); } @@ -421,6 +423,7 @@ CPDF_Document::CPDF_Document(std::unique_ptr pParser) CPDF_Document::~CPDF_Document() { delete m_pDocPage; CPDF_ModuleMgr::Get()->GetPageModule()->ClearStockFont(this); + m_pByteStringPool.Clear(); // Make weak. } CPDF_Object* CPDF_Document::ParseIndirectObject(uint32_t objnum) { @@ -687,20 +690,21 @@ CPDF_Image* CPDF_Document::LoadImageF(CPDF_Object* pObj) { void CPDF_Document::CreateNewDoc() { ASSERT(!m_pRootDict && !m_pInfoDict); - m_pRootDict = new CPDF_Dictionary; + m_pRootDict = new CPDF_Dictionary(m_pByteStringPool); m_pRootDict->SetNameFor("Type", "Catalog"); AddIndirectObject(m_pRootDict); - CPDF_Dictionary* pPages = new CPDF_Dictionary; + + CPDF_Dictionary* pPages = new CPDF_Dictionary(m_pByteStringPool); pPages->SetNameFor("Type", "Pages"); pPages->SetNumberFor("Count", 0); pPages->SetFor("Kids", new CPDF_Array); m_pRootDict->SetReferenceFor("Pages", this, AddIndirectObject(pPages)); - m_pInfoDict = new CPDF_Dictionary; + m_pInfoDict = new CPDF_Dictionary(m_pByteStringPool); AddIndirectObject(m_pInfoDict); } CPDF_Dictionary* CPDF_Document::CreateNewPage(int iPage) { - CPDF_Dictionary* pDict = new CPDF_Dictionary; + CPDF_Dictionary* pDict = new CPDF_Dictionary(m_pByteStringPool); pDict->SetNameFor("Type", "Page"); uint32_t dwObjNum = AddIndirectObject(pDict); if (InsertNewPage(this, iPage, pDict, m_PageList) < 0) { @@ -743,7 +747,7 @@ size_t CPDF_Document::CalculateEncodingDict(int charset, } if (i == FX_ArraySize(g_FX_CharsetUnicodes)) return i; - CPDF_Dictionary* pEncodingDict = new CPDF_Dictionary; + CPDF_Dictionary* pEncodingDict = new CPDF_Dictionary(m_pByteStringPool); pEncodingDict->SetNameFor("BaseEncoding", "WinAnsiEncoding"); CPDF_Array* pArray = new CPDF_Array; pArray->AddInteger(128); @@ -765,7 +769,7 @@ CPDF_Dictionary* CPDF_Document::ProcessbCJK( FX_BOOL bVert, CFX_ByteString basefont, std::function Insert) { - CPDF_Dictionary* pFontDict = new CPDF_Dictionary; + CPDF_Dictionary* pFontDict = new CPDF_Dictionary(m_pByteStringPool); CFX_ByteString cmap; CFX_ByteString ordering; int supplement = 0; @@ -815,7 +819,7 @@ CPDF_Dictionary* CPDF_Document::ProcessbCJK( pFontDict->SetNameFor("Type", "Font"); pFontDict->SetNameFor("Subtype", "CIDFontType2"); pFontDict->SetNameFor("BaseFont", basefont); - CPDF_Dictionary* pCIDSysInfo = new CPDF_Dictionary; + CPDF_Dictionary* pCIDSysInfo = new CPDF_Dictionary(m_pByteStringPool); pCIDSysInfo->SetStringFor("Registry", "Adobe"); pCIDSysInfo->SetStringFor("Ordering", ordering); pCIDSysInfo->SetIntegerFor("Supplement", supplement); @@ -840,7 +844,7 @@ CPDF_Font* CPDF_Document::AddFont(CFX_Font* pFont, int charset, FX_BOOL bVert) { CalculateFlags(pFont->IsBold(), pFont->IsItalic(), pFont->IsFixedWidth(), false, false, charset == FXFONT_SYMBOL_CHARSET); - CPDF_Dictionary* pBaseDict = new CPDF_Dictionary; + CPDF_Dictionary* pBaseDict = new CPDF_Dictionary(m_pByteStringPool); pBaseDict->SetNameFor("Type", "Font"); std::unique_ptr pEncoding( new CFX_UnicodeEncoding(pFont)); @@ -907,7 +911,7 @@ CPDF_Font* CPDF_Document::AddFont(CFX_Font* pFont, int charset, FX_BOOL bVert) { } } CPDF_Dictionary* pFontDesc = - CalculateFontDesc(basefont, flags, italicangle, pFont->GetAscent(), + CalculateFontDesc(this, basefont, flags, italicangle, pFont->GetAscent(), pFont->GetDescent(), pBBox, nStemV); pFontDict->SetReferenceFor("FontDescriptor", this, AddIndirectObject(pFontDesc)); @@ -972,7 +976,7 @@ CPDF_Font* CPDF_Document::AddWindowsFont(LOGFONTA* pLogFont, ptm->otmrcFontBox.right, ptm->otmrcFontBox.top}; FX_Free(tm_buf); basefont.Replace(" ", ""); - CPDF_Dictionary* pBaseDict = new CPDF_Dictionary; + CPDF_Dictionary* pBaseDict = new CPDF_Dictionary(m_pByteStringPool); pBaseDict->SetNameFor("Type", "Font"); CPDF_Dictionary* pFontDict = pBaseDict; if (!bCJK) { @@ -1002,8 +1006,8 @@ CPDF_Font* CPDF_Document::AddWindowsFont(LOGFONTA* pLogFont, for (int i = 0; i < 4; i++) pBBox->AddInteger(bbox[i]); CPDF_Dictionary* pFontDesc = - CalculateFontDesc(basefont, flags, italicangle, ascend, descend, pBBox, - pLogFont->lfWeight / 5); + CalculateFontDesc(this, basefont, flags, italicangle, ascend, descend, + pBBox, pLogFont->lfWeight / 5); pFontDesc->SetIntegerFor("CapHeight", capheight); pFontDict->SetReferenceFor("FontDescriptor", this, AddIndirectObject(pFontDesc)); diff --git a/core/fpdfapi/fpdf_parser/cpdf_object_unittest.cpp b/core/fpdfapi/fpdf_parser/cpdf_object_unittest.cpp index dad98cd28e..1548b1914a 100644 --- a/core/fpdfapi/fpdf_parser/cpdf_object_unittest.cpp +++ b/core/fpdfapi/fpdf_parser/cpdf_object_unittest.cpp @@ -66,7 +66,7 @@ class PDFObjectsTest : public testing::Test { m_ArrayObj->InsertAt(0, new CPDF_Number(8902)); m_ArrayObj->InsertAt(1, new CPDF_Name("address")); // Dictionary object. - m_DictObj = new CPDF_Dictionary; + m_DictObj = new CPDF_Dictionary(CFX_WeakPtr()); m_DictObj->SetFor("bool", new CPDF_Boolean(false)); m_DictObj->SetFor("num", new CPDF_Number(0.23f)); // Stream object. @@ -74,7 +74,7 @@ class PDFObjectsTest : public testing::Test { size_t buf_len = FX_ArraySize(content); uint8_t* buf = reinterpret_cast(malloc(buf_len)); memcpy(buf, content, buf_len); - m_StreamDictObj = new CPDF_Dictionary; + m_StreamDictObj = new CPDF_Dictionary(CFX_WeakPtr()); m_StreamDictObj->SetFor("key1", new CPDF_String(L" test dict")); m_StreamDictObj->SetFor("key2", new CPDF_Number(-1)); CPDF_Stream* stream_obj = new CPDF_Stream(buf, buf_len, m_StreamDictObj); @@ -553,7 +553,7 @@ TEST(PDFArrayTest, GetTypeAt) { CPDF_Dictionary* vals[3]; ScopedArray arr(new CPDF_Array); for (size_t i = 0; i < 3; ++i) { - vals[i] = new CPDF_Dictionary; + vals[i] = new CPDF_Dictionary(CFX_WeakPtr()); for (size_t j = 0; j < 3; ++j) { std::string key("key"); char buf[33]; @@ -580,7 +580,7 @@ TEST(PDFArrayTest, GetTypeAt) { CPDF_Stream* stream_vals[3]; ScopedArray arr(new CPDF_Array); for (size_t i = 0; i < 3; ++i) { - vals[i] = new CPDF_Dictionary; + vals[i] = new CPDF_Dictionary(CFX_WeakPtr()); for (size_t j = 0; j < 3; ++j) { std::string key("key"); char buf[33]; @@ -625,11 +625,13 @@ TEST(PDFArrayTest, GetTypeAt) { arr_val->AddNumber(1); arr_val->AddNumber(2); arr->InsertAt(11, arr_val); - CPDF_Dictionary* dict_val = new CPDF_Dictionary; + CPDF_Dictionary* dict_val = + new CPDF_Dictionary(CFX_WeakPtr()); dict_val->SetFor("key1", new CPDF_String("Linda", false)); dict_val->SetFor("key2", new CPDF_String("Zoe", false)); arr->InsertAt(12, dict_val); - CPDF_Dictionary* stream_dict = new CPDF_Dictionary; + CPDF_Dictionary* stream_dict = + new CPDF_Dictionary(CFX_WeakPtr()); stream_dict->SetFor("key1", new CPDF_String("John", false)); stream_dict->SetFor("key2", new CPDF_String("King", false)); uint8_t data[] = "A stream for test"; @@ -768,7 +770,7 @@ TEST(PDFArrayTest, CloneDirectObject) { TEST(PDFDictionaryTest, CloneDirectObject) { CPDF_IndirectObjectHolder objects_holder; - ScopedDict dict(new CPDF_Dictionary); + ScopedDict dict(new CPDF_Dictionary(CFX_WeakPtr())); dict->SetReferenceFor("foo", &objects_holder, 1234); ASSERT_EQ(1U, dict->GetCount()); CPDF_Object* obj = dict->GetObjectFor("foo"); @@ -790,7 +792,8 @@ TEST(PDFObjectTest, CloneCheckLoop) { // Create an object with a reference loop. ScopedArray arr_obj(new CPDF_Array); // Dictionary object. - CPDF_Dictionary* dict_obj = new CPDF_Dictionary; + CPDF_Dictionary* dict_obj = + new CPDF_Dictionary(CFX_WeakPtr()); dict_obj->SetFor("arr", arr_obj.get()); arr_obj->InsertAt(0, dict_obj); @@ -808,7 +811,8 @@ TEST(PDFObjectTest, CloneCheckLoop) { { CPDF_IndirectObjectHolder objects_holder; // Create an object with a reference loop. - CPDF_Dictionary* dict_obj = new CPDF_Dictionary; + CPDF_Dictionary* dict_obj = + new CPDF_Dictionary(CFX_WeakPtr()); CPDF_Array* arr_obj = new CPDF_Array; objects_holder.AddIndirectObject(dict_obj); EXPECT_EQ(1u, dict_obj->GetObjNum()); diff --git a/core/fpdfapi/fpdf_parser/cpdf_stream.cpp b/core/fpdfapi/fpdf_parser/cpdf_stream.cpp index cc584b78b3..3b047205c4 100644 --- a/core/fpdfapi/fpdf_parser/cpdf_stream.cpp +++ b/core/fpdfapi/fpdf_parser/cpdf_stream.cpp @@ -93,7 +93,7 @@ void CPDF_Stream::SetData(const uint8_t* pData, uint32_t size) { FXSYS_memcpy(m_pDataBuf.get(), pData, size); m_dwSize = size; if (!m_pDict) - m_pDict.reset(new CPDF_Dictionary); + m_pDict.reset(new CPDF_Dictionary(CFX_WeakPtr())); m_pDict->SetIntegerFor("Length", size); m_pDict->RemoveFor("Filter"); m_pDict->RemoveFor("DecodeParms"); diff --git a/core/fpdfapi/fpdf_parser/cpdf_syntax_parser.cpp b/core/fpdfapi/fpdf_parser/cpdf_syntax_parser.cpp index 4bfaf99ed9..a29137cd43 100644 --- a/core/fpdfapi/fpdf_parser/cpdf_syntax_parser.cpp +++ b/core/fpdfapi/fpdf_parser/cpdf_syntax_parser.cpp @@ -37,10 +37,15 @@ struct SearchTagRecord { int CPDF_SyntaxParser::s_CurrentRecursionDepth = 0; CPDF_SyntaxParser::CPDF_SyntaxParser() + : CPDF_SyntaxParser(CFX_WeakPtr()) {} + +CPDF_SyntaxParser::CPDF_SyntaxParser( + const CFX_WeakPtr& pPool) : m_MetadataObjnum(0), m_pFileAccess(nullptr), m_pFileBuf(nullptr), - m_BufSize(CPDF_ModuleMgr::kFileBufSize) {} + m_BufSize(CPDF_ModuleMgr::kFileBufSize), + m_pPool(pPool) {} CPDF_SyntaxParser::~CPDF_SyntaxParser() { FX_Free(m_pFileBuf); @@ -409,15 +414,14 @@ CPDF_Object* CPDF_SyntaxParser::GetObject(CPDF_IndirectObjectHolder* pObjList, CFX_ByteString str = ReadString(); if (m_pCryptoHandler && bDecrypt) m_pCryptoHandler->Decrypt(objnum, gennum, str); - return new CPDF_String(str, FALSE); + return new CPDF_String(MaybeIntern(str), FALSE); } if (word == "<") { CFX_ByteString str = ReadHexString(); if (m_pCryptoHandler && bDecrypt) m_pCryptoHandler->Decrypt(objnum, gennum, str); - - return new CPDF_String(str, TRUE); + return new CPDF_String(MaybeIntern(str), TRUE); } if (word == "[") { @@ -429,8 +433,8 @@ CPDF_Object* CPDF_SyntaxParser::GetObject(CPDF_IndirectObjectHolder* pObjList, } if (word[0] == '/') { - return new CPDF_Name( - PDF_NameDecode(CFX_ByteStringC(m_WordBuffer + 1, m_WordSize - 1))); + return new CPDF_Name(MaybeIntern( + PDF_NameDecode(CFX_ByteStringC(m_WordBuffer + 1, m_WordSize - 1)))); } if (word == "<<") { @@ -438,7 +442,7 @@ CPDF_Object* CPDF_SyntaxParser::GetObject(CPDF_IndirectObjectHolder* pObjList, FX_FILESIZE dwSignValuePos = 0; std::unique_ptr> pDict( - new CPDF_Dictionary); + new CPDF_Dictionary(m_pPool)); while (1) { CFX_ByteString key = GetNextWord(nullptr); if (key.IsEmpty()) @@ -531,14 +535,14 @@ CPDF_Object* CPDF_SyntaxParser::GetObjectForStrict( CFX_ByteString str = ReadString(); if (m_pCryptoHandler) m_pCryptoHandler->Decrypt(objnum, gennum, str); - return new CPDF_String(str, FALSE); + return new CPDF_String(MaybeIntern(str), FALSE); } if (word == "<") { CFX_ByteString str = ReadHexString(); if (m_pCryptoHandler) m_pCryptoHandler->Decrypt(objnum, gennum, str); - return new CPDF_String(str, TRUE); + return new CPDF_String(MaybeIntern(str), TRUE); } if (word == "[") { @@ -551,13 +555,13 @@ CPDF_Object* CPDF_SyntaxParser::GetObjectForStrict( } if (word[0] == '/') { - return new CPDF_Name( - PDF_NameDecode(CFX_ByteStringC(m_WordBuffer + 1, m_WordSize - 1))); + return new CPDF_Name(MaybeIntern( + PDF_NameDecode(CFX_ByteStringC(m_WordBuffer + 1, m_WordSize - 1)))); } if (word == "<<") { std::unique_ptr> pDict( - new CPDF_Dictionary); + new CPDF_Dictionary(m_pPool)); while (1) { FX_FILESIZE SavedPos = m_Pos; CFX_ByteString key = GetNextWord(nullptr); @@ -987,3 +991,7 @@ void CPDF_SyntaxParser::SetEncrypt( std::unique_ptr pCryptoHandler) { m_pCryptoHandler = std::move(pCryptoHandler); } + +CFX_ByteString CPDF_SyntaxParser::MaybeIntern(const CFX_ByteString& str) { + return m_pPool ? m_pPool->Intern(str) : str; +} diff --git a/core/fpdfapi/fpdf_parser/cpdf_syntax_parser.h b/core/fpdfapi/fpdf_parser/cpdf_syntax_parser.h index 8ca7e33824..5838fb7144 100644 --- a/core/fpdfapi/fpdf_parser/cpdf_syntax_parser.h +++ b/core/fpdfapi/fpdf_parser/cpdf_syntax_parser.h @@ -9,6 +9,8 @@ #include +#include "core/fxcrt/include/cfx_string_pool_template.h" +#include "core/fxcrt/include/cfx_weak_ptr.h" #include "core/fxcrt/include/fx_basic.h" class CPDF_CryptoHandler; @@ -21,6 +23,7 @@ class IFX_FileRead; class CPDF_SyntaxParser { public: CPDF_SyntaxParser(); + explicit CPDF_SyntaxParser(const CFX_WeakPtr& pPool); ~CPDF_SyntaxParser(); void InitParser(IFX_FileRead* pFileAccess, uint32_t HeaderOffset); @@ -64,7 +67,6 @@ class CPDF_SyntaxParser { static int s_CurrentRecursionDepth; uint32_t GetDirectNum(); - FX_BOOL GetNextChar(uint8_t& ch); FX_BOOL GetCharAtBackward(FX_FILESIZE pos, uint8_t& ch); void GetNextWordInternal(bool* bIsNumber); @@ -80,6 +82,8 @@ class CPDF_SyntaxParser { uint32_t objnum, uint32_t gennum); + CFX_ByteString MaybeIntern(const CFX_ByteString& str); + FX_FILESIZE m_Pos; int m_MetadataObjnum; IFX_FileRead* m_pFileAccess; @@ -91,6 +95,7 @@ class CPDF_SyntaxParser { std::unique_ptr m_pCryptoHandler; uint8_t m_WordBuffer[257]; uint32_t m_WordSize; + CFX_WeakPtr m_pPool; }; #endif // CORE_FPDFAPI_FPDF_PARSER_CPDF_SYNTAX_PARSER_H_ diff --git a/core/fpdfapi/fpdf_parser/include/cfdf_document.h b/core/fpdfapi/fpdf_parser/include/cfdf_document.h index 834aecd1ba..25366b0cd4 100644 --- a/core/fpdfapi/fpdf_parser/include/cfdf_document.h +++ b/core/fpdfapi/fpdf_parser/include/cfdf_document.h @@ -9,6 +9,8 @@ #include "core/fpdfapi/fpdf_parser/include/cpdf_indirect_object_holder.h" #include "core/fpdfapi/fpdf_parser/include/cpdf_object.h" +#include "core/fxcrt/include/cfx_string_pool_template.h" +#include "core/fxcrt/include/cfx_weak_ptr.h" #include "core/fxcrt/include/fx_basic.h" class CPDF_Dictionary; @@ -23,6 +25,9 @@ class CFDF_Document : public CPDF_IndirectObjectHolder { FX_BOOL WriteBuf(CFX_ByteTextBuf& buf) const; CPDF_Dictionary* GetRoot() const { return m_pRootDict; } + CFX_WeakPtr GetByteStringPool() const { + return m_pByteStringPool; + } protected: CFDF_Document(); @@ -31,6 +36,7 @@ class CFDF_Document : public CPDF_IndirectObjectHolder { CPDF_Dictionary* m_pRootDict; IFX_FileRead* m_pFile; FX_BOOL m_bOwnFile; + CFX_WeakPtr m_pByteStringPool; }; #endif // CORE_FPDFAPI_FPDF_PARSER_INCLUDE_CFDF_DOCUMENT_H_ diff --git a/core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h b/core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h index fc69ce2f4b..501b287dfc 100644 --- a/core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h +++ b/core/fpdfapi/fpdf_parser/include/cpdf_dictionary.h @@ -11,6 +11,8 @@ #include #include "core/fpdfapi/fpdf_parser/include/cpdf_object.h" +#include "core/fxcrt/include/cfx_string_pool_template.h" +#include "core/fxcrt/include/cfx_weak_ptr.h" #include "core/fxcrt/include/fx_coordinates.h" #include "core/fxcrt/include/fx_string.h" @@ -21,7 +23,7 @@ class CPDF_Dictionary : public CPDF_Object { using iterator = std::map::iterator; using const_iterator = std::map::const_iterator; - CPDF_Dictionary(); + explicit CPDF_Dictionary(const CFX_WeakPtr& pPool); // CPDF_Object. Type GetType() const override; @@ -78,13 +80,17 @@ class CPDF_Dictionary : public CPDF_Object { const_iterator begin() const { return m_Map.begin(); } const_iterator end() const { return m_Map.end(); } + CFX_WeakPtr GetByteStringPool() const { return m_pPool; } + protected: ~CPDF_Dictionary() override; + CFX_ByteString MaybeIntern(const CFX_ByteString& str); CPDF_Object* CloneNonCyclic( bool bDirect, std::set* visited) const override; + CFX_WeakPtr m_pPool; std::map m_Map; }; diff --git a/core/fpdfapi/fpdf_parser/include/cpdf_document.h b/core/fpdfapi/fpdf_parser/include/cpdf_document.h index 1cc32dc3b2..383c6faeb4 100644 --- a/core/fpdfapi/fpdf_parser/include/cpdf_document.h +++ b/core/fpdfapi/fpdf_parser/include/cpdf_document.h @@ -13,6 +13,8 @@ #include "core/fpdfapi/fpdf_parser/include/cpdf_indirect_object_holder.h" #include "core/fpdfapi/fpdf_parser/include/cpdf_object.h" #include "core/fpdfdoc/include/cpdf_linklist.h" +#include "core/fxcrt/include/cfx_string_pool_template.h" +#include "core/fxcrt/include/cfx_weak_ptr.h" #include "core/fxcrt/include/fx_basic.h" class CFX_Font; @@ -47,6 +49,9 @@ class CPDF_Document : public CPDF_IndirectObjectHolder { CPDF_Parser* GetParser() const { return m_pParser.get(); } CPDF_Dictionary* GetRoot() const { return m_pRootDict; } CPDF_Dictionary* GetInfo() const { return m_pInfoDict; } + CFX_WeakPtr GetByteStringPool() const { + return m_pByteStringPool; + } void DeletePage(int iPage); int GetPageCount() const; @@ -134,6 +139,7 @@ class CPDF_Document : public CPDF_IndirectObjectHolder { std::unique_ptr m_pCodecContext; std::unique_ptr m_pLinksContext; CFX_ArrayTemplate m_PageList; + CFX_WeakPtr m_pByteStringPool; }; #endif // CORE_FPDFAPI_FPDF_PARSER_INCLUDE_CPDF_DOCUMENT_H_ diff --git a/core/fpdfdoc/cpdf_annotlist.cpp b/core/fpdfdoc/cpdf_annotlist.cpp index 8ab99e55d2..38d73460ef 100644 --- a/core/fpdfdoc/cpdf_annotlist.cpp +++ b/core/fpdfdoc/cpdf_annotlist.cpp @@ -30,7 +30,8 @@ std::unique_ptr CreatePopupAnnot(CPDF_Annot* pAnnot, if (sContents.IsEmpty()) return std::unique_ptr(); - CPDF_Dictionary* pAnnotDict = new CPDF_Dictionary; + CPDF_Dictionary* pAnnotDict = + new CPDF_Dictionary(pDocument->GetByteStringPool()); pAnnotDict->SetNameFor("Type", "Annot"); pAnnotDict->SetNameFor("Subtype", "Popup"); pAnnotDict->SetStringFor("T", pParentDict->GetStringFor("T")); diff --git a/core/fpdfdoc/cpdf_filespec.cpp b/core/fpdfdoc/cpdf_filespec.cpp index 3176eb51af..8423d66fc7 100644 --- a/core/fpdfdoc/cpdf_filespec.cpp +++ b/core/fpdfdoc/cpdf_filespec.cpp @@ -110,8 +110,8 @@ bool CPDF_FileSpec::GetFileName(CFX_WideString* csFileName) const { return true; } -CPDF_FileSpec::CPDF_FileSpec() { - m_pObj = new CPDF_Dictionary; +CPDF_FileSpec::CPDF_FileSpec(const CFX_WeakPtr& pPool) { + m_pObj = new CPDF_Dictionary(pPool); m_pObj->AsDictionary()->SetNameFor("Type", "Filespec"); } diff --git a/core/fpdfdoc/cpdf_filespec_unittest.cpp b/core/fpdfdoc/cpdf_filespec_unittest.cpp index f63c388478..25577bb00b 100644 --- a/core/fpdfdoc/cpdf_filespec_unittest.cpp +++ b/core/fpdfdoc/cpdf_filespec_unittest.cpp @@ -105,7 +105,7 @@ TEST(cpdf_filespec, GetFileName) { }; // Keyword fields in reverse order of precedence to retrieve the file name. const char* const keywords[5] = {"Unix", "Mac", "DOS", "F", "UF"}; - ScopedDict dict_obj(new CPDF_Dictionary); + ScopedDict dict_obj(new CPDF_Dictionary(CFX_WeakPtr())); CPDF_FileSpec file_spec(dict_obj.get()); CFX_WideString file_name; for (int i = 0; i < 5; ++i) { @@ -155,7 +155,7 @@ TEST(cpdf_filespec, SetFileName) { EXPECT_TRUE(file_name == test_data.input); // Dictionary object. - ScopedDict dict_obj(new CPDF_Dictionary); + ScopedDict dict_obj(new CPDF_Dictionary(CFX_WeakPtr())); CPDF_FileSpec file_spec2(dict_obj.get()); file_spec2.SetFileName(test_data.input); // Check internal object value. diff --git a/core/fpdfdoc/cpdf_formfield_unittest.cpp b/core/fpdfdoc/cpdf_formfield_unittest.cpp index 34c70caad2..eb7a5927e6 100644 --- a/core/fpdfdoc/cpdf_formfield_unittest.cpp +++ b/core/fpdfdoc/cpdf_formfield_unittest.cpp @@ -12,25 +12,29 @@ TEST(cpdf_formfield, FPDF_GetFullName) { EXPECT_TRUE(name.IsEmpty()); CPDF_IndirectObjectHolder obj_holder; - CPDF_Dictionary* root = new CPDF_Dictionary; + CPDF_Dictionary* root = + new CPDF_Dictionary(CFX_WeakPtr()); obj_holder.AddIndirectObject(root); root->SetNameFor("T", "foo"); name = FPDF_GetFullName(root); EXPECT_STREQ("foo", name.UTF8Encode().c_str()); - CPDF_Dictionary* dict1 = new CPDF_Dictionary; + CPDF_Dictionary* dict1 = + new CPDF_Dictionary(CFX_WeakPtr()); root->SetReferenceFor("Parent", &obj_holder, obj_holder.AddIndirectObject(dict1)); dict1->SetNameFor("T", "bar"); name = FPDF_GetFullName(root); EXPECT_STREQ("bar.foo", name.UTF8Encode().c_str()); - CPDF_Dictionary* dict2 = new CPDF_Dictionary; + CPDF_Dictionary* dict2 = + new CPDF_Dictionary(CFX_WeakPtr()); dict1->SetFor("Parent", dict2); name = FPDF_GetFullName(root); EXPECT_STREQ("bar.foo", name.UTF8Encode().c_str()); - CPDF_Dictionary* dict3 = new CPDF_Dictionary; + CPDF_Dictionary* dict3 = + new CPDF_Dictionary(CFX_WeakPtr()); dict2->SetReferenceFor("Parent", &obj_holder, obj_holder.AddIndirectObject(dict3)); dict3->SetNameFor("T", "qux"); diff --git a/core/fpdfdoc/cpdf_interform.cpp b/core/fpdfdoc/cpdf_interform.cpp index d2a842262e..29063f534b 100644 --- a/core/fpdfdoc/cpdf_interform.cpp +++ b/core/fpdfdoc/cpdf_interform.cpp @@ -58,7 +58,7 @@ void InitDict(CPDF_Dictionary*& pFormDict, CPDF_Document* pDocument) { return; if (!pFormDict) { - pFormDict = new CPDF_Dictionary; + pFormDict = new CPDF_Dictionary(pDocument->GetByteStringPool()); pDocument->GetRoot()->SetReferenceFor( "AcroForm", pDocument, pDocument->AddIndirectObject(pFormDict)); } @@ -259,12 +259,12 @@ void AddFont(CPDF_Dictionary*& pFormDict, CPDF_Dictionary* pDR = pFormDict->GetDictFor("DR"); if (!pDR) { - pDR = new CPDF_Dictionary; + pDR = new CPDF_Dictionary(pDocument->GetByteStringPool()); pFormDict->SetFor("DR", pDR); } CPDF_Dictionary* pFonts = pDR->GetDictFor("Font"); if (!pFonts) { - pFonts = new CPDF_Dictionary; + pFonts = new CPDF_Dictionary(pDocument->GetByteStringPool()); pDR->SetFor("Font", pFonts); } if (csNameTag.IsEmpty()) @@ -1212,7 +1212,7 @@ CFDF_Document* CPDF_InterForm::ExportToFDF( pMainDict->SetStringFor("F", CFX_ByteString::FromUnicode(wsFilePath)); pMainDict->SetStringFor("UF", PDF_EncodeText(wsFilePath)); } else { - CPDF_FileSpec filespec; + CPDF_FileSpec filespec(pDoc->GetByteStringPool()); filespec.SetFileName(pdf_path); pMainDict->SetFor("F", filespec.GetObj()); } @@ -1235,7 +1235,8 @@ CFDF_Document* CPDF_InterForm::ExportToFDF( continue; CFX_WideString fullname = FPDF_GetFullName(pField->GetFieldDict()); - CPDF_Dictionary* pFieldDict = new CPDF_Dictionary; + CPDF_Dictionary* pFieldDict = + new CPDF_Dictionary(pDoc->GetByteStringPool()); pFieldDict->SetFor("T", new CPDF_String(fullname)); if (pField->GetType() == CPDF_FormField::CheckBox || pField->GetType() == CPDF_FormField::RadioButton) { diff --git a/core/fpdfdoc/cpvt_generateap.cpp b/core/fpdfdoc/cpvt_generateap.cpp index f7ece9bc35..4c7a56352b 100644 --- a/core/fpdfdoc/cpvt_generateap.cpp +++ b/core/fpdfdoc/cpvt_generateap.cpp @@ -58,7 +58,7 @@ bool GenerateWidgetAP(CPDF_Document* pDoc, CPDF_Dictionary* pFontDict = pDRFontDict->GetDictFor(sFontName.Mid(1)); if (!pFontDict) { - pFontDict = new CPDF_Dictionary; + pFontDict = new CPDF_Dictionary(pDoc->GetByteStringPool()); pFontDict->SetNameFor("Type", "Font"); pFontDict->SetNameFor("Subtype", "Type1"); pFontDict->SetNameFor("BaseFont", "Helvetica"); @@ -163,7 +163,7 @@ bool GenerateWidgetAP(CPDF_Document* pDoc, rcBody.Normalize(); CPDF_Dictionary* pAPDict = pAnnotDict->GetDictFor("AP"); if (!pAPDict) { - pAPDict = new CPDF_Dictionary; + pAPDict = new CPDF_Dictionary(pDoc->GetByteStringPool()); pAnnotDict->SetFor("AP", pAPDict); } CPDF_Stream* pNormalStream = pAPDict->GetStreamFor("N"); @@ -179,7 +179,7 @@ bool GenerateWidgetAP(CPDF_Document* pDoc, if (pStreamResList) { CPDF_Dictionary* pStreamResFontList = pStreamResList->GetDictFor("Font"); if (!pStreamResFontList) { - pStreamResFontList = new CPDF_Dictionary; + pStreamResFontList = new CPDF_Dictionary(pDoc->GetByteStringPool()); pStreamResList->SetFor("Font", pStreamResFontList); } if (!pStreamResFontList->KeyExist(sFontName)) @@ -430,7 +430,7 @@ bool GenerateWidgetAP(CPDF_Document* pDoc, CPDF_Dictionary* pStreamResFontList = pStreamResList->GetDictFor("Font"); if (!pStreamResFontList) { - pStreamResFontList = new CPDF_Dictionary; + pStreamResFontList = new CPDF_Dictionary(pDoc->GetByteStringPool()); pStreamResList->SetFor("Font", pStreamResFontList); } if (!pStreamResFontList->KeyExist(sFontName)) @@ -540,7 +540,8 @@ CFX_ByteString GetPopupContentsString(CPDF_Document* pDoc, CPDF_Dictionary* GenerateExtGStateDict(const CPDF_Dictionary& pAnnotDict, const CFX_ByteString& sExtGSDictName, const CFX_ByteString& sBlendMode) { - CPDF_Dictionary* pGSDict = new CPDF_Dictionary; + CPDF_Dictionary* pGSDict = + new CPDF_Dictionary(pAnnotDict.GetByteStringPool()); pGSDict->SetStringFor("Type", "ExtGState"); FX_FLOAT fOpacity = @@ -550,31 +551,33 @@ CPDF_Dictionary* GenerateExtGStateDict(const CPDF_Dictionary& pAnnotDict, pGSDict->SetBooleanFor("AIS", false); pGSDict->SetStringFor("BM", sBlendMode); - CPDF_Dictionary* pExtGStateDict = new CPDF_Dictionary; + CPDF_Dictionary* pExtGStateDict = + new CPDF_Dictionary(pAnnotDict.GetByteStringPool()); pExtGStateDict->SetFor(sExtGSDictName, pGSDict); - return pExtGStateDict; } CPDF_Dictionary* GenerateResourceFontDict(CPDF_Document* pDoc, const CFX_ByteString& sFontDictName) { - CPDF_Dictionary* pFontDict = new CPDF_Dictionary; + CPDF_Dictionary* pFontDict = new CPDF_Dictionary(pDoc->GetByteStringPool()); pFontDict->SetNameFor("Type", "Font"); pFontDict->SetNameFor("Subtype", "Type1"); pFontDict->SetNameFor("BaseFont", "Helvetica"); pFontDict->SetNameFor("Encoding", "WinAnsiEncoding"); - CPDF_Dictionary* pResourceFontDict = new CPDF_Dictionary; + CPDF_Dictionary* pResourceFontDict = + new CPDF_Dictionary(pDoc->GetByteStringPool()); pResourceFontDict->SetReferenceFor(sFontDictName, pDoc, pDoc->AddIndirectObject(pFontDict)); - return pResourceFontDict; } // Takes ownership of |pExtGStateDict| and |pResourceFontDict|. -CPDF_Dictionary* GenerateResourceDict(CPDF_Dictionary* pExtGStateDict, +CPDF_Dictionary* GenerateResourceDict(CPDF_Document* pDoc, + CPDF_Dictionary* pExtGStateDict, CPDF_Dictionary* pResourceFontDict) { - CPDF_Dictionary* pResourceDict = new CPDF_Dictionary; + CPDF_Dictionary* pResourceDict = + new CPDF_Dictionary(pDoc->GetByteStringPool()); if (pExtGStateDict) pResourceDict->SetFor("ExtGState", pExtGStateDict); @@ -590,7 +593,7 @@ void GenerateAndSetAPDict(CPDF_Document* pDoc, const CFX_ByteTextBuf& sAppStream, CPDF_Dictionary* pResourceDict, bool bIsTextMarkupAnnotation) { - CPDF_Dictionary* pAPDict = new CPDF_Dictionary; + CPDF_Dictionary* pAPDict = new CPDF_Dictionary(pDoc->GetByteStringPool()); pAnnotDict->SetFor("AP", pAPDict); CPDF_Stream* pNormalStream = new CPDF_Stream; @@ -789,7 +792,7 @@ bool CPVT_GenerateAP::GenerateCircleAP(CPDF_Document* pDoc, CPDF_Dictionary* pExtGStateDict = GenerateExtGStateDict(*pAnnotDict, sExtGSDictName, "Normal"); CPDF_Dictionary* pResourceDict = - GenerateResourceDict(pExtGStateDict, nullptr); + GenerateResourceDict(pDoc, pExtGStateDict, nullptr); GenerateAndSetAPDict(pDoc, pAnnotDict, sAppStream, pResourceDict, false /*IsTextMarkupAnnotation*/); return true; @@ -816,7 +819,7 @@ bool CPVT_GenerateAP::GenerateHighlightAP(CPDF_Document* pDoc, CPDF_Dictionary* pExtGStateDict = GenerateExtGStateDict(*pAnnotDict, sExtGSDictName, "Multiply"); CPDF_Dictionary* pResourceDict = - GenerateResourceDict(pExtGStateDict, nullptr); + GenerateResourceDict(pDoc, pExtGStateDict, nullptr); GenerateAndSetAPDict(pDoc, pAnnotDict, sAppStream, pResourceDict, true /*IsTextMarkupAnnotation*/); @@ -871,7 +874,7 @@ bool CPVT_GenerateAP::GenerateInkAP(CPDF_Document* pDoc, CPDF_Dictionary* pExtGStateDict = GenerateExtGStateDict(*pAnnotDict, sExtGSDictName, "Normal"); CPDF_Dictionary* pResourceDict = - GenerateResourceDict(pExtGStateDict, nullptr); + GenerateResourceDict(pDoc, pExtGStateDict, nullptr); GenerateAndSetAPDict(pDoc, pAnnotDict, sAppStream, pResourceDict, false /*IsTextMarkupAnnotation*/); return true; @@ -894,7 +897,7 @@ bool CPVT_GenerateAP::GenerateTextAP(CPDF_Document* pDoc, CPDF_Dictionary* pExtGStateDict = GenerateExtGStateDict(*pAnnotDict, sExtGSDictName, "Normal"); CPDF_Dictionary* pResourceDict = - GenerateResourceDict(pExtGStateDict, nullptr); + GenerateResourceDict(pDoc, pExtGStateDict, nullptr); GenerateAndSetAPDict(pDoc, pAnnotDict, sAppStream, pResourceDict, false /*IsTextMarkupAnnotation*/); return true; @@ -921,7 +924,7 @@ bool CPVT_GenerateAP::GenerateUnderlineAP(CPDF_Document* pDoc, CPDF_Dictionary* pExtGStateDict = GenerateExtGStateDict(*pAnnotDict, sExtGSDictName, "Normal"); CPDF_Dictionary* pResourceDict = - GenerateResourceDict(pExtGStateDict, nullptr); + GenerateResourceDict(pDoc, pExtGStateDict, nullptr); GenerateAndSetAPDict(pDoc, pAnnotDict, sAppStream, pResourceDict, true /*IsTextMarkupAnnotation*/); return true; @@ -954,7 +957,7 @@ bool CPVT_GenerateAP::GeneratePopupAP(CPDF_Document* pDoc, CPDF_Dictionary* pResourceFontDict = GenerateResourceFontDict(pDoc, sFontName); CPDF_Dictionary* pResourceDict = - GenerateResourceDict(pResourceFontDict, pExtGStateDict); + GenerateResourceDict(pDoc, pResourceFontDict, pExtGStateDict); CPDF_Font* pDefFont = pDoc->LoadFont(pResourceFontDict); if (!pDefFont) @@ -1008,7 +1011,7 @@ bool CPVT_GenerateAP::GenerateSquareAP(CPDF_Document* pDoc, CPDF_Dictionary* pExtGStateDict = GenerateExtGStateDict(*pAnnotDict, sExtGSDictName, "Normal"); CPDF_Dictionary* pResourceDict = - GenerateResourceDict(pExtGStateDict, nullptr); + GenerateResourceDict(pDoc, pExtGStateDict, nullptr); GenerateAndSetAPDict(pDoc, pAnnotDict, sAppStream, pResourceDict, false /*IsTextMarkupAnnotation*/); return true; @@ -1057,7 +1060,7 @@ bool CPVT_GenerateAP::GenerateSquigglyAP(CPDF_Document* pDoc, CPDF_Dictionary* pExtGStateDict = GenerateExtGStateDict(*pAnnotDict, sExtGSDictName, "Normal"); CPDF_Dictionary* pResourceDict = - GenerateResourceDict(pExtGStateDict, nullptr); + GenerateResourceDict(pDoc, pExtGStateDict, nullptr); GenerateAndSetAPDict(pDoc, pAnnotDict, sAppStream, pResourceDict, true /*IsTextMarkupAnnotation*/); return true; @@ -1084,7 +1087,7 @@ bool CPVT_GenerateAP::GenerateStrikeOutAP(CPDF_Document* pDoc, CPDF_Dictionary* pExtGStateDict = GenerateExtGStateDict(*pAnnotDict, sExtGSDictName, "Normal"); CPDF_Dictionary* pResourceDict = - GenerateResourceDict(pExtGStateDict, nullptr); + GenerateResourceDict(pDoc, pExtGStateDict, nullptr); GenerateAndSetAPDict(pDoc, pAnnotDict, sAppStream, pResourceDict, true /*IsTextMarkupAnnotation*/); return true; diff --git a/core/fpdfdoc/include/cpdf_annot.h b/core/fpdfdoc/include/cpdf_annot.h index 43f58931d3..e88375a903 100644 --- a/core/fpdfdoc/include/cpdf_annot.h +++ b/core/fpdfdoc/include/cpdf_annot.h @@ -81,6 +81,8 @@ class CPDF_Annot { CFX_FloatRect GetRect() const; const CPDF_Dictionary* GetAnnotDict() const { return m_pAnnotDict; } CPDF_Dictionary* GetAnnotDict() { return m_pAnnotDict; } + CPDF_Document* GetDocument() const { return m_pDocument; } + FX_BOOL DrawAppearance(CPDF_Page* pPage, CFX_RenderDevice* pDevice, const CFX_Matrix* pUser2Device, @@ -90,6 +92,7 @@ class CPDF_Annot { CPDF_RenderContext* pContext, const CFX_Matrix* pUser2Device, AppearanceMode mode); + void ClearCachedAP(); void DrawBorder(CFX_RenderDevice* pDevice, const CFX_Matrix* pUser2Device, diff --git a/core/fpdfdoc/include/cpdf_filespec.h b/core/fpdfdoc/include/cpdf_filespec.h index 06badbaa5e..66f35fc202 100644 --- a/core/fpdfdoc/include/cpdf_filespec.h +++ b/core/fpdfdoc/include/cpdf_filespec.h @@ -7,13 +7,15 @@ #ifndef CORE_FPDFDOC_INCLUDE_CPDF_FILESPEC_H_ #define CORE_FPDFDOC_INCLUDE_CPDF_FILESPEC_H_ +#include "core/fxcrt/include/cfx_string_pool_template.h" +#include "core/fxcrt/include/cfx_weak_ptr.h" #include "core/fxcrt/include/fx_string.h" class CPDF_Object; class CPDF_FileSpec { public: - CPDF_FileSpec(); + explicit CPDF_FileSpec(const CFX_WeakPtr& pPool); explicit CPDF_FileSpec(CPDF_Object* pObj) : m_pObj(pObj) {} // Convert a platform dependent file name into pdf format. diff --git a/core/fxge/dib/fx_dib_engine_unittest.cpp b/core/fxge/dib/fx_dib_engine_unittest.cpp index 4b4063b7e5..0d0fdbdca7 100644 --- a/core/fxge/dib/fx_dib_engine_unittest.cpp +++ b/core/fxge/dib/fx_dib_engine_unittest.cpp @@ -16,7 +16,7 @@ TEST(CStretchEngine, OverflowInCtor) { FX_RECT clip_rect; std::unique_ptr> dict_obj( - new CPDF_Dictionary); + new CPDF_Dictionary(CFX_WeakPtr())); dict_obj->SetFor("Width", new CPDF_Number(71000)); dict_obj->SetFor("Height", new CPDF_Number(12500)); std::unique_ptr> stream( diff --git a/core/fxge/include/cfx_renderdevice.h b/core/fxge/include/cfx_renderdevice.h index 3b9c93fc9b..f790cdae68 100644 --- a/core/fxge/include/cfx_renderdevice.h +++ b/core/fxge/include/cfx_renderdevice.h @@ -212,16 +212,16 @@ class CFX_RenderDevice { uint32_t fill_color, uint32_t text_flags); FX_BOOL DrawTextPath(int nChars, - const FXTEXT_CHARPOS* pCharPos, - CFX_Font* pFont, - FX_FLOAT font_size, - const CFX_Matrix* pText2User, - const CFX_Matrix* pUser2Device, - const CFX_GraphStateData* pGraphState, - uint32_t fill_color, - uint32_t stroke_color, - CFX_PathData* pClippingPath, - int nFlag); + const FXTEXT_CHARPOS* pCharPos, + CFX_Font* pFont, + FX_FLOAT font_size, + const CFX_Matrix* pText2User, + const CFX_Matrix* pUser2Device, + const CFX_GraphStateData* pGraphState, + uint32_t fill_color, + uint32_t stroke_color, + CFX_PathData* pClippingPath, + int nFlag); #ifdef _SKIA_SUPPORT_ virtual void DebugVerifyBitmapIsPreMultiplied() const; -- cgit v1.2.3