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 ++++ 19 files changed, 163 insertions(+), 89 deletions(-) (limited to 'core/fpdfapi') 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_ -- cgit v1.2.3