From 1c5d8504ed38dbf19ae4dee04360cf0893cdb18f Mon Sep 17 00:00:00 2001 From: Lei Zhang Date: Tue, 1 Aug 2017 11:08:33 -0700 Subject: Change CPDF_Parser::GetIndirectBinary() to return a std::vector. Fixes potential leaks in CPDF_Creator::WriteOldIndirectObject(), the only caller. Change-Id: I8a20da8a555c8d28f3bcd467a193a6a81c9f91d9 Reviewed-on: https://pdfium-review.googlesource.com/9751 Reviewed-by: Art Snake Commit-Queue: Lei Zhang --- core/fpdfapi/edit/cpdf_creator.cpp | 11 ++++------ core/fpdfapi/parser/cpdf_parser.cpp | 41 ++++++++++++++++++------------------- core/fpdfapi/parser/cpdf_parser.h | 2 +- 3 files changed, 25 insertions(+), 29 deletions(-) diff --git a/core/fpdfapi/edit/cpdf_creator.cpp b/core/fpdfapi/edit/cpdf_creator.cpp index ceffa5077f..b347d45dce 100644 --- a/core/fpdfapi/edit/cpdf_creator.cpp +++ b/core/fpdfapi/edit/cpdf_creator.cpp @@ -336,23 +336,20 @@ bool CPDF_Creator::WriteOldIndirectObject(uint32_t objnum) { if (!bExistInMap) m_pDocument->DeleteIndirectObject(objnum); } else { - uint8_t* pBuffer; - uint32_t size; - m_pParser->GetIndirectBinary(objnum, pBuffer, size); - if (!pBuffer) + std::vector buffer = m_pParser->GetIndirectBinary(objnum); + if (buffer.empty()) return true; if (object_type == CPDF_Parser::ObjectType::kCompressed) { if (!m_Archive->WriteDWord(objnum) || !m_Archive->WriteString(" 0 obj ") || - !m_Archive->WriteBlock(pBuffer, size) || + !m_Archive->WriteBlock(buffer.data(), buffer.size()) || !m_Archive->WriteString("\r\nendobj\r\n")) { return false; } } else { - if (!m_Archive->WriteBlock(pBuffer, size)) + if (!m_Archive->WriteBlock(buffer.data(), buffer.size())) return false; } - FX_Free(pBuffer); } return true; } diff --git a/core/fpdfapi/parser/cpdf_parser.cpp b/core/fpdfapi/parser/cpdf_parser.cpp index 0f4da6e28f..eb59195aa2 100644 --- a/core/fpdfapi/parser/cpdf_parser.cpp +++ b/core/fpdfapi/parser/cpdf_parser.cpp @@ -1222,19 +1222,16 @@ FX_FILESIZE CPDF_Parser::GetObjectSize(uint32_t objnum) const { return *it - offset; } -void CPDF_Parser::GetIndirectBinary(uint32_t objnum, - uint8_t*& pBuffer, - uint32_t& size) { - pBuffer = nullptr; - size = 0; +std::vector CPDF_Parser::GetIndirectBinary(uint32_t objnum) { + std::vector buffer; if (!IsValidObjectNumber(objnum)) - return; + return buffer; if (GetObjectType(objnum) == ObjectType::kCompressed) { CFX_RetainPtr pObjStream = GetObjectStream(m_ObjectInfo[objnum].pos); if (!pObjStream) - return; + return buffer; int32_t offset = GetStreamFirst(pObjStream); const uint8_t* pData = pObjStream->GetData(); @@ -1250,6 +1247,7 @@ void CPDF_Parser::GetIndirectBinary(uint32_t objnum, if (thisnum != objnum) continue; + size_t size = 0; if (i == 1) { size = totalsize - (thisoff + offset); } else { @@ -1258,19 +1256,19 @@ void CPDF_Parser::GetIndirectBinary(uint32_t objnum, size = nextoff - thisoff; } - pBuffer = FX_Alloc(uint8_t, size); - memcpy(pBuffer, pData + thisoff + offset, size); - return; + buffer.resize(size); + memcpy(buffer.data(), pData + thisoff + offset, size); + break; } - return; + return buffer; } if (GetObjectType(objnum) != ObjectType::kNotCompressed) - return; + return buffer; FX_FILESIZE pos = m_ObjectInfo[objnum].pos; if (pos == 0) - return; + return buffer; FX_FILESIZE SavedPos = m_pSyntax->GetPos(); m_pSyntax->SetPos(pos); @@ -1279,30 +1277,30 @@ void CPDF_Parser::GetIndirectBinary(uint32_t objnum, CFX_ByteString word = m_pSyntax->GetNextWord(&bIsNumber); if (!bIsNumber) { m_pSyntax->SetPos(SavedPos); - return; + return buffer; } uint32_t parser_objnum = FXSYS_atoui(word.c_str()); if (parser_objnum && parser_objnum != objnum) { m_pSyntax->SetPos(SavedPos); - return; + return buffer; } word = m_pSyntax->GetNextWord(&bIsNumber); if (!bIsNumber) { m_pSyntax->SetPos(SavedPos); - return; + return buffer; } if (m_pSyntax->GetKeyword() != "obj") { m_pSyntax->SetPos(SavedPos); - return; + return buffer; } auto it = m_SortedOffset.find(pos); if (it == m_SortedOffset.end() || ++it == m_SortedOffset.end()) { m_pSyntax->SetPos(SavedPos); - return; + return buffer; } FX_FILESIZE nextoff = *it; @@ -1332,11 +1330,12 @@ void CPDF_Parser::GetIndirectBinary(uint32_t objnum, nextoff = m_pSyntax->GetPos(); } - size = (uint32_t)(nextoff - pos); - pBuffer = FX_Alloc(uint8_t, size); + size_t size = (uint32_t)(nextoff - pos); + buffer.resize(size); m_pSyntax->SetPos(pos); - m_pSyntax->ReadBlock(pBuffer, size); + m_pSyntax->ReadBlock(buffer.data(), size); m_pSyntax->SetPos(SavedPos); + return buffer; } std::unique_ptr CPDF_Parser::ParseIndirectObjectAt( diff --git a/core/fpdfapi/parser/cpdf_parser.h b/core/fpdfapi/parser/cpdf_parser.h index 3acdbbfa6f..4d78d7052f 100644 --- a/core/fpdfapi/parser/cpdf_parser.h +++ b/core/fpdfapi/parser/cpdf_parser.h @@ -91,7 +91,7 @@ class CPDF_Parser { FX_FILESIZE GetObjectOffset(uint32_t objnum) const; FX_FILESIZE GetObjectSize(uint32_t objnum) const; - void GetIndirectBinary(uint32_t objnum, uint8_t*& pBuffer, uint32_t& size); + std::vector GetIndirectBinary(uint32_t objnum); int GetFileVersion() const { return m_FileVersion; } bool IsXRefStream() const { return m_bXRefStream; } -- cgit v1.2.3