diff options
-rw-r--r-- | core/fpdfapi/font/cpdf_fontencoding.cpp | 23 | ||||
-rw-r--r-- | core/fpdfapi/font/cpdf_fontencoding.h | 4 | ||||
-rw-r--r-- | core/fpdfapi/page/cpdf_docpagedata.cpp | 5 | ||||
-rw-r--r-- | core/fpdfapi/page/cpdf_image.cpp | 19 | ||||
-rw-r--r-- | core/fpdfapi/page/cpdf_image.h | 2 | ||||
-rw-r--r-- | core/fpdfapi/page/cpdf_streamcontentparser.cpp | 51 | ||||
-rw-r--r-- | core/fpdfapi/page/cpdf_streamcontentparser.h | 32 | ||||
-rw-r--r-- | core/fpdfapi/page/cpdf_streamparser.cpp | 80 | ||||
-rw-r--r-- | core/fpdfapi/page/pageint.h | 14 | ||||
-rw-r--r-- | core/fpdfapi/parser/cpdf_document.cpp | 39 | ||||
-rw-r--r-- | core/fpdfapi/parser/cpdf_parser.cpp | 17 | ||||
-rw-r--r-- | testing/libfuzzer/pdf_streamparser_fuzzer.cc | 5 |
12 files changed, 150 insertions, 141 deletions
diff --git a/core/fpdfapi/font/cpdf_fontencoding.cpp b/core/fpdfapi/font/cpdf_fontencoding.cpp index df21267e1d..88b2c8d6a5 100644 --- a/core/fpdfapi/font/cpdf_fontencoding.cpp +++ b/core/fpdfapi/font/cpdf_fontencoding.cpp @@ -1672,7 +1672,8 @@ bool CPDF_FontEncoding::IsIdentical(CPDF_FontEncoding* pAnother) const { 0; } -CPDF_Object* CPDF_FontEncoding::Realize(CFX_WeakPtr<CFX_ByteStringPool> pPool) { +std::unique_ptr<CPDF_Object> CPDF_FontEncoding::Realize( + CFX_WeakPtr<CFX_ByteStringPool> pPool) { int predefined = 0; for (int cs = PDFFONT_ENCODING_WINANSI; cs < PDFFONT_ENCODING_ZAPFDINGBATS; cs++) { @@ -1690,15 +1691,13 @@ CPDF_Object* CPDF_FontEncoding::Realize(CFX_WeakPtr<CFX_ByteStringPool> pPool) { } } if (predefined) { - if (predefined == PDFFONT_ENCODING_WINANSI) { - return new CPDF_Name(pPool, "WinAnsiEncoding"); - } - if (predefined == PDFFONT_ENCODING_MACROMAN) { - return new CPDF_Name(pPool, "MacRomanEncoding"); - } - if (predefined == PDFFONT_ENCODING_MACEXPERT) { - return new CPDF_Name(pPool, "MacExpertEncoding"); - } + if (predefined == PDFFONT_ENCODING_WINANSI) + return pdfium::MakeUnique<CPDF_Name>(pPool, "WinAnsiEncoding"); + if (predefined == PDFFONT_ENCODING_MACROMAN) + return pdfium::MakeUnique<CPDF_Name>(pPool, "MacRomanEncoding"); + if (predefined == PDFFONT_ENCODING_MACEXPERT) + return pdfium::MakeUnique<CPDF_Name>(pPool, "MacExpertEncoding"); + return nullptr; } const uint16_t* pStandard = @@ -1712,10 +1711,10 @@ CPDF_Object* CPDF_FontEncoding::Realize(CFX_WeakPtr<CFX_ByteStringPool> pPool) { pDiff->AddNew<CPDF_Name>(PDF_AdobeNameFromUnicode(m_Unicodes[i])); } - CPDF_Dictionary* pDict = new CPDF_Dictionary(pPool); + auto pDict = pdfium::MakeUnique<CPDF_Dictionary>(pPool); pDict->SetNewFor<CPDF_Name>("BaseEncoding", "WinAnsiEncoding"); pDict->SetFor("Differences", std::move(pDiff)); - return pDict; + return std::move(pDict); } uint32_t FT_CharCodeFromUnicode(int encoding, FX_WCHAR unicode) { diff --git a/core/fpdfapi/font/cpdf_fontencoding.h b/core/fpdfapi/font/cpdf_fontencoding.h index a497681e5e..6c0de909e1 100644 --- a/core/fpdfapi/font/cpdf_fontencoding.h +++ b/core/fpdfapi/font/cpdf_fontencoding.h @@ -7,6 +7,8 @@ #ifndef CORE_FPDFAPI_FONT_CPDF_FONTENCODING_H_ #define CORE_FPDFAPI_FONT_CPDF_FONTENCODING_H_ +#include <memory> + #include "core/fxcrt/cfx_string_pool_template.h" #include "core/fxcrt/cfx_weak_ptr.h" #include "core/fxcrt/fx_string.h" @@ -52,7 +54,7 @@ class CPDF_FontEncoding { m_Unicodes[charcode] = unicode; } - CPDF_Object* Realize(CFX_WeakPtr<CFX_ByteStringPool> pPool); + std::unique_ptr<CPDF_Object> Realize(CFX_WeakPtr<CFX_ByteStringPool> pPool); public: FX_WCHAR m_Unicodes[256]; diff --git a/core/fpdfapi/page/cpdf_docpagedata.cpp b/core/fpdfapi/page/cpdf_docpagedata.cpp index 3df771070e..1c99d523b0 100644 --- a/core/fpdfapi/page/cpdf_docpagedata.cpp +++ b/core/fpdfapi/page/cpdf_docpagedata.cpp @@ -182,9 +182,8 @@ CPDF_Font* CPDF_DocPageData::GetStandardFont(const CFX_ByteString& fontName, pDict->SetNewFor<CPDF_Name>("Subtype", "Type1"); pDict->SetNewFor<CPDF_Name>("BaseFont", fontName); if (pEncoding) { - pDict->SetFor( - "Encoding", - pdfium::WrapUnique(pEncoding->Realize(m_pPDFDoc->GetByteStringPool()))); + pDict->SetFor("Encoding", + pEncoding->Realize(m_pPDFDoc->GetByteStringPool())); } std::unique_ptr<CPDF_Font> pFont = CPDF_Font::Create(m_pPDFDoc, pDict); diff --git a/core/fpdfapi/page/cpdf_image.cpp b/core/fpdfapi/page/cpdf_image.cpp index 66599a8268..dafca2b764 100644 --- a/core/fpdfapi/page/cpdf_image.cpp +++ b/core/fpdfapi/page/cpdf_image.cpp @@ -26,6 +26,7 @@ #include "core/fpdfapi/render/render_int.h" #include "core/fxcodec/fx_codec.h" #include "core/fxge/fx_dib.h" +#include "third_party/base/numerics/safe_conversions.h" #include "third_party/base/ptr_util.h" CPDF_Image::CPDF_Image(CPDF_Document* pDoc) : m_pDocument(pDoc) {} @@ -86,7 +87,8 @@ void CPDF_Image::ConvertStreamToIndirectObject() { m_pDocument->AddIndirectObject(std::move(m_pOwnedStream)); } -CPDF_Dictionary* CPDF_Image::InitJPEG(uint8_t* pData, uint32_t size) { +std::unique_ptr<CPDF_Dictionary> CPDF_Image::InitJPEG(uint8_t* pData, + uint32_t size) { int32_t width; int32_t height; int32_t num_comps; @@ -97,8 +99,8 @@ CPDF_Dictionary* CPDF_Image::InitJPEG(uint8_t* pData, uint32_t size) { return nullptr; } - CPDF_Dictionary* pDict = - new CPDF_Dictionary(m_pDocument->GetByteStringPool()); + auto pDict = + pdfium::MakeUnique<CPDF_Dictionary>(m_pDocument->GetByteStringPool()); pDict->SetNewFor<CPDF_Name>("Type", "XObject"); pDict->SetNewFor<CPDF_Name>("Subtype", "Image"); pDict->SetNewFor<CPDF_Number>("Width", width); @@ -134,14 +136,17 @@ CPDF_Dictionary* CPDF_Image::InitJPEG(uint8_t* pData, uint32_t size) { } void CPDF_Image::SetJpegImage(IFX_SeekableReadStream* pFile) { - uint32_t size = (uint32_t)pFile->GetSize(); + uint32_t size = pdfium::base::checked_cast<uint32_t>(pFile->GetSize()); if (!size) return; uint32_t dwEstimateSize = std::min(size, 8192U); std::vector<uint8_t> data(dwEstimateSize); - pFile->ReadBlock(data.data(), 0, dwEstimateSize); - CPDF_Dictionary* pDict = InitJPEG(data.data(), dwEstimateSize); + if (!pFile->ReadBlock(data.data(), 0, dwEstimateSize)) + return; + + std::unique_ptr<CPDF_Dictionary> pDict = + InitJPEG(data.data(), dwEstimateSize); if (!pDict && size > dwEstimateSize) { data.resize(size); pFile->ReadBlock(data.data(), 0, size); @@ -150,7 +155,7 @@ void CPDF_Image::SetJpegImage(IFX_SeekableReadStream* pFile) { if (!pDict) return; - m_pStream->InitStreamFromFile(pFile, pdfium::WrapUnique(pDict)); + m_pStream->InitStreamFromFile(pFile, std::move(pDict)); } void CPDF_Image::SetImage(const CFX_DIBitmap* pBitmap) { diff --git a/core/fpdfapi/page/cpdf_image.h b/core/fpdfapi/page/cpdf_image.h index ac35ce1ac7..1491efe1c6 100644 --- a/core/fpdfapi/page/cpdf_image.h +++ b/core/fpdfapi/page/cpdf_image.h @@ -70,7 +70,7 @@ class CPDF_Image { private: void FinishInitialization(); - CPDF_Dictionary* InitJPEG(uint8_t* pData, uint32_t size); + std::unique_ptr<CPDF_Dictionary> InitJPEG(uint8_t* pData, uint32_t size); int32_t m_Height = 0; int32_t m_Width = 0; diff --git a/core/fpdfapi/page/cpdf_streamcontentparser.cpp b/core/fpdfapi/page/cpdf_streamcontentparser.cpp index 107ab1ccaa..8c6038d626 100644 --- a/core/fpdfapi/page/cpdf_streamcontentparser.cpp +++ b/core/fpdfapi/page/cpdf_streamcontentparser.cpp @@ -306,8 +306,8 @@ int CPDF_StreamContentParser::GetNextParamPos() { if (m_ParamStartPos == kParamBufSize) { m_ParamStartPos = 0; } - if (m_ParamBuf[m_ParamStartPos].m_Type == 0) - delete m_ParamBuf[m_ParamStartPos].m_pObject; + if (m_ParamBuf[m_ParamStartPos].m_Type == ContentParam::OBJECT) + m_ParamBuf[m_ParamStartPos].m_pObject.reset(); return m_ParamStartPos; } @@ -324,8 +324,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(m_pDocument->GetByteStringPool(), PDF_NameDecode(bsName)); + param.m_pObject = pdfium::MakeUnique<CPDF_Name>( + m_pDocument->GetByteStringPool(), PDF_NameDecode(bsName)); } else { param.m_Type = ContentParam::NAME; if (bsName.Find('#') == -1) { @@ -346,22 +346,21 @@ void CPDF_StreamContentParser::AddNumberParam(const FX_CHAR* str, int len) { FX_atonum(CFX_ByteStringC(str, len), ¶m.m_Number.m_Integer); } -void CPDF_StreamContentParser::AddObjectParam(CPDF_Object* pObj) { +void CPDF_StreamContentParser::AddObjectParam( + std::unique_ptr<CPDF_Object> pObj) { ContentParam& param = m_ParamBuf[GetNextParamPos()]; param.m_Type = ContentParam::OBJECT; - param.m_pObject = pObj; + param.m_pObject = std::move(pObj); } void CPDF_StreamContentParser::ClearAllParams() { uint32_t index = m_ParamStartPos; for (uint32_t i = 0; i < m_ParamCount; i++) { - if (m_ParamBuf[index].m_Type == 0) - delete m_ParamBuf[index].m_pObject; - + if (m_ParamBuf[index].m_Type == ContentParam::OBJECT) + m_ParamBuf[index].m_pObject.reset(); index++; - if (index == kParamBufSize) { + if (index == kParamBufSize) index = 0; - } } m_ParamStartPos = 0; m_ParamCount = 0; @@ -377,25 +376,23 @@ CPDF_Object* CPDF_StreamContentParser::GetObject(uint32_t index) { } ContentParam& param = m_ParamBuf[real_index]; if (param.m_Type == ContentParam::NUMBER) { - CPDF_Number* pNumber = param.m_Number.m_bInteger - ? new CPDF_Number(param.m_Number.m_Integer) - : new CPDF_Number(param.m_Number.m_Float); - param.m_Type = ContentParam::OBJECT; - param.m_pObject = pNumber; - return pNumber; + param.m_pObject = + param.m_Number.m_bInteger + ? pdfium::MakeUnique<CPDF_Number>(param.m_Number.m_Integer) + : pdfium::MakeUnique<CPDF_Number>(param.m_Number.m_Float); + return param.m_pObject.get(); } if (param.m_Type == ContentParam::NAME) { - CPDF_Name* pName = new CPDF_Name( + param.m_Type = ContentParam::OBJECT; + param.m_pObject = pdfium::MakeUnique<CPDF_Name>( m_pDocument->GetByteStringPool(), CFX_ByteString(param.m_Name.m_Buffer, param.m_Name.m_Len)); - param.m_Type = ContentParam::OBJECT; - param.m_pObject = pName; - return pName; - } - if (param.m_Type == ContentParam::OBJECT) { - return param.m_pObject; + return param.m_pObject.get(); } + if (param.m_Type == ContentParam::OBJECT) + return param.m_pObject.get(); + ASSERT(false); return nullptr; } @@ -651,7 +648,7 @@ void CPDF_StreamContentParser::Handle_BeginImage() { } CFX_ByteString key((const FX_CHAR*)m_pSyntax->GetWordBuf() + 1, m_pSyntax->GetWordSize() - 1); - auto pObj = pdfium::WrapUnique(m_pSyntax->ReadNextObject(false, 0)); + auto pObj = m_pSyntax->ReadNextObject(false, 0); if (!key.IsEmpty()) { uint32_t dwObjNum = pObj ? pObj->GetObjNum() : 0; if (dwObjNum) @@ -1668,3 +1665,7 @@ void CPDF_StreamContentParser::ParsePathObject() { } } } + +CPDF_StreamContentParser::ContentParam::ContentParam() {} + +CPDF_StreamContentParser::ContentParam::~ContentParam() {} diff --git a/core/fpdfapi/page/cpdf_streamcontentparser.h b/core/fpdfapi/page/cpdf_streamcontentparser.h index 1ed2aaa4de..dfb5230809 100644 --- a/core/fpdfapi/page/cpdf_streamcontentparser.h +++ b/core/fpdfapi/page/cpdf_streamcontentparser.h @@ -52,21 +52,23 @@ class CPDF_StreamContentParser { private: struct ContentParam { enum Type { OBJECT = 0, NUMBER, NAME }; + + ContentParam(); + ~ContentParam(); + Type m_Type; - union { - struct { - bool m_bInteger; - union { - int m_Integer; - FX_FLOAT m_Float; - }; - } m_Number; - CPDF_Object* m_pObject; - struct { - int m_Len; - char m_Buffer[32]; - } m_Name; - }; + std::unique_ptr<CPDF_Object> m_pObject; + struct { + bool m_bInteger; + union { + int m_Integer; + FX_FLOAT m_Float; + }; + } m_Number; + struct { + int m_Len; + char m_Buffer[32]; + } m_Name; }; static const int kParamBufSize = 16; @@ -76,7 +78,7 @@ class CPDF_StreamContentParser { static OpCodes InitializeOpCodes(); void AddNumberParam(const FX_CHAR* str, int len); - void AddObjectParam(CPDF_Object* pObj); + void AddObjectParam(std::unique_ptr<CPDF_Object> pObj); void AddNameParam(const FX_CHAR* name, int size); int GetNextParamPos(); void ClearAllParams(); diff --git a/core/fpdfapi/page/cpdf_streamparser.cpp b/core/fpdfapi/page/cpdf_streamparser.cpp index f271e58d78..2901d3b50b 100644 --- a/core/fpdfapi/page/cpdf_streamparser.cpp +++ b/core/fpdfapi/page/cpdf_streamparser.cpp @@ -8,6 +8,7 @@ #include <limits.h> +#include <memory> #include <utility> #include "core/fpdfapi/cpdf_modulemgr.h" @@ -112,7 +113,6 @@ 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( @@ -122,16 +122,14 @@ CPDF_StreamParser::CPDF_StreamParser( : m_pBuf(pData), m_Size(dwSize), m_Pos(0), - m_pLastObj(nullptr), m_pPool(pPool) {} -CPDF_StreamParser::~CPDF_StreamParser() { - delete m_pLastObj; -} +CPDF_StreamParser::~CPDF_StreamParser() {} -CPDF_Stream* CPDF_StreamParser::ReadInlineStream(CPDF_Document* pDoc, - CPDF_Dictionary* pDict, - CPDF_Object* pCSObj) { +std::unique_ptr<CPDF_Stream> CPDF_StreamParser::ReadInlineStream( + CPDF_Document* pDoc, + CPDF_Dictionary* pDict, + CPDF_Object* pCSObj) { if (m_Pos == m_Size) return nullptr; @@ -233,15 +231,13 @@ CPDF_Stream* CPDF_StreamParser::ReadInlineStream(CPDF_Document* pDoc, m_Pos += dwStreamSize; } pDict->SetNewFor<CPDF_Number>("Length", (int)dwStreamSize); - return new CPDF_Stream(pData, dwStreamSize, pdfium::WrapUnique(pDict)); + return pdfium::MakeUnique<CPDF_Stream>(pData, dwStreamSize, + pdfium::WrapUnique(pDict)); } CPDF_StreamParser::SyntaxType CPDF_StreamParser::ParseNextElement() { - delete m_pLastObj; - m_pLastObj = nullptr; - + m_pLastObj.reset(); m_WordSize = 0; - bool bIsNumber = true; if (!PositionIsInBounds()) return EndOfData; @@ -273,6 +269,7 @@ CPDF_StreamParser::SyntaxType CPDF_StreamParser::ParseNextElement() { return Others; } + bool bIsNumber = true; while (1) { if (m_WordSize < kMaxWordBuffer) m_WordBuffer[m_WordSize++] = ch; @@ -300,30 +297,25 @@ CPDF_StreamParser::SyntaxType CPDF_StreamParser::ParseNextElement() { if (m_WordSize == 4) { if (memcmp(m_WordBuffer, "true", 4) == 0) { - m_pLastObj = new CPDF_Boolean(true); + m_pLastObj = pdfium::MakeUnique<CPDF_Boolean>(true); return Others; } if (memcmp(m_WordBuffer, "null", 4) == 0) { - m_pLastObj = new CPDF_Null; + m_pLastObj = pdfium::MakeUnique<CPDF_Null>(); return Others; } } else if (m_WordSize == 5) { if (memcmp(m_WordBuffer, "false", 5) == 0) { - m_pLastObj = new CPDF_Boolean(false); + m_pLastObj = pdfium::MakeUnique<CPDF_Boolean>(false); return Others; } } return Keyword; } -CPDF_Object* CPDF_StreamParser::GetObject() { - CPDF_Object* pObj = m_pLastObj; - m_pLastObj = nullptr; - return pObj; -} - -CPDF_Object* CPDF_StreamParser::ReadNextObject(bool bAllowNestedArray, - uint32_t dwInArrayLevel) { +std::unique_ptr<CPDF_Object> CPDF_StreamParser::ReadNextObject( + bool bAllowNestedArray, + uint32_t dwInArrayLevel) { bool bIsNumber; GetNextWord(bIsNumber); if (!m_WordSize) @@ -331,47 +323,45 @@ CPDF_Object* CPDF_StreamParser::ReadNextObject(bool bAllowNestedArray, if (bIsNumber) { m_WordBuffer[m_WordSize] = 0; - return new CPDF_Number(CFX_ByteStringC(m_WordBuffer, m_WordSize)); + return pdfium::MakeUnique<CPDF_Number>( + CFX_ByteStringC(m_WordBuffer, m_WordSize)); } int first_char = m_WordBuffer[0]; if (first_char == '/') { CFX_ByteString name = PDF_NameDecode(CFX_ByteStringC(m_WordBuffer + 1, m_WordSize - 1)); - return new CPDF_Name(m_pPool, name); + return pdfium::MakeUnique<CPDF_Name>(m_pPool, name); } if (first_char == '(') { CFX_ByteString str = ReadString(); - return new CPDF_String(m_pPool, str, false); + return pdfium::MakeUnique<CPDF_String>(m_pPool, str, false); } if (first_char == '<') { if (m_WordSize == 1) - return new CPDF_String(m_pPool, ReadHexString(), true); + return pdfium::MakeUnique<CPDF_String>(m_pPool, ReadHexString(), true); - CPDF_Dictionary* pDict = new CPDF_Dictionary(m_pPool); + auto pDict = pdfium::MakeUnique<CPDF_Dictionary>(m_pPool); while (1) { GetNextWord(bIsNumber); if (m_WordSize == 2 && m_WordBuffer[0] == '>') break; - if (!m_WordSize || m_WordBuffer[0] != '/') { - delete pDict; + if (!m_WordSize || m_WordBuffer[0] != '/') return nullptr; - } CFX_ByteString key = PDF_NameDecode(CFX_ByteStringC(m_WordBuffer + 1, m_WordSize - 1)); - auto pObj = pdfium::WrapUnique(ReadNextObject(true, 0)); - if (!pObj) { - delete pDict; + std::unique_ptr<CPDF_Object> pObj = ReadNextObject(true, 0); + if (!pObj) return nullptr; - } + if (!key.IsEmpty()) pDict->SetFor(key, std::move(pObj)); } - return pDict; + return std::move(pDict); } if (first_char == '[') { @@ -380,28 +370,28 @@ CPDF_Object* CPDF_StreamParser::ReadNextObject(bool bAllowNestedArray, return nullptr; } - CPDF_Array* pArray = new CPDF_Array; + auto pArray = pdfium::MakeUnique<CPDF_Array>(); while (1) { - CPDF_Object* pObj = ReadNextObject(bAllowNestedArray, dwInArrayLevel + 1); + std::unique_ptr<CPDF_Object> pObj = + ReadNextObject(bAllowNestedArray, dwInArrayLevel + 1); if (pObj) { - pArray->Add(pdfium::WrapUnique(pObj)); + pArray->Add(std::move(pObj)); continue; } if (!m_WordSize || m_WordBuffer[0] == ']') break; } - return pArray; + return std::move(pArray); } if (m_WordSize == 5 && !memcmp(m_WordBuffer, "false", 5)) - return new CPDF_Boolean(false); + return pdfium::MakeUnique<CPDF_Boolean>(false); if (m_WordSize == 4) { if (memcmp(m_WordBuffer, "true", 4) == 0) - return new CPDF_Boolean(true); - + return pdfium::MakeUnique<CPDF_Boolean>(true); if (memcmp(m_WordBuffer, "null", 4) == 0) - return new CPDF_Null; + return pdfium::MakeUnique<CPDF_Null>(); } return nullptr; diff --git a/core/fpdfapi/page/pageint.h b/core/fpdfapi/page/pageint.h index dee9639d7d..cf3522d44a 100644 --- a/core/fpdfapi/page/pageint.h +++ b/core/fpdfapi/page/pageint.h @@ -11,6 +11,7 @@ #include <memory> #include <set> #include <unordered_map> +#include <utility> #include <vector> #include "core/fpdfapi/page/cpdf_contentmark.h" @@ -52,16 +53,17 @@ class CPDF_StreamParser { const CFX_WeakPtr<CFX_ByteStringPool>& pPool); ~CPDF_StreamParser(); - CPDF_Stream* ReadInlineStream(CPDF_Document* pDoc, - CPDF_Dictionary* pDict, - CPDF_Object* pCSObj); SyntaxType ParseNextElement(); uint8_t* GetWordBuf() { return m_WordBuffer; } uint32_t GetWordSize() const { return m_WordSize; } - CPDF_Object* GetObject(); uint32_t GetPos() const { return m_Pos; } void SetPos(uint32_t pos) { m_Pos = pos; } - CPDF_Object* ReadNextObject(bool bAllowNestedArray, uint32_t dwInArrayLevel); + std::unique_ptr<CPDF_Object> GetObject() { return std::move(m_pLastObj); } + std::unique_ptr<CPDF_Object> ReadNextObject(bool bAllowNestedArray, + uint32_t dwInArrayLevel); + std::unique_ptr<CPDF_Stream> ReadInlineStream(CPDF_Document* pDoc, + CPDF_Dictionary* pDict, + CPDF_Object* pCSObj); private: friend class cpdf_streamparser_ReadHexString_Test; @@ -76,7 +78,7 @@ class CPDF_StreamParser { uint32_t m_Pos; // Current byte position within m_pBuf. uint8_t m_WordBuffer[256]; uint32_t m_WordSize; - CPDF_Object* m_pLastObj; + std::unique_ptr<CPDF_Object> m_pLastObj; CFX_WeakPtr<CFX_ByteStringPool> m_pPool; }; diff --git a/core/fpdfapi/parser/cpdf_document.cpp b/core/fpdfapi/parser/cpdf_document.cpp index 97f55f872d..207071c69c 100644 --- a/core/fpdfapi/parser/cpdf_document.cpp +++ b/core/fpdfapi/parser/cpdf_document.cpp @@ -299,7 +299,7 @@ void ProcessNonbCJK(CPDF_Dictionary* pBaseDict, bool bold, bool italic, CFX_ByteString basefont, - CPDF_Array* pWidths) { + std::unique_ptr<CPDF_Array> pWidths) { if (bold && italic) basefont += ",BoldItalic"; else if (bold) @@ -310,23 +310,24 @@ void ProcessNonbCJK(CPDF_Dictionary* pBaseDict, pBaseDict->SetNewFor<CPDF_Name>("BaseFont", basefont); pBaseDict->SetNewFor<CPDF_Number>("FirstChar", 32); pBaseDict->SetNewFor<CPDF_Number>("LastChar", 255); - pBaseDict->SetFor("Widths", pdfium::WrapUnique(pWidths)); + pBaseDict->SetFor("Widths", std::move(pWidths)); } -std::unique_ptr<CPDF_Dictionary> CalculateFontDesc(CPDF_Document* pDoc, - CFX_ByteString basefont, - int flags, - int italicangle, - int ascend, - int descend, - CPDF_Array* bbox, - int32_t stemV) { +std::unique_ptr<CPDF_Dictionary> CalculateFontDesc( + CPDF_Document* pDoc, + CFX_ByteString basefont, + int flags, + int italicangle, + int ascend, + int descend, + std::unique_ptr<CPDF_Array> bbox, + int32_t stemV) { auto pFontDesc = pdfium::MakeUnique<CPDF_Dictionary>(pDoc->GetByteStringPool()); pFontDesc->SetNewFor<CPDF_Name>("Type", "FontDescriptor"); pFontDesc->SetNewFor<CPDF_Name>("FontName", basefont); pFontDesc->SetNewFor<CPDF_Number>("Flags", flags); - pFontDesc->SetFor("FontBBox", pdfium::WrapUnique(bbox)); + pFontDesc->SetFor("FontBBox", std::move(bbox)); pFontDesc->SetNewFor<CPDF_Number>("ItalicAngle", italicangle); pFontDesc->SetNewFor<CPDF_Number>("Ascent", ascend); pFontDesc->SetNewFor<CPDF_Number>("Descent", descend); @@ -883,7 +884,7 @@ CPDF_Font* CPDF_Document::AddFont(CFX_Font* pFont, int charset, bool bVert) { new CFX_UnicodeEncoding(pFont)); CPDF_Dictionary* pFontDict = pBaseDict; if (!bCJK) { - CPDF_Array* pWidths = new CPDF_Array; + auto pWidths = pdfium::MakeUnique<CPDF_Array>(); for (int charcode = 32; charcode < 128; charcode++) { int glyph_index = pEncoding->GlyphFromCharCode(charcode); int char_width = pFont->GetGlyphWidth(glyph_index); @@ -909,7 +910,7 @@ CPDF_Font* CPDF_Document::AddFont(CFX_Font* pFont, int charset, bool bVert) { } } ProcessNonbCJK(pBaseDict, pFont->IsBold(), pFont->IsItalic(), basefont, - pWidths); + std::move(pWidths)); } else { pFontDict = ProcessbCJK(pBaseDict, charset, bVert, basefont, [pFont, &pEncoding](FX_WCHAR start, FX_WCHAR end, @@ -922,7 +923,7 @@ CPDF_Font* CPDF_Document::AddFont(CFX_Font* pFont, int charset, bool bVert) { pFont->GetSubstFont() ? pFont->GetSubstFont()->m_ItalicAngle : 0; FX_RECT bbox; pFont->GetBBox(bbox); - CPDF_Array* pBBox = new CPDF_Array; + auto pBBox = pdfium::MakeUnique<CPDF_Array>(); pBBox->AddNew<CPDF_Number>(bbox.left); pBBox->AddNew<CPDF_Number>(bbox.bottom); pBBox->AddNew<CPDF_Number>(bbox.right); @@ -944,7 +945,7 @@ CPDF_Font* CPDF_Document::AddFont(CFX_Font* pFont, int charset, bool bVert) { } CPDF_Dictionary* pFontDesc = ToDictionary(AddIndirectObject( CalculateFontDesc(this, basefont, flags, italicangle, pFont->GetAscent(), - pFont->GetDescent(), pBBox, nStemV))); + pFont->GetDescent(), std::move(pBBox), nStemV))); pFontDict->SetNewFor<CPDF_Reference>("FontDescriptor", this, pFontDesc->GetObjNum()); return LoadFont(pBaseDict); @@ -1021,11 +1022,11 @@ CPDF_Font* CPDF_Document::AddWindowsFont(LOGFONTA* pLogFont, } int char_widths[224]; GetCharWidth(hDC, 32, 255, char_widths); - CPDF_Array* pWidths = new CPDF_Array; + auto pWidths = pdfium::MakeUnique<CPDF_Array>(); for (size_t i = 0; i < 224; i++) pWidths->AddNew<CPDF_Number>(char_widths[i]); ProcessNonbCJK(pBaseDict, pLogFont->lfWeight > FW_MEDIUM, - pLogFont->lfItalic != 0, basefont, pWidths); + pLogFont->lfItalic != 0, basefont, std::move(pWidths)); } else { pFontDict = ProcessbCJK(pBaseDict, pLogFont->lfCharSet, bVert, basefont, @@ -1033,12 +1034,12 @@ CPDF_Font* CPDF_Document::AddWindowsFont(LOGFONTA* pLogFont, InsertWidthArray(hDC, start, end, widthArr); }); } - CPDF_Array* pBBox = new CPDF_Array; + auto pBBox = pdfium::MakeUnique<CPDF_Array>(); for (int i = 0; i < 4; i++) pBBox->AddNew<CPDF_Number>(bbox[i]); std::unique_ptr<CPDF_Dictionary> pFontDesc = CalculateFontDesc(this, basefont, flags, italicangle, ascend, descend, - pBBox, pLogFont->lfWeight / 5); + std::move(pBBox), pLogFont->lfWeight / 5); pFontDesc->SetNewFor<CPDF_Number>("CapHeight", capheight); pFontDict->SetNewFor<CPDF_Reference>( "FontDescriptor", this, diff --git a/core/fpdfapi/parser/cpdf_parser.cpp b/core/fpdfapi/parser/cpdf_parser.cpp index 5354417eda..2f432ed9f9 100644 --- a/core/fpdfapi/parser/cpdf_parser.cpp +++ b/core/fpdfapi/parser/cpdf_parser.cpp @@ -1070,14 +1070,21 @@ bool CPDF_Parser::LoadCrossRefV5(FX_FILESIZE* pos, bool bMainXRef) { } CPDF_Array* CPDF_Parser::GetIDArray() { - CPDF_Object* pID = m_pTrailer ? m_pTrailer->GetObjectFor("ID") : nullptr; + if (!m_pTrailer) + return nullptr; + + CPDF_Object* pID = m_pTrailer->GetObjectFor("ID"); if (!pID) return nullptr; - if (CPDF_Reference* pRef = pID->AsReference()) { - pID = ParseIndirectObject(nullptr, pRef->GetRefObjNum()).release(); - m_pTrailer->SetFor("ID", pdfium::WrapUnique(pID)); - } + CPDF_Reference* pRef = pID->AsReference(); + if (!pRef) + return ToArray(pID); + + std::unique_ptr<CPDF_Object> pNewObj = + ParseIndirectObject(nullptr, pRef->GetRefObjNum()); + pID = pNewObj.get(); + m_pTrailer->SetFor("ID", std::move(pNewObj)); return ToArray(pID); } diff --git a/testing/libfuzzer/pdf_streamparser_fuzzer.cc b/testing/libfuzzer/pdf_streamparser_fuzzer.cc index a0287c935a..277acc0a12 100644 --- a/testing/libfuzzer/pdf_streamparser_fuzzer.cc +++ b/testing/libfuzzer/pdf_streamparser_fuzzer.cc @@ -3,14 +3,15 @@ // found in the LICENSE file. #include <cstdint> +#include <memory> #include "core/fpdfapi/page/pageint.h" #include "core/fpdfapi/parser/cpdf_object.h" extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { CPDF_StreamParser parser(data, size); - while (CPDF_Object* pObj = parser.ReadNextObject(true, 0)) - delete pObj; + while (std::unique_ptr<CPDF_Object> pObj = parser.ReadNextObject(true, 0)) + continue; return 0; } |