diff options
author | tsepez <tsepez@chromium.org> | 2016-11-07 13:49:17 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-11-07 13:49:17 -0800 |
commit | 5ab31ef3ed4c86211f1ebb3686abb4f5a66472ec (patch) | |
tree | 87c1fda94151528b7fcfa3a18cfda87a78cd3b4f | |
parent | c09625ca59701fabeb49dc59edcf33031b2c6672 (diff) | |
download | pdfium-5ab31ef3ed4c86211f1ebb3686abb4f5a66472ec.tar.xz |
Use unique_ptr return from CPDF_Parser::ParseIndirectObject()
In turn, propgate to callers. This introduces a few
release() calls that will go away as more code is converted.
It also removes a couple of WrapUnique calls that are no
longer needed as ownership of the object flows along.
Review-Url: https://codereview.chromium.org/2479303002
-rw-r--r-- | core/fpdfapi/parser/cfdf_document.cpp | 12 | ||||
-rw-r--r-- | core/fpdfapi/parser/cpdf_boolean.h | 5 | ||||
-rw-r--r-- | core/fpdfapi/parser/cpdf_data_avail.cpp | 118 | ||||
-rw-r--r-- | core/fpdfapi/parser/cpdf_data_avail.h | 12 | ||||
-rw-r--r-- | core/fpdfapi/parser/cpdf_document.cpp | 3 | ||||
-rw-r--r-- | core/fpdfapi/parser/cpdf_document.h | 2 | ||||
-rw-r--r-- | core/fpdfapi/parser/cpdf_indirect_object_holder.cpp | 13 | ||||
-rw-r--r-- | core/fpdfapi/parser/cpdf_indirect_object_holder.h | 2 | ||||
-rw-r--r-- | core/fpdfapi/parser/cpdf_name.h | 5 | ||||
-rw-r--r-- | core/fpdfapi/parser/cpdf_parser.cpp | 38 | ||||
-rw-r--r-- | core/fpdfapi/parser/cpdf_parser.h | 14 | ||||
-rw-r--r-- | core/fpdfapi/parser/cpdf_reference.h | 4 | ||||
-rw-r--r-- | core/fpdfapi/parser/cpdf_syntax_parser.cpp | 109 | ||||
-rw-r--r-- | core/fpdfapi/parser/cpdf_syntax_parser.h | 29 |
14 files changed, 163 insertions, 203 deletions
diff --git a/core/fpdfapi/parser/cfdf_document.cpp b/core/fpdfapi/parser/cfdf_document.cpp index a0f3e1490d..f54e598506 100644 --- a/core/fpdfapi/parser/cfdf_document.cpp +++ b/core/fpdfapi/parser/cfdf_document.cpp @@ -69,8 +69,8 @@ void CFDF_Document::ParseStream(IFX_SeekableReadStream* pFile, bool bOwnFile) { if (word != "obj") break; - auto pObj = pdfium::WrapUnique<CPDF_Object>( - parser.GetObject(this, objnum, 0, true)); + std::unique_ptr<CPDF_Object> pObj = + parser.GetObject(this, objnum, 0, true); if (!pObj) break; @@ -82,11 +82,11 @@ void CFDF_Document::ParseStream(IFX_SeekableReadStream* pFile, bool bOwnFile) { if (word != "trailer") break; - if (CPDF_Dictionary* pMainDict = - ToDictionary(parser.GetObject(this, 0, 0, true))) { + std::unique_ptr<CPDF_Dictionary> pMainDict = + ToDictionary(parser.GetObject(this, 0, 0, true)); + if (pMainDict) m_pRootDict = pMainDict->GetDictFor("Root"); - delete pMainDict; - } + break; } } diff --git a/core/fpdfapi/parser/cpdf_boolean.h b/core/fpdfapi/parser/cpdf_boolean.h index 91b99f6dd2..bc864a6ab8 100644 --- a/core/fpdfapi/parser/cpdf_boolean.h +++ b/core/fpdfapi/parser/cpdf_boolean.h @@ -15,8 +15,9 @@ class CPDF_Boolean : public CPDF_Object { public: CPDF_Boolean(); explicit CPDF_Boolean(bool value); + ~CPDF_Boolean() override; - // CPDF_Object. + // CPDF_Object: Type GetType() const override; CPDF_Object* Clone() const override; CFX_ByteString GetString() const override; @@ -27,8 +28,6 @@ class CPDF_Boolean : public CPDF_Object { const CPDF_Boolean* AsBoolean() const override; protected: - ~CPDF_Boolean() override; - bool m_bValue; }; diff --git a/core/fpdfapi/parser/cpdf_data_avail.cpp b/core/fpdfapi/parser/cpdf_data_avail.cpp index 1f43a4bdfe..3fe4b03da6 100644 --- a/core/fpdfapi/parser/cpdf_data_avail.cpp +++ b/core/fpdfapi/parser/cpdf_data_avail.cpp @@ -23,6 +23,7 @@ #include "core/fpdfapi/parser/fpdf_parser_utility.h" #include "core/fxcrt/fx_ext.h" #include "core/fxcrt/fx_safe_types.h" +#include "third_party/base/numerics/safe_conversions.h" #include "third_party/base/stl_util.h" CPDF_DataAvail::FileAvail::~FileAvail() {} @@ -65,7 +66,6 @@ CPDF_DataAvail::CPDF_DataAvail(FileAvail* pFileAvail, m_bPageLoadedOK = false; m_bNeedDownLoadResource = false; m_bLinearizedFormParamLoad = false; - m_pRoot = nullptr; m_pTrailer = nullptr; m_pCurrentParser = nullptr; m_pAcroForm = nullptr; @@ -81,7 +81,6 @@ CPDF_DataAvail::CPDF_DataAvail(FileAvail* pFileAvail, CPDF_DataAvail::~CPDF_DataAvail() { m_pHintTables.reset(); - for (CPDF_Object* pObject : m_arrayAcroforms) delete pObject; } @@ -228,7 +227,7 @@ bool CPDF_DataAvail::CheckAcroFormSubObject(DownloadHints* pHints) { bool CPDF_DataAvail::CheckAcroForm(DownloadHints* pHints) { bool bExist = false; - m_pAcroForm = GetObject(m_dwAcroFormObjNum, pHints, &bExist); + m_pAcroForm = GetObject(m_dwAcroFormObjNum, pHints, &bExist).release(); if (!bExist) { m_docStatus = PDF_DATAAVAIL_PAGETREE; return true; @@ -338,10 +337,9 @@ bool CPDF_DataAvail::LoadAllXref(DownloadHints* pHints) { return true; } -CPDF_Object* CPDF_DataAvail::GetObject(uint32_t objnum, - DownloadHints* pHints, - bool* pExistInFile) { - CPDF_Object* pRet = nullptr; +std::unique_ptr<CPDF_Object> CPDF_DataAvail::GetObject(uint32_t objnum, + DownloadHints* pHints, + bool* pExistInFile) { uint32_t size = 0; FX_FILESIZE offset = 0; CPDF_Parser* pParser = nullptr; @@ -361,6 +359,7 @@ CPDF_Object* CPDF_DataAvail::GetObject(uint32_t objnum, if (!IsDataAvail(offset, size, pHints)) return nullptr; + std::unique_ptr<CPDF_Object> pRet; if (pParser) pRet = pParser->ParseIndirectObject(nullptr, objnum); @@ -372,28 +371,19 @@ CPDF_Object* CPDF_DataAvail::GetObject(uint32_t objnum, bool CPDF_DataAvail::CheckInfo(DownloadHints* pHints) { bool bExist = false; - CPDF_Object* pInfo = GetObject(m_dwInfoObjNum, pHints, &bExist); - if (!bExist) { - m_docStatus = - (m_bHaveAcroForm ? PDF_DATAAVAIL_ACROFORM : PDF_DATAAVAIL_PAGETREE); - return true; - } - - if (!pInfo) { + std::unique_ptr<CPDF_Object> pInfo = + GetObject(m_dwInfoObjNum, pHints, &bExist); + if (bExist && !pInfo) { if (m_docStatus == PDF_DATAAVAIL_ERROR) { m_docStatus = PDF_DATAAVAIL_LOADALLFILE; return true; } - if (m_Pos == m_dwFileLen) m_docStatus = PDF_DATAAVAIL_ERROR; return false; } - - delete pInfo; m_docStatus = - (m_bHaveAcroForm ? PDF_DATAAVAIL_ACROFORM : PDF_DATAAVAIL_PAGETREE); - + m_bHaveAcroForm ? PDF_DATAAVAIL_ACROFORM : PDF_DATAAVAIL_PAGETREE; return true; } @@ -471,14 +461,15 @@ bool CPDF_DataAvail::CheckPage(DownloadHints* pHints) { for (uint32_t i = 0; i < iPageObjs; ++i) { uint32_t dwPageObjNum = m_PageObjList.GetAt(i); bool bExist = false; - CPDF_Object* pObj = GetObject(dwPageObjNum, pHints, &bExist); + std::unique_ptr<CPDF_Object> pObj = + GetObject(dwPageObjNum, pHints, &bExist); if (!pObj) { if (bExist) UnavailObjList.Add(dwPageObjNum); continue; } - CPDF_Array* pArray = ToArray(pObj); + CPDF_Array* pArray = ToArray(pObj.get()); if (pArray) { for (CPDF_Object* pArrayObj : *pArray) { if (CPDF_Reference* pRef = ToReference(pArrayObj)) @@ -487,16 +478,14 @@ bool CPDF_DataAvail::CheckPage(DownloadHints* pHints) { } if (!pObj->IsDictionary()) { - delete pObj; continue; } CFX_ByteString type = pObj->GetDict()->GetStringFor("Type"); if (type == "Pages") { - m_PagesArray.push_back(pObj); + m_PagesArray.push_back(std::move(pObj)); continue; } - delete pObj; } m_PageObjList.RemoveAll(); @@ -507,25 +496,17 @@ bool CPDF_DataAvail::CheckPage(DownloadHints* pHints) { uint32_t iPages = m_PagesArray.size(); for (uint32_t i = 0; i < iPages; i++) { - CPDF_Object* pPages = m_PagesArray[i]; - if (!pPages) - continue; - - if (!GetPageKids(m_pCurrentParser, pPages)) { - delete pPages; - while (++i < iPages) - delete m_PagesArray[i]; - + std::unique_ptr<CPDF_Object> pPages = std::move(m_PagesArray[i]); + if (pPages && !GetPageKids(m_pCurrentParser, pPages.get())) { m_PagesArray.clear(); m_docStatus = PDF_DATAAVAIL_ERROR; return false; } - delete pPages; } - m_PagesArray.clear(); if (!m_PageObjList.GetSize()) m_docStatus = PDF_DATAAVAIL_DONE; + return true; } @@ -560,7 +541,8 @@ bool CPDF_DataAvail::GetPageKids(CPDF_Parser* pParser, CPDF_Object* pPages) { bool CPDF_DataAvail::CheckPages(DownloadHints* pHints) { bool bExist = false; - CPDF_Object* pPages = GetObject(m_PagesObjNum, pHints, &bExist); + std::unique_ptr<CPDF_Object> pPages = + GetObject(m_PagesObjNum, pHints, &bExist); if (!bExist) { m_docStatus = PDF_DATAAVAIL_LOADALLFILE; return true; @@ -574,13 +556,11 @@ bool CPDF_DataAvail::CheckPages(DownloadHints* pHints) { return false; } - if (!GetPageKids(m_pCurrentParser, pPages)) { - delete pPages; + if (!GetPageKids(m_pCurrentParser, pPages.get())) { m_docStatus = PDF_DATAAVAIL_ERROR; return false; } - delete pPages; m_docStatus = PDF_DATAAVAIL_PAGE; return true; } @@ -705,7 +685,7 @@ bool CPDF_DataAvail::CheckHintTables(DownloadHints* pHints) { return true; } -CPDF_Object* CPDF_DataAvail::ParseIndirectObjectAt( +std::unique_ptr<CPDF_Object> CPDF_DataAvail::ParseIndirectObjectAt( FX_FILESIZE pos, uint32_t objnum, CPDF_IndirectObjectHolder* pObjList) { @@ -731,7 +711,7 @@ CPDF_Object* CPDF_DataAvail::ParseIndirectObjectAt( return nullptr; } - CPDF_Object* pObj = + std::unique_ptr<CPDF_Object> pObj = m_syntaxParser.GetObject(pObjList, parser_objnum, gennum, true); m_syntaxParser.RestorePos(SavedPos); return pObj; @@ -766,7 +746,6 @@ bool CPDF_DataAvail::IsLinearizedFile(uint8_t* pData, uint32_t dwLen) { return true; ScopedFileStream file(FX_CreateMemoryStream(pData, (size_t)dwLen, false)); - int32_t offset = GetHeaderOffset(file.get()); if (offset == -1) { m_docStatus = PDF_DATAAVAIL_ERROR; @@ -783,8 +762,8 @@ bool CPDF_DataAvail::IsLinearizedFile(uint8_t* pData, uint32_t dwLen) { return false; uint32_t objnum = FXSYS_atoui(wordObjNum.c_str()); - m_pLinearized = CPDF_LinearizedHeader::CreateForObject(pdfium::WrapUnique( - ParseIndirectObjectAt(m_syntaxParser.m_HeaderOffset + 9, objnum))); + m_pLinearized = CPDF_LinearizedHeader::CreateForObject( + ParseIndirectObjectAt(m_syntaxParser.m_HeaderOffset + 9, objnum)); if (!m_pLinearized || m_pLinearized->GetFileSize() != m_pFileRead->GetSize()) { m_pLinearized.reset(); @@ -857,7 +836,9 @@ int32_t CPDF_DataAvail::CheckCrossRefStream(DownloadHints* pHints, return -1; uint32_t objNum = FXSYS_atoui(objnum.c_str()); - CPDF_Object* pObj = m_parser.ParseIndirectObjectAt(nullptr, 0, objNum); + std::unique_ptr<CPDF_Object> pObj = + m_parser.ParseIndirectObjectAt(nullptr, 0, objNum); + if (!pObj) { m_Pos += m_parser.m_pSyntax->SavePos(); return 0; @@ -865,15 +846,11 @@ int32_t CPDF_DataAvail::CheckCrossRefStream(DownloadHints* pHints, CPDF_Dictionary* pDict = pObj->GetDict(); CPDF_Name* pName = ToName(pDict ? pDict->GetObjectFor("Type") : nullptr); - if (pName) { - if (pName->GetString() == "XRef") { - m_Pos += m_parser.m_pSyntax->SavePos(); - xref_offset = pObj->GetDict()->GetIntegerFor("Prev"); - delete pObj; - return 1; - } + if (pName && pName->GetString() == "XRef") { + m_Pos += m_parser.m_pSyntax->SavePos(); + xref_offset = pObj->GetDict()->GetIntegerFor("Prev"); + return 1; } - delete pObj; return -1; } pHints->AddSegment(m_Pos, req_size); @@ -1168,7 +1145,7 @@ bool CPDF_DataAvail::CheckArrayPageNode(uint32_t dwPageNo, PageNode* pPageNode, DownloadHints* pHints) { bool bExist = false; - CPDF_Object* pPages = GetObject(dwPageNo, pHints, &bExist); + std::unique_ptr<CPDF_Object> pPages = GetObject(dwPageNo, pHints, &bExist); if (!bExist) { m_docStatus = PDF_DATAAVAIL_ERROR; return false; @@ -1184,7 +1161,6 @@ bool CPDF_DataAvail::CheckArrayPageNode(uint32_t dwPageNo, CPDF_Array* pArray = pPages->AsArray(); if (!pArray) { - delete pPages; m_docStatus = PDF_DATAAVAIL_ERROR; return false; } @@ -1199,7 +1175,6 @@ bool CPDF_DataAvail::CheckArrayPageNode(uint32_t dwPageNo, pPageNode->m_childNode.Add(pNode); pNode->m_dwPageNo = pKid->GetRefObjNum(); } - delete pPages; return true; } @@ -1207,7 +1182,7 @@ bool CPDF_DataAvail::CheckUnkownPageNode(uint32_t dwPageNo, PageNode* pPageNode, DownloadHints* pHints) { bool bExist = false; - CPDF_Object* pPage = GetObject(dwPageNo, pHints, &bExist); + std::unique_ptr<CPDF_Object> pPage = GetObject(dwPageNo, pHints, &bExist); if (!bExist) { m_docStatus = PDF_DATAAVAIL_ERROR; return false; @@ -1222,12 +1197,10 @@ bool CPDF_DataAvail::CheckUnkownPageNode(uint32_t dwPageNo, if (pPage->IsArray()) { pPageNode->m_dwPageNo = dwPageNo; pPageNode->m_type = PDF_PAGENODE_ARRAY; - delete pPage; return true; } if (!pPage->IsDictionary()) { - delete pPage; m_docStatus = PDF_DATAAVAIL_ERROR; return false; } @@ -1268,11 +1241,9 @@ bool CPDF_DataAvail::CheckUnkownPageNode(uint32_t dwPageNo, } else if (type == "Page") { pPageNode->m_type = PDF_PAGENODE_PAGE; } else { - delete pPage; m_docStatus = PDF_DATAAVAIL_ERROR; return false; } - delete pPage; return true; } @@ -1349,7 +1320,8 @@ bool CPDF_DataAvail::LoadDocPage(uint32_t dwPage, DownloadHints* pHints) { bool CPDF_DataAvail::CheckPageCount(DownloadHints* pHints) { bool bExist = false; - CPDF_Object* pPages = GetObject(m_PagesObjNum, pHints, &bExist); + std::unique_ptr<CPDF_Object> pPages = + GetObject(m_PagesObjNum, pHints, &bExist); if (!bExist) { m_docStatus = PDF_DATAAVAIL_ERROR; return false; @@ -1360,24 +1332,14 @@ bool CPDF_DataAvail::CheckPageCount(DownloadHints* pHints) { CPDF_Dictionary* pPagesDict = pPages->GetDict(); if (!pPagesDict) { - delete pPages; m_docStatus = PDF_DATAAVAIL_ERROR; return false; } - if (!pPagesDict->KeyExist("Kids")) { - delete pPages; + if (!pPagesDict->KeyExist("Kids")) return true; - } - - int count = pPagesDict->GetIntegerFor("Count"); - if (count > 0) { - delete pPages; - return true; - } - delete pPages; - return false; + return pPagesDict->GetIntegerFor("Count") > 0; } bool CPDF_DataAvail::LoadDocPages(DownloadHints* pHints) { @@ -1683,10 +1645,10 @@ CPDF_Dictionary* CPDF_DataAvail::GetPage(int index) { m_pDocument->SetPageObjNum(index, dwObjNum); // Page object already can be parsed in document. if (!m_pDocument->GetIndirectObject(dwObjNum)) { - m_syntaxParser.InitParser(m_pFileRead, (uint32_t)szPageStartPos); + m_syntaxParser.InitParser( + m_pFileRead, pdfium::base::checked_cast<uint32_t>(szPageStartPos)); m_pDocument->ReplaceIndirectObjectIfHigherGeneration( - dwObjNum, pdfium::WrapUnique<CPDF_Object>( - ParseIndirectObjectAt(0, dwObjNum, m_pDocument))); + dwObjNum, ParseIndirectObjectAt(0, dwObjNum, m_pDocument)); } return m_pDocument->GetPage(index); } diff --git a/core/fpdfapi/parser/cpdf_data_avail.h b/core/fpdfapi/parser/cpdf_data_avail.h index e4fc7bad8b..250064f38a 100644 --- a/core/fpdfapi/parser/cpdf_data_avail.h +++ b/core/fpdfapi/parser/cpdf_data_avail.h @@ -156,13 +156,13 @@ class CPDF_DataAvail final { void SetStartOffset(FX_FILESIZE dwOffset); bool GetNextToken(CFX_ByteString& token); bool GetNextChar(uint8_t& ch); - CPDF_Object* ParseIndirectObjectAt( + std::unique_ptr<CPDF_Object> ParseIndirectObjectAt( FX_FILESIZE pos, uint32_t objnum, CPDF_IndirectObjectHolder* pObjList = nullptr); - CPDF_Object* GetObject(uint32_t objnum, - DownloadHints* pHints, - bool* pExistInFile); + std::unique_ptr<CPDF_Object> GetObject(uint32_t objnum, + DownloadHints* pHints, + bool* pExistInFile); bool GetPageKids(CPDF_Parser* pParser, CPDF_Object* pPages); bool PreparePageItem(); bool LoadPages(DownloadHints* pHints); @@ -197,7 +197,7 @@ class CPDF_DataAvail final { IFX_SeekableReadStream* const m_pFileRead; CPDF_Parser m_parser; CPDF_SyntaxParser m_syntaxParser; - CPDF_Object* m_pRoot; + std::unique_ptr<CPDF_Object> m_pRoot; uint32_t m_dwRootObjNum; uint32_t m_dwInfoObjNum; std::unique_ptr<CPDF_LinearizedHeader> m_pLinearized; @@ -239,7 +239,7 @@ class CPDF_DataAvail final { bool m_bNeedDownLoadResource; bool m_bPageLoadedOK; bool m_bLinearizedFormParamLoad; - std::vector<CPDF_Object*> m_PagesArray; + std::vector<std::unique_ptr<CPDF_Object>> m_PagesArray; uint32_t m_dwEncryptObjNum; FX_FILESIZE m_dwPrevXRefOffset; bool m_bTotalLoadPageTree; diff --git a/core/fpdfapi/parser/cpdf_document.cpp b/core/fpdfapi/parser/cpdf_document.cpp index eb2ab554c7..1c73ce1015 100644 --- a/core/fpdfapi/parser/cpdf_document.cpp +++ b/core/fpdfapi/parser/cpdf_document.cpp @@ -354,7 +354,8 @@ CPDF_Document::~CPDF_Document() { m_pByteStringPool.DeleteObject(); // Make weak. } -CPDF_Object* CPDF_Document::ParseIndirectObject(uint32_t objnum) { +std::unique_ptr<CPDF_Object> CPDF_Document::ParseIndirectObject( + uint32_t objnum) { return m_pParser ? m_pParser->ParseIndirectObject(this, objnum) : nullptr; } diff --git a/core/fpdfapi/parser/cpdf_document.h b/core/fpdfapi/parser/cpdf_document.h index cf1bcae6b5..fce84001b9 100644 --- a/core/fpdfapi/parser/cpdf_document.h +++ b/core/fpdfapi/parser/cpdf_document.h @@ -113,7 +113,7 @@ class CPDF_Document : public CPDF_IndirectObjectHolder { uint32_t objnum, int& index, int level = 0); - CPDF_Object* ParseIndirectObject(uint32_t objnum) override; + std::unique_ptr<CPDF_Object> ParseIndirectObject(uint32_t objnum) override; void LoadDocInternal(); size_t CalculateEncodingDict(int charset, CPDF_Dictionary* pBaseDict); CPDF_Dictionary* GetPagesDict() const; diff --git a/core/fpdfapi/parser/cpdf_indirect_object_holder.cpp b/core/fpdfapi/parser/cpdf_indirect_object_holder.cpp index b2cb08c08a..529eda21fb 100644 --- a/core/fpdfapi/parser/cpdf_indirect_object_holder.cpp +++ b/core/fpdfapi/parser/cpdf_indirect_object_holder.cpp @@ -28,17 +28,18 @@ CPDF_Object* CPDF_IndirectObjectHolder::GetOrParseIndirectObject( if (pObj) return pObj->GetObjNum() != CPDF_Object::kInvalidObjNum ? pObj : nullptr; - pObj = ParseIndirectObject(objnum); - if (!pObj) + std::unique_ptr<CPDF_Object> pNewObj = ParseIndirectObject(objnum); + if (!pNewObj) return nullptr; - pObj->m_ObjNum = objnum; + pNewObj->m_ObjNum = objnum; m_LastObjNum = std::max(m_LastObjNum, objnum); - m_IndirectObjs[objnum].reset(pObj); - return pObj; + m_IndirectObjs[objnum] = std::move(pNewObj); + return m_IndirectObjs[objnum].get(); } -CPDF_Object* CPDF_IndirectObjectHolder::ParseIndirectObject(uint32_t objnum) { +std::unique_ptr<CPDF_Object> CPDF_IndirectObjectHolder::ParseIndirectObject( + uint32_t objnum) { return nullptr; } diff --git a/core/fpdfapi/parser/cpdf_indirect_object_holder.h b/core/fpdfapi/parser/cpdf_indirect_object_holder.h index fcd77215eb..db6f4acbf4 100644 --- a/core/fpdfapi/parser/cpdf_indirect_object_holder.h +++ b/core/fpdfapi/parser/cpdf_indirect_object_holder.h @@ -39,7 +39,7 @@ class CPDF_IndirectObjectHolder { const_iterator end() const { return m_IndirectObjs.end(); } protected: - virtual CPDF_Object* ParseIndirectObject(uint32_t objnum); + virtual std::unique_ptr<CPDF_Object> ParseIndirectObject(uint32_t objnum); private: uint32_t m_LastObjNum; diff --git a/core/fpdfapi/parser/cpdf_name.h b/core/fpdfapi/parser/cpdf_name.h index cfc2fe641a..aea1de4f83 100644 --- a/core/fpdfapi/parser/cpdf_name.h +++ b/core/fpdfapi/parser/cpdf_name.h @@ -12,8 +12,9 @@ class CPDF_Name : public CPDF_Object { public: explicit CPDF_Name(const CFX_ByteString& str); + ~CPDF_Name() override; - // CPDF_Object. + // CPDF_Object: Type GetType() const override; CPDF_Object* Clone() const override; CFX_ByteString GetString() const override; @@ -24,8 +25,6 @@ class CPDF_Name : public CPDF_Object { const CPDF_Name* AsName() const override; protected: - ~CPDF_Name() override; - CFX_ByteString m_Name; }; diff --git a/core/fpdfapi/parser/cpdf_parser.cpp b/core/fpdfapi/parser/cpdf_parser.cpp index 74136efbd8..905f36622a 100644 --- a/core/fpdfapi/parser/cpdf_parser.cpp +++ b/core/fpdfapi/parser/cpdf_parser.cpp @@ -731,9 +731,10 @@ bool CPDF_Parser::RebuildCrossRef() { m_SortedOffset.insert(obj_pos); last_obj = start_pos; FX_FILESIZE obj_end = 0; - CPDF_Object* pObject = ParseIndirectObjectAtByStrict( - m_pDocument, obj_pos, objnum, &obj_end); - if (CPDF_Stream* pStream = ToStream(pObject)) { + std::unique_ptr<CPDF_Object> pObject = + ParseIndirectObjectAtByStrict(m_pDocument, obj_pos, objnum, + &obj_end); + if (CPDF_Stream* pStream = ToStream(pObject.get())) { if (CPDF_Dictionary* pDict = pStream->GetDict()) { if ((pDict->KeyExist("Type")) && (pDict->GetStringFor("Type") == "XRef" && @@ -778,8 +779,6 @@ bool CPDF_Parser::RebuildCrossRef() { m_ObjectInfo[objnum].type = 1; m_ObjectInfo[objnum].gennum = gennum; } - - delete pObject; } --i; state = ParserState::kDefault; @@ -793,11 +792,10 @@ bool CPDF_Parser::RebuildCrossRef() { last_trailer = pos + i - 7; m_pSyntax->RestorePos(pos + i - m_pSyntax->m_HeaderOffset); - CPDF_Object* pObj = m_pSyntax->GetObject(m_pDocument, 0, 0, true); + std::unique_ptr<CPDF_Object> pObj = + m_pSyntax->GetObject(m_pDocument, 0, 0, true); if (pObj) { - if (!pObj->IsDictionary() && !pObj->AsStream()) { - delete pObj; - } else { + if (pObj->IsDictionary() || pObj->AsStream()) { CPDF_Stream* pStream = pObj->AsStream(); if (CPDF_Dictionary* pTrailer = pStream ? pStream->GetDict() : pObj->AsDictionary()) { @@ -822,12 +820,11 @@ bool CPDF_Parser::RebuildCrossRef() { } } } - delete pObj; } else { if (pObj->IsStream()) { m_pTrailer = ToDictionary(pTrailer->Clone()); - delete pObj; } else { + pObj.release(); m_pTrailer = pTrailer; } @@ -842,8 +839,6 @@ bool CPDF_Parser::RebuildCrossRef() { } m_pSyntax->RestorePos(dwSavePos); } - } else { - delete pObj; } } } @@ -1087,7 +1082,7 @@ CPDF_Array* CPDF_Parser::GetIDArray() { return nullptr; if (CPDF_Reference* pRef = pID->AsReference()) { - pID = ParseIndirectObject(nullptr, pRef->GetRefObjNum()); + pID = ParseIndirectObject(nullptr, pRef->GetRefObjNum()).release(); m_pTrailer->SetFor("ID", pID); } return ToArray(pID); @@ -1105,7 +1100,7 @@ uint32_t CPDF_Parser::GetInfoObjNum() { return pRef ? pRef->GetRefObjNum() : 0; } -CPDF_Object* CPDF_Parser::ParseIndirectObject( +std::unique_ptr<CPDF_Object> CPDF_Parser::ParseIndirectObject( CPDF_IndirectObjectHolder* pObjList, uint32_t objnum) { if (!IsValidObjectNumber(objnum)) @@ -1308,7 +1303,7 @@ void CPDF_Parser::GetIndirectBinary(uint32_t objnum, m_pSyntax->RestorePos(SavedPos); } -CPDF_Object* CPDF_Parser::ParseIndirectObjectAt( +std::unique_ptr<CPDF_Object> CPDF_Parser::ParseIndirectObjectAt( CPDF_IndirectObjectHolder* pObjList, FX_FILESIZE pos, uint32_t objnum) { @@ -1341,7 +1336,7 @@ CPDF_Object* CPDF_Parser::ParseIndirectObjectAt( return nullptr; } - CPDF_Object* pObj = + std::unique_ptr<CPDF_Object> pObj = m_pSyntax->GetObject(pObjList, objnum, parser_gennum, true); m_pSyntax->SavePos(); @@ -1358,7 +1353,7 @@ CPDF_Object* CPDF_Parser::ParseIndirectObjectAt( return pObj; } -CPDF_Object* CPDF_Parser::ParseIndirectObjectAtByStrict( +std::unique_ptr<CPDF_Object> CPDF_Parser::ParseIndirectObjectAtByStrict( CPDF_IndirectObjectHolder* pObjList, FX_FILESIZE pos, uint32_t objnum, @@ -1391,7 +1386,9 @@ CPDF_Object* CPDF_Parser::ParseIndirectObjectAtByStrict( return nullptr; } - CPDF_Object* pObj = m_pSyntax->GetObjectForStrict(pObjList, objnum, gennum); + std::unique_ptr<CPDF_Object> pObj = + m_pSyntax->GetObjectForStrict(pObjList, objnum, gennum); + if (pResultPos) *pResultPos = m_pSyntax->m_Pos; @@ -1450,9 +1447,10 @@ bool CPDF_Parser::IsLinearizedFile(IFX_SeekableReadStream* pFileAccess, } m_pLinearized = CPDF_LinearizedHeader::CreateForObject( - pdfium::WrapUnique(m_pSyntax->GetObject(nullptr, objnum, gennum, true))); + m_pSyntax->GetObject(nullptr, objnum, gennum, true)); if (!m_pLinearized) return false; + m_LastXRefOffset = m_pLinearized->GetLastXRefOffset(); // Move parser onto first page xref table start. m_pSyntax->GetNextWord(nullptr); diff --git a/core/fpdfapi/parser/cpdf_parser.h b/core/fpdfapi/parser/cpdf_parser.h index faac6c5195..007193b3ea 100644 --- a/core/fpdfapi/parser/cpdf_parser.h +++ b/core/fpdfapi/parser/cpdf_parser.h @@ -59,8 +59,9 @@ class CPDF_Parser { CPDF_Dictionary* GetEncryptDict() const { return m_pEncryptDict; } - CPDF_Object* ParseIndirectObject(CPDF_IndirectObjectHolder* pObjList, - uint32_t objnum); + std::unique_ptr<CPDF_Object> ParseIndirectObject( + CPDF_IndirectObjectHolder* pObjList, + uint32_t objnum); uint32_t GetLastObjNum() const; bool IsValidObjectNumber(uint32_t objnum) const; @@ -79,11 +80,12 @@ class CPDF_Parser { int GetFileVersion() const { return m_FileVersion; } bool IsXRefStream() const { return m_bXRefStream; } - CPDF_Object* ParseIndirectObjectAt(CPDF_IndirectObjectHolder* pObjList, - FX_FILESIZE pos, - uint32_t objnum); + std::unique_ptr<CPDF_Object> ParseIndirectObjectAt( + CPDF_IndirectObjectHolder* pObjList, + FX_FILESIZE pos, + uint32_t objnum); - CPDF_Object* ParseIndirectObjectAtByStrict( + std::unique_ptr<CPDF_Object> ParseIndirectObjectAtByStrict( CPDF_IndirectObjectHolder* pObjList, FX_FILESIZE pos, uint32_t objnum, diff --git a/core/fpdfapi/parser/cpdf_reference.h b/core/fpdfapi/parser/cpdf_reference.h index 5221832f80..20516ae567 100644 --- a/core/fpdfapi/parser/cpdf_reference.h +++ b/core/fpdfapi/parser/cpdf_reference.h @@ -16,6 +16,7 @@ class CPDF_IndirectObjectHolder; class CPDF_Reference : public CPDF_Object { public: CPDF_Reference(CPDF_IndirectObjectHolder* pDoc, int objnum); + ~CPDF_Reference() override; // CPDF_Object. Type GetType() const override; @@ -35,12 +36,9 @@ class CPDF_Reference : public CPDF_Object { void SetRef(CPDF_IndirectObjectHolder* pDoc, uint32_t objnum); protected: - ~CPDF_Reference() override; - CPDF_Object* CloneNonCyclic( bool bDirect, std::set<const CPDF_Object*>* pVisited) const override; - CPDF_Object* SafeGetDirect() const; CPDF_IndirectObjectHolder* m_pObjList; diff --git a/core/fpdfapi/parser/cpdf_syntax_parser.cpp b/core/fpdfapi/parser/cpdf_syntax_parser.cpp index da3c8b0c79..842ef2b222 100644 --- a/core/fpdfapi/parser/cpdf_syntax_parser.cpp +++ b/core/fpdfapi/parser/cpdf_syntax_parser.cpp @@ -23,6 +23,7 @@ #include "core/fpdfapi/parser/fpdf_parser_utility.h" #include "core/fxcrt/fx_ext.h" #include "third_party/base/numerics/safe_math.h" +#include "third_party/base/ptr_util.h" namespace { @@ -362,10 +363,11 @@ CFX_ByteString CPDF_SyntaxParser::GetKeyword() { return GetNextWord(nullptr); } -CPDF_Object* CPDF_SyntaxParser::GetObject(CPDF_IndirectObjectHolder* pObjList, - uint32_t objnum, - uint32_t gennum, - bool bDecrypt) { +std::unique_ptr<CPDF_Object> CPDF_SyntaxParser::GetObject( + CPDF_IndirectObjectHolder* pObjList, + uint32_t objnum, + uint32_t gennum, + bool bDecrypt) { CFX_AutoRestorer<int> restorer(&s_CurrentRecursionDepth); if (++s_CurrentRecursionDepth > kParserMaxRecursionDepth) return nullptr; @@ -381,51 +383,50 @@ CPDF_Object* CPDF_SyntaxParser::GetObject(CPDF_IndirectObjectHolder* pObjList, CFX_ByteString nextword = GetNextWord(&bIsNumber); if (bIsNumber) { CFX_ByteString nextword2 = GetNextWord(nullptr); - if (nextword2 == "R") - return new CPDF_Reference(pObjList, FXSYS_atoui(word.c_str())); + if (nextword2 == "R") { + return pdfium::MakeUnique<CPDF_Reference>(pObjList, + FXSYS_atoui(word.c_str())); + } } m_Pos = SavedPos; - return new CPDF_Number(word.AsStringC()); + return pdfium::MakeUnique<CPDF_Number>(word.AsStringC()); } if (word == "true" || word == "false") - return new CPDF_Boolean(word == "true"); + return pdfium::MakeUnique<CPDF_Boolean>(word == "true"); if (word == "null") - return new CPDF_Null; + return pdfium::MakeUnique<CPDF_Null>(); if (word == "(") { CFX_ByteString str = ReadString(); if (m_pCryptoHandler && bDecrypt) m_pCryptoHandler->Decrypt(objnum, gennum, str); - return new CPDF_String(MaybeIntern(str), false); + return pdfium::MakeUnique<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(MaybeIntern(str), true); + return pdfium::MakeUnique<CPDF_String>(MaybeIntern(str), true); } - if (word == "[") { - CPDF_Array* pArray = new CPDF_Array; - while (CPDF_Object* pObj = GetObject(pObjList, objnum, gennum, true)) - pArray->Add(pObj); - - return pArray; + std::unique_ptr<CPDF_Array> pArray = pdfium::MakeUnique<CPDF_Array>(); + while (std::unique_ptr<CPDF_Object> pObj = + GetObject(pObjList, objnum, gennum, true)) { + pArray->Add(pObj.release()); + } + return std::move(pArray); } - if (word[0] == '/') { - return new CPDF_Name(MaybeIntern( + return pdfium::MakeUnique<CPDF_Name>(MaybeIntern( PDF_NameDecode(CFX_ByteStringC(m_WordBuffer + 1, m_WordSize - 1)))); } - if (word == "<<") { int32_t nKeys = 0; FX_FILESIZE dwSignValuePos = 0; - - std::unique_ptr<CPDF_Dictionary> pDict(new CPDF_Dictionary(m_pPool)); + std::unique_ptr<CPDF_Dictionary> pDict = + pdfium::MakeUnique<CPDF_Dictionary>(m_pPool); while (1) { CFX_ByteString key = GetNextWord(nullptr); if (key.IsEmpty()) @@ -439,7 +440,6 @@ CPDF_Object* CPDF_SyntaxParser::GetObject(CPDF_IndirectObjectHolder* pObjList, m_Pos = SavedPos; break; } - if (key[0] != '/') continue; @@ -451,12 +451,13 @@ CPDF_Object* CPDF_SyntaxParser::GetObject(CPDF_IndirectObjectHolder* pObjList, if (key == "/Contents") dwSignValuePos = m_Pos; - CPDF_Object* pObj = GetObject(pObjList, objnum, gennum, true); + std::unique_ptr<CPDF_Object> pObj = + GetObject(pObjList, objnum, gennum, true); if (!pObj) continue; CFX_ByteString keyNoSlash(key.raw_str() + 1, key.GetLength() - 1); - pDict->SetFor(keyNoSlash, pObj); + pDict->SetFor(keyNoSlash, pObj.release()); } // Only when this is a signature dictionary and has contents, we reset the @@ -464,14 +465,15 @@ CPDF_Object* CPDF_SyntaxParser::GetObject(CPDF_IndirectObjectHolder* pObjList, if (pDict->IsSignatureDict() && dwSignValuePos) { CFX_AutoRestorer<FX_FILESIZE> save_pos(&m_Pos); m_Pos = dwSignValuePos; - pDict->SetFor("Contents", GetObject(pObjList, objnum, gennum, false)); + pDict->SetFor("Contents", + GetObject(pObjList, objnum, gennum, false).release()); } FX_FILESIZE SavedPos = m_Pos; CFX_ByteString nextword = GetNextWord(nullptr); if (nextword != "stream") { m_Pos = SavedPos; - return pDict.release(); + return std::move(pDict); } return ReadStream(pDict.release(), objnum, gennum); } @@ -482,7 +484,7 @@ CPDF_Object* CPDF_SyntaxParser::GetObject(CPDF_IndirectObjectHolder* pObjList, return nullptr; } -CPDF_Object* CPDF_SyntaxParser::GetObjectForStrict( +std::unique_ptr<CPDF_Object> CPDF_SyntaxParser::GetObjectForStrict( CPDF_IndirectObjectHolder* pObjList, uint32_t objnum, uint32_t gennum) { @@ -501,48 +503,48 @@ CPDF_Object* CPDF_SyntaxParser::GetObjectForStrict( CFX_ByteString nextword = GetNextWord(&bIsNumber); if (bIsNumber) { CFX_ByteString nextword2 = GetNextWord(nullptr); - if (nextword2 == "R") - return new CPDF_Reference(pObjList, FXSYS_atoui(word.c_str())); + if (nextword2 == "R") { + return pdfium::MakeUnique<CPDF_Reference>(pObjList, + FXSYS_atoui(word.c_str())); + } } m_Pos = SavedPos; - return new CPDF_Number(word.AsStringC()); + return pdfium::MakeUnique<CPDF_Number>(word.AsStringC()); } if (word == "true" || word == "false") - return new CPDF_Boolean(word == "true"); + return pdfium::MakeUnique<CPDF_Boolean>(word == "true"); if (word == "null") - return new CPDF_Null; + return pdfium::MakeUnique<CPDF_Null>(); if (word == "(") { CFX_ByteString str = ReadString(); if (m_pCryptoHandler) m_pCryptoHandler->Decrypt(objnum, gennum, str); - return new CPDF_String(MaybeIntern(str), false); + return pdfium::MakeUnique<CPDF_String>(MaybeIntern(str), false); } - if (word == "<") { CFX_ByteString str = ReadHexString(); if (m_pCryptoHandler) m_pCryptoHandler->Decrypt(objnum, gennum, str); - return new CPDF_String(MaybeIntern(str), true); + return pdfium::MakeUnique<CPDF_String>(MaybeIntern(str), true); } - if (word == "[") { - std::unique_ptr<CPDF_Array> pArray(new CPDF_Array); - while (CPDF_Object* pObj = GetObject(pObjList, objnum, gennum, true)) - pArray->Add(pObj); - - return m_WordBuffer[0] == ']' ? pArray.release() : nullptr; + std::unique_ptr<CPDF_Array> pArray = pdfium::MakeUnique<CPDF_Array>(); + while (std::unique_ptr<CPDF_Object> pObj = + GetObject(pObjList, objnum, gennum, true)) { + pArray->Add(pObj.release()); + } + return m_WordBuffer[0] == ']' ? std::move(pArray) : nullptr; } - if (word[0] == '/') { - return new CPDF_Name(MaybeIntern( + return pdfium::MakeUnique<CPDF_Name>(MaybeIntern( PDF_NameDecode(CFX_ByteStringC(m_WordBuffer + 1, m_WordSize - 1)))); } - if (word == "<<") { - std::unique_ptr<CPDF_Dictionary> pDict(new CPDF_Dictionary(m_pPool)); + std::unique_ptr<CPDF_Dictionary> pDict = + pdfium::MakeUnique<CPDF_Dictionary>(m_pPool); while (1) { FX_FILESIZE SavedPos = m_Pos; CFX_ByteString key = GetNextWord(nullptr); @@ -556,7 +558,6 @@ CPDF_Object* CPDF_SyntaxParser::GetObjectForStrict( m_Pos = SavedPos; break; } - if (key[0] != '/') continue; @@ -581,7 +582,7 @@ CPDF_Object* CPDF_SyntaxParser::GetObjectForStrict( CFX_ByteString nextword = GetNextWord(nullptr); if (nextword != "stream") { m_Pos = SavedPos; - return pDict.release(); + return std::move(pDict); } return ReadStream(pDict.release(), objnum, gennum); @@ -609,9 +610,10 @@ unsigned int CPDF_SyntaxParser::ReadEOLMarkers(FX_FILESIZE pos) { return 0; } -CPDF_Stream* CPDF_SyntaxParser::ReadStream(CPDF_Dictionary* pDict, - uint32_t objnum, - uint32_t gennum) { +std::unique_ptr<CPDF_Stream> CPDF_SyntaxParser::ReadStream( + CPDF_Dictionary* pDict, + uint32_t objnum, + uint32_t gennum) { CPDF_Object* pLenObj = pDict->GetObjectFor("Length"); FX_FILESIZE len = -1; CPDF_Reference* pLenObjRef = ToReference(pLenObj); @@ -747,10 +749,9 @@ CPDF_Stream* CPDF_SyntaxParser::ReadStream(CPDF_Dictionary* pDict, } } - CPDF_Stream* pStream = new CPDF_Stream(pData, len, pDict); + auto pStream = pdfium::MakeUnique<CPDF_Stream>(pData, len, pDict); streamStartPos = m_Pos; FXSYS_memset(m_WordBuffer, 0, kEndObjStr.GetLength() + 1); - GetNextWordInternal(nullptr); int numMarkers = ReadEOLMarkers(m_Pos); diff --git a/core/fpdfapi/parser/cpdf_syntax_parser.h b/core/fpdfapi/parser/cpdf_syntax_parser.h index 6aab8db3fe..29eb3e1896 100644 --- a/core/fpdfapi/parser/cpdf_syntax_parser.h +++ b/core/fpdfapi/parser/cpdf_syntax_parser.h @@ -27,30 +27,29 @@ class CPDF_SyntaxParser { ~CPDF_SyntaxParser(); void InitParser(IFX_SeekableReadStream* pFileAccess, uint32_t HeaderOffset); - FX_FILESIZE SavePos() const { return m_Pos; } void RestorePos(FX_FILESIZE pos) { m_Pos = pos; } - CPDF_Object* GetObject(CPDF_IndirectObjectHolder* pObjList, - uint32_t objnum, - uint32_t gennum, - bool bDecrypt); - CPDF_Object* GetObjectForStrict(CPDF_IndirectObjectHolder* pObjList, - uint32_t objnum, - uint32_t gennum); - CFX_ByteString GetKeyword(); + std::unique_ptr<CPDF_Object> GetObject(CPDF_IndirectObjectHolder* pObjList, + uint32_t objnum, + uint32_t gennum, + bool bDecrypt); + std::unique_ptr<CPDF_Object> GetObjectForStrict( + CPDF_IndirectObjectHolder* pObjList, + uint32_t objnum, + uint32_t gennum); + + CFX_ByteString GetKeyword(); void ToNextLine(); void ToNextWord(); - bool SearchWord(const CFX_ByteStringC& word, bool bWholeWord, bool bForward, FX_FILESIZE limit); - FX_FILESIZE FindTag(const CFX_ByteStringC& tag, FX_FILESIZE limit); + FX_FILESIZE FindTag(const CFX_ByteStringC& tag, FX_FILESIZE limit); void SetEncrypt(std::unique_ptr<CPDF_CryptoHandler> pCryptoHandler); - bool ReadBlock(uint8_t* pBuf, uint32_t size); bool GetCharAt(FX_FILESIZE pos, uint8_t& ch); CFX_ByteString GetNextWord(bool* bIsNumber); @@ -76,9 +75,9 @@ class CPDF_SyntaxParser { CFX_ByteString ReadString(); CFX_ByteString ReadHexString(); unsigned int ReadEOLMarkers(FX_FILESIZE pos); - CPDF_Stream* ReadStream(CPDF_Dictionary* pDict, - uint32_t objnum, - uint32_t gennum); + std::unique_ptr<CPDF_Stream> ReadStream(CPDF_Dictionary* pDict, + uint32_t objnum, + uint32_t gennum); CFX_ByteString MaybeIntern(const CFX_ByteString& str); inline bool CheckPosition(FX_FILESIZE pos) { |