From aa7022833db1a6e21b81fcca30b45ba652298f32 Mon Sep 17 00:00:00 2001 From: Dan Sinclair Date: Wed, 10 May 2017 13:54:54 -0400 Subject: Cleaning up Edit code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This Cl conslidates if statements, converts int returns to bools where possible and various other cleanups in fpdfapi/edit. Change-Id: Ia31ecc69843117eb5ebfff449a6046a267d08e89 Reviewed-on: https://pdfium-review.googlesource.com/5190 Reviewed-by: Nicolás Peña Commit-Queue: dsinclair --- core/fpdfapi/edit/cpdf_creator.cpp | 460 ++++++++++++++------------------ core/fpdfapi/edit/cpdf_creator.h | 35 +-- core/fpdfapi/edit/cpdf_objectstream.cpp | 23 +- core/fpdfapi/edit/cpdf_xrefstream.cpp | 73 ++--- core/fpdfapi/edit/cpdf_xrefstream.h | 16 +- core/fxcrt/fx_basic_buffer.cpp | 8 +- 6 files changed, 272 insertions(+), 343 deletions(-) diff --git a/core/fpdfapi/edit/cpdf_creator.cpp b/core/fpdfapi/edit/cpdf_creator.cpp index 5f540bd088..0aa9fb0b1b 100644 --- a/core/fpdfapi/edit/cpdf_creator.cpp +++ b/core/fpdfapi/edit/cpdf_creator.cpp @@ -41,16 +41,13 @@ std::vector GenerateFileID(uint32_t dwSeed1, uint32_t dwSeed2) { } int32_t OutputIndex(CFX_FileBufferArchive* pFile, FX_FILESIZE offset) { - if (pFile->AppendByte(static_cast(offset >> 24)) < 0) - return -1; - if (pFile->AppendByte(static_cast(offset >> 16)) < 0) - return -1; - if (pFile->AppendByte(static_cast(offset >> 8)) < 0) - return -1; - if (pFile->AppendByte(static_cast(offset)) < 0) - return -1; - if (pFile->AppendByte(0) < 0) + if (pFile->AppendByte(static_cast(offset >> 24)) < 0 || + pFile->AppendByte(static_cast(offset >> 16)) < 0 || + pFile->AppendByte(static_cast(offset >> 8)) < 0 || + pFile->AppendByte(static_cast(offset)) < 0 || + pFile->AppendByte(0) < 0) { return -1; + } return 0; } @@ -87,80 +84,37 @@ bool CPDF_Creator::IsXRefNeedEnd() { return m_pXRefStream->CountIndexArrayItems() >= kXRefStreamMaxSize; } -int32_t CPDF_Creator::WriteIndirectObjectToStream(const CPDF_Object* pObj) { - if (!m_pXRefStream) - return 1; - - uint32_t objnum = pObj->GetObjNum(); - if (m_pParser && m_pParser->GetObjectGenNum(objnum) > 0) - return 1; - if (pObj->IsNumber()) - return 1; - - CPDF_Dictionary* pDict = pObj->GetDict(); - if (pObj->IsStream()) { - if (pDict && pDict->GetStringFor("Type") == "XRef") - return 0; - return 1; - } - - if (pDict) { - if (pDict == m_pDocument->GetRoot() || pDict == m_pEncryptDict) - return 1; - if (pDict->IsSignatureDict()) - return 1; - if (pDict->GetStringFor("Type") == "Page") - return 1; - } - - m_pXRefStream->AddObjectNumberToIndexArray(objnum); - if (m_pXRefStream->CompressIndirectObject(objnum, pObj, this) < 0) - return -1; - if (!IsXRefNeedEnd()) - return 0; - if (!m_pXRefStream->End(this, false)) - return -1; - if (!m_pXRefStream->Start()) - return -1; - return 0; -} -int32_t CPDF_Creator::WriteIndirectObjectToStream(uint32_t objnum, - const uint8_t* pBuffer, - uint32_t dwSize) { +bool CPDF_Creator::WriteIndirectObjectToStream(uint32_t objnum, + const uint8_t* pBuffer, + uint32_t dwSize) { if (!m_pXRefStream) - return 1; + return true; m_pXRefStream->AddObjectNumberToIndexArray(objnum); - int32_t iRet = - m_pXRefStream->CompressIndirectObject(objnum, pBuffer, dwSize, this); - if (iRet < 1) - return iRet; + if (!m_pXRefStream->CompressIndirectObject(objnum, pBuffer, dwSize, this)) + return false; if (!IsXRefNeedEnd()) - return 0; - if (!m_pXRefStream->End(this, false)) - return -1; - if (!m_pXRefStream->Start()) - return -1; - return 0; + return true; + if (!m_pXRefStream->End(this, false) || !m_pXRefStream->Start()) + return false; + return true; } -int32_t CPDF_Creator::AppendObjectNumberToXRef(uint32_t objnum) { +bool CPDF_Creator::AppendObjectNumberToXRef(uint32_t objnum) { if (!m_pXRefStream) - return 1; + return true; m_pXRefStream->AddObjectNumberToIndexArray(objnum); if (!IsXRefNeedEnd()) - return 0; - if (!m_pXRefStream->End(this, false)) - return -1; - if (!m_pXRefStream->Start()) - return -1; - return 0; + return true; + if (!m_pXRefStream->End(this, false) || !m_pXRefStream->Start()) + return false; + return true; } -int32_t CPDF_Creator::WriteStream(const CPDF_Object* pStream, - uint32_t objnum, - CPDF_CryptoHandler* pCrypto) { +bool CPDF_Creator::WriteStream(const CPDF_Object* pStream, + uint32_t objnum, + CPDF_CryptoHandler* pCrypto) { CPDF_FlateEncoder encoder(const_cast(pStream->AsStream()), pStream != m_pMetadata); CPDF_Encryptor encryptor(pCrypto, objnum, encoder.GetData(), @@ -171,69 +125,89 @@ int32_t CPDF_Creator::WriteStream(const CPDF_Object* pStream, encoder.GetDict()->SetNewFor( "Length", static_cast(encryptor.GetSize())); } - if (WriteDirectObj(objnum, encoder.GetDict(), true) < 0) - return -1; + if (!WriteDirectObj(objnum, encoder.GetDict(), true)) + return false; int len = m_File.AppendString("stream\r\n"); if (len < 0) - return -1; - + return false; m_Offset += len; - if (m_File.AppendBlock(encryptor.GetData(), encryptor.GetSize()) < 0) - return -1; + if (m_File.AppendBlock(encryptor.GetData(), encryptor.GetSize()) < 0) + return false; m_Offset += encryptor.GetSize(); + len = m_File.AppendString("\r\nendstream"); if (len < 0) - return -1; - + return false; m_Offset += len; - return 1; + + return true; } -int32_t CPDF_Creator::WriteIndirectObj(uint32_t objnum, - const CPDF_Object* pObj) { +bool CPDF_Creator::WriteIndirectObj(uint32_t objnum, const CPDF_Object* pObj) { int32_t len = m_File.AppendDWord(objnum); if (len < 0) - return -1; - + return false; m_Offset += len; len = m_File.AppendString(" 0 obj\r\n"); if (len < 0) - return -1; - + return false; m_Offset += len; + if (pObj->IsStream()) { CPDF_CryptoHandler* pHandler = pObj != m_pMetadata ? m_pCryptoHandler.Get() : nullptr; - if (WriteStream(pObj, objnum, pHandler) < 0) - return -1; - } else { - if (WriteDirectObj(objnum, pObj, true) < 0) - return -1; + if (!WriteStream(pObj, objnum, pHandler)) + return false; + } else if (!WriteDirectObj(objnum, pObj, true)) { + return false; } len = m_File.AppendString("\r\nendobj\r\n"); if (len < 0) - return -1; + return false; m_Offset += len; - if (AppendObjectNumberToXRef(objnum) < 0) - return -1; - return 0; + if (!AppendObjectNumberToXRef(objnum)) + return false; + return true; } -int32_t CPDF_Creator::WriteIndirectObj(const CPDF_Object* pObj) { - int32_t iRet = WriteIndirectObjectToStream(pObj); - if (iRet < 1) - return iRet; - return WriteIndirectObj(pObj->GetObjNum(), pObj); +bool CPDF_Creator::WriteIndirectObj(const CPDF_Object* pObj) { + uint32_t objnum = pObj->GetObjNum(); + if (!m_pXRefStream || (m_pParser && m_pParser->GetObjectGenNum(objnum) > 0) || + pObj->IsNumber()) { + return WriteIndirectObj(objnum, pObj); + } + + CPDF_Dictionary* pDict = pObj->GetDict(); + if (pObj->IsStream()) { + if (pDict && pDict->GetStringFor("Type") == "XRef") + return true; + return WriteIndirectObj(objnum, pObj); + } + + if (pDict && + (pDict == m_pDocument->GetRoot() || pDict == m_pEncryptDict || + pDict->IsSignatureDict() || pDict->GetStringFor("Type") == "Page")) { + return WriteIndirectObj(objnum, pObj); + } + + m_pXRefStream->AddObjectNumberToIndexArray(objnum); + if (!m_pXRefStream->CompressIndirectObject(objnum, pObj, this)) + return false; + if (!IsXRefNeedEnd()) + return true; + if (!m_pXRefStream->End(this, false) || !m_pXRefStream->Start()) + return false; + return true; } -int32_t CPDF_Creator::WriteDirectObj(uint32_t objnum, - const CPDF_Object* pObj, - bool bEncrypt) { +bool CPDF_Creator::WriteDirectObj(uint32_t objnum, + const CPDF_Object* pObj, + bool bEncrypt) { switch (pObj->GetType()) { case CPDF_Object::BOOLEAN: case CPDF_Object::NAME: @@ -241,7 +215,7 @@ int32_t CPDF_Creator::WriteDirectObj(uint32_t objnum, case CPDF_Object::NUMBER: case CPDF_Object::REFERENCE: if (!pObj->WriteTo(&m_File, &m_Offset)) - return -1; + return false; break; case CPDF_Object::STRING: { @@ -249,7 +223,7 @@ int32_t CPDF_Creator::WriteDirectObj(uint32_t objnum, bool bHex = pObj->AsString()->IsHex(); if (!m_pCryptoHandler || !bEncrypt) { if (!pObj->WriteTo(&m_File, &m_Offset)) - return -1; + return false; break; } CPDF_Encryptor encryptor(m_pCryptoHandler.Get(), objnum, @@ -258,7 +232,7 @@ int32_t CPDF_Creator::WriteDirectObj(uint32_t objnum, CFX_ByteString(encryptor.GetData(), encryptor.GetSize()), bHex); int32_t len = m_File.AppendString(content.AsStringC()); if (len < 0) - return -1; + return false; m_Offset += len; break; @@ -274,28 +248,28 @@ int32_t CPDF_Creator::WriteDirectObj(uint32_t objnum, encoder.GetDict()->SetNewFor( "Length", static_cast(encryptor.GetSize())); } - if (WriteDirectObj(objnum, encoder.GetDict(), true) < 0) - return -1; + if (!WriteDirectObj(objnum, encoder.GetDict(), true)) + return false; int32_t len = m_File.AppendString("stream\r\n"); if (len < 0) - return -1; - + return false; m_Offset += len; - if (m_File.AppendBlock(encryptor.GetData(), encryptor.GetSize()) < 0) - return -1; + if (m_File.AppendBlock(encryptor.GetData(), encryptor.GetSize()) < 0) + return false; m_Offset += encryptor.GetSize(); + len = m_File.AppendString("\r\nendstream"); if (len < 0) - return -1; - + return false; m_Offset += len; + break; } case CPDF_Object::ARRAY: { if (m_File.AppendString("[") < 0) - return -1; + return false; m_Offset += 1; const CPDF_Array* p = pObj->AsArray(); @@ -303,22 +277,18 @@ int32_t CPDF_Creator::WriteDirectObj(uint32_t objnum, CPDF_Object* pElement = p->GetObjectAt(i); if (!pElement->IsInline()) { if (m_File.AppendString(" ") < 0) - return -1; + return false; int32_t len = m_File.AppendDWord(pElement->GetObjNum()); - if (len < 0) - return -1; - if (m_File.AppendString(" 0 R") < 0) - return -1; - + if (len < 0 || m_File.AppendString(" 0 R") < 0) + return false; m_Offset += len + 5; - } else { - if (WriteDirectObj(objnum, pElement, true) < 0) - return -1; + } else if (!WriteDirectObj(objnum, pElement, true)) { + return false; } } if (m_File.AppendString("]") < 0) - return -1; + return false; m_Offset += 1; break; @@ -326,12 +296,12 @@ int32_t CPDF_Creator::WriteDirectObj(uint32_t objnum, case CPDF_Object::DICTIONARY: { if (!m_pCryptoHandler || pObj == m_pEncryptDict) { if (!pObj->WriteTo(&m_File, &m_Offset)) - return -1; + return false; break; } if (m_File.AppendString("<<") < 0) - return -1; + return false; m_Offset += 2; const CPDF_Dictionary* p = pObj->AsDictionary(); @@ -341,59 +311,53 @@ int32_t CPDF_Creator::WriteDirectObj(uint32_t objnum, const CFX_ByteString& key = it.first; CPDF_Object* pValue = it.second.get(); if (m_File.AppendString("/") < 0) - return -1; + return false; int32_t len = m_File.AppendString(PDF_NameEncode(key).AsStringC()); if (len < 0) - return -1; - + return false; m_Offset += len + 1; + if (bSignDict && key == "Contents") bSignValue = true; - if (!pValue->IsInline()) { if (m_File.AppendString(" ") < 0) - return -1; + return false; len = m_File.AppendDWord(pValue->GetObjNum()); - if (len < 0) - return -1; - if (m_File.AppendString(" 0 R ") < 0) - return -1; - + if (len < 0 || m_File.AppendString(" 0 R ") < 0) + return false; m_Offset += len + 6; - } else { - if (WriteDirectObj(objnum, pValue, !bSignValue) < 0) - return -1; + } else if (!WriteDirectObj(objnum, pValue, !bSignValue)) { + return false; } } if (m_File.AppendString(">>") < 0) - return -1; + return false; m_Offset += 2; break; } } - return 1; + return true; } -int32_t CPDF_Creator::WriteOldIndirectObject(uint32_t objnum) { +bool CPDF_Creator::WriteOldIndirectObject(uint32_t objnum) { if (m_pParser->IsObjectFreeOrNull(objnum)) - return 0; + return true; m_ObjectOffsets[objnum] = m_Offset; bool bExistInMap = !!m_pDocument->GetIndirectObject(objnum); const uint8_t object_type = m_pParser->GetObjectType(objnum); - bool bObjStm = (object_type == 2) && m_pEncryptDict && !m_pXRefStream; if (m_pParser->IsVersionUpdated() || m_bSecurityChanged || bExistInMap || - bObjStm) { + (object_type == 2 && m_pEncryptDict && !m_pXRefStream)) { CPDF_Object* pObj = m_pDocument->GetOrParseIndirectObject(objnum); if (!pObj) { m_ObjectOffsets.erase(objnum); - return 0; + return true; } - if (WriteIndirectObj(pObj)) - return -1; + if (!WriteIndirectObj(pObj)) + return false; if (!bExistInMap) m_pDocument->DeleteIndirectObject(objnum); } else { @@ -401,57 +365,53 @@ int32_t CPDF_Creator::WriteOldIndirectObject(uint32_t objnum) { uint32_t size; m_pParser->GetIndirectBinary(objnum, pBuffer, size); if (!pBuffer) - return 0; + return true; if (object_type == 2) { if (m_pXRefStream) { - if (WriteIndirectObjectToStream(objnum, pBuffer, size) < 0) { + if (!WriteIndirectObjectToStream(objnum, pBuffer, size)) { FX_Free(pBuffer); - return -1; + return false; } } else { int32_t len = m_File.AppendDWord(objnum); - if (len < 0) - return -1; - if (m_File.AppendString(" 0 obj ") < 0) - return -1; - + if (len < 0 || m_File.AppendString(" 0 obj ") < 0) + return false; m_Offset += len + 7; - if (m_File.AppendBlock(pBuffer, size) < 0) - return -1; + if (m_File.AppendBlock(pBuffer, size) < 0) + return false; m_Offset += size; - if (m_File.AppendString("\r\nendobj\r\n") < 0) - return -1; + if (m_File.AppendString("\r\nendobj\r\n") < 0) + return false; m_Offset += 10; } } else { if (m_File.AppendBlock(pBuffer, size) < 0) - return -1; - + return false; m_Offset += size; - if (AppendObjectNumberToXRef(objnum) < 0) - return -1; + + if (!AppendObjectNumberToXRef(objnum)) + return false; } FX_Free(pBuffer); } - return 1; + return true; } -int32_t CPDF_Creator::WriteOldObjs() { +bool CPDF_Creator::WriteOldObjs() { uint32_t nLastObjNum = m_pParser->GetLastObjNum(); if (!m_pParser->IsValidObjectNumber(nLastObjNum)) - return 0; + return true; for (uint32_t objnum = m_CurObjNum; objnum <= nLastObjNum; ++objnum) { - int32_t iRet = WriteOldIndirectObject(objnum); - if (iRet < 0) - return iRet; + if (!WriteOldIndirectObject(objnum)) + return false; } - return 0; + return true; } -int32_t CPDF_Creator::WriteNewObjs() { +bool CPDF_Creator::WriteNewObjs() { for (size_t i = m_CurObjNum; i < m_NewObjNumArray.size(); ++i) { uint32_t objnum = m_NewObjNumArray[i]; CPDF_Object* pObj = m_pDocument->GetIndirectObject(objnum); @@ -459,17 +419,16 @@ int32_t CPDF_Creator::WriteNewObjs() { continue; m_ObjectOffsets[objnum] = m_Offset; - if (WriteIndirectObj(pObj)) - return -1; + if (!WriteIndirectObj(pObj)) + return false; } - return 0; + return true; } void CPDF_Creator::InitOldObjNumOffsets() { if (!m_pParser) return; - uint32_t j = 0; uint32_t dwStart = 0; uint32_t dwEnd = m_pParser->GetLastObjNum(); while (dwStart <= dwEnd) { @@ -479,7 +438,7 @@ void CPDF_Creator::InitOldObjNumOffsets() { if (dwStart > dwEnd) break; - j = dwStart; + uint32_t j = dwStart; while (j <= dwEnd && !m_pParser->IsObjectFreeOrNull(j)) j++; @@ -490,9 +449,10 @@ void CPDF_Creator::InitOldObjNumOffsets() { void CPDF_Creator::InitNewObjNumOffsets() { for (const auto& pair : *m_pDocument) { const uint32_t objnum = pair.first; - const CPDF_Object* pObj = pair.second.get(); - if (IsIncremental() || pObj->GetObjNum() == CPDF_Object::kInvalidObjNum) + if (IsIncremental() || + pair.second->GetObjNum() == CPDF_Object::kInvalidObjNum) { continue; + } if (m_pParser && m_pParser->IsValidObjectNumber(objnum) && m_pParser->GetObjectType(objnum)) { continue; @@ -508,12 +468,12 @@ int32_t CPDF_Creator::WriteDoc_Stage1() { if (m_iStage == 0) { if (!m_pParser) m_dwFlags &= ~FPDFCREATE_INCREMENTAL; - if (m_bSecurityChanged && (m_dwFlags & FPDFCREATE_NO_ORIGINAL) == 0) + if (m_bSecurityChanged && IsOriginal()) m_dwFlags &= ~FPDFCREATE_INCREMENTAL; CPDF_Dictionary* pDict = m_pDocument->GetRoot(); m_pMetadata = pDict ? pDict->GetDirectObjectFor("Metadata") : nullptr; - if (m_dwFlags & FPDFCREATE_OBJECTSTREAM) { + if (HasObjectStream()) { m_pXRefStream = pdfium::MakeUnique(); m_pXRefStream->Start(); if (IsIncremental() && m_pParser) @@ -525,8 +485,8 @@ int32_t CPDF_Creator::WriteDoc_Stage1() { if (!IsIncremental()) { if (m_File.AppendString("%PDF-1.") < 0) return -1; - m_Offset += 7; + int32_t version = 7; if (m_FileVersion) version = m_FileVersion; @@ -541,20 +501,18 @@ int32_t CPDF_Creator::WriteDoc_Stage1() { len = m_File.AppendString("\r\n%\xA1\xB3\xC5\xD7\r\n"); if (len < 0) return -1; - m_Offset += len; + InitOldObjNumOffsets(); m_iStage = 20; } else { - CFX_RetainPtr pSrcFile = - m_pParser->GetFileAccess(); - m_Offset = pSrcFile->GetSize(); + m_Offset = m_pParser->GetFileAccess()->GetSize(); m_SavedOffset = m_Offset; m_iStage = 15; } } if (m_iStage == 15) { - if ((m_dwFlags & FPDFCREATE_NO_ORIGINAL) == 0 && m_SavedOffset > 0) { + if (IsOriginal() && m_SavedOffset > 0) { CFX_RetainPtr pSrcFile = m_pParser->GetFileAccess(); std::vector buffer(4096); @@ -571,20 +529,18 @@ int32_t CPDF_Creator::WriteDoc_Stage1() { src_size -= block_size; } } - if ((m_dwFlags & FPDFCREATE_NO_ORIGINAL) == 0 && - m_pParser->GetLastXRefOffset() == 0) { + if (IsOriginal() && m_pParser->GetLastXRefOffset() == 0) { InitOldObjNumOffsets(); - uint32_t dwEnd = m_pParser->GetLastObjNum(); - bool bObjStm = (m_dwFlags & FPDFCREATE_OBJECTSTREAM) != 0; - for (uint32_t objnum = 0; objnum <= dwEnd; objnum++) { - if (m_pParser->IsObjectFreeOrNull(objnum)) + + for (uint32_t num = 0; num <= m_pParser->GetLastObjNum(); ++num) { + if (m_pParser->IsObjectFreeOrNull(num)) continue; - m_ObjectOffsets[objnum] = m_pParser->GetObjectPositionOrZero(objnum); - if (bObjStm) - m_pXRefStream->AddObjectNumberToIndexArray(objnum); + m_ObjectOffsets[num] = m_pParser->GetObjectPositionOrZero(num); + if (HasObjectStream()) + m_pXRefStream->AddObjectNumberToIndexArray(num); } - if (bObjStm) { + if (HasObjectStream()) { m_pXRefStream->EndXRefStream(this); m_pXRefStream->Start(); } @@ -606,9 +562,8 @@ int32_t CPDF_Creator::WriteDoc_Stage2() { } } if (m_iStage == 21) { - int32_t iRet = WriteOldObjs(); - if (iRet) - return iRet; + if (!WriteOldObjs()) + return -1; m_iStage = 25; } @@ -617,9 +572,8 @@ int32_t CPDF_Creator::WriteDoc_Stage2() { m_iStage = 26; } if (m_iStage == 26) { - int32_t iRet = WriteNewObjs(); - if (iRet) - return iRet; + if (!WriteNewObjs()) + return -1; m_iStage = 27; } @@ -627,7 +581,7 @@ int32_t CPDF_Creator::WriteDoc_Stage2() { if (m_pEncryptDict && m_pEncryptDict->IsInline()) { m_dwLastObjNum += 1; FX_FILESIZE saveOffset = m_Offset; - if (WriteIndirectObj(m_dwLastObjNum, m_pEncryptDict) < 0) + if (!WriteIndirectObj(m_dwLastObjNum, m_pEncryptDict)) return -1; m_ObjectOffsets[m_dwLastObjNum] = saveOffset; @@ -642,10 +596,11 @@ int32_t CPDF_Creator::WriteDoc_Stage2() { int32_t CPDF_Creator::WriteDoc_Stage3() { ASSERT(m_iStage >= 80 || m_iStage < 90); + uint32_t dwLastObjNum = m_dwLastObjNum; if (m_iStage == 80) { m_XrefStart = m_Offset; - if (m_dwFlags & FPDFCREATE_OBJECTSTREAM) { + if (HasObjectStream()) { m_pXRefStream->End(this, true); m_XrefStart = m_pXRefStream->GetPreviousOffset(); m_iStage = 90; @@ -742,16 +697,17 @@ int32_t CPDF_Creator::WriteDoc_Stage3() { int32_t CPDF_Creator::WriteDoc_Stage4() { ASSERT(m_iStage >= 90); - if ((m_dwFlags & FPDFCREATE_OBJECTSTREAM) == 0) { + + if (!HasObjectStream()) { bool bXRefStream = IsIncremental() && m_pParser->IsXRefStream(); if (!bXRefStream) { if (m_File.AppendString("trailer\r\n<<") < 0) return -1; } else { - if (m_File.AppendDWord(m_pDocument->GetLastObjNum() + 1) < 0) - return -1; - if (m_File.AppendString(" 0 obj <<") < 0) + if (m_File.AppendDWord(m_pDocument->GetLastObjNum() + 1) < 0 || + m_File.AppendString(" 0 obj <<") < 0) { return -1; + } } if (m_pParser) { @@ -766,17 +722,16 @@ int32_t CPDF_Creator::WriteDoc_Stage4() { key == "XRefStm" || key == "ID") { continue; } - if (m_File.AppendString(("/")) < 0) - return -1; - if (m_File.AppendString(PDF_NameEncode(key).AsStringC()) < 0) + if (m_File.AppendString(("/")) < 0 || + m_File.AppendString(PDF_NameEncode(key).AsStringC()) < 0) { return -1; + } if (!pValue->IsInline()) { - if (m_File.AppendString(" ") < 0) - return -1; - if (m_File.AppendDWord(pValue->GetObjNum()) < 0) - return -1; - if (m_File.AppendString(" 0 R ") < 0) + if (m_File.AppendString(" ") < 0 || + m_File.AppendDWord(pValue->GetObjNum()) < 0 || + m_File.AppendString(" 0 R ") < 0) { return -1; + } } else { FX_FILESIZE offset = 0; if (!pValue->WriteTo(&m_File, &offset)) @@ -784,19 +739,17 @@ int32_t CPDF_Creator::WriteDoc_Stage4() { } } } else { - if (m_File.AppendString("\r\n/Root ") < 0) - return -1; - if (m_File.AppendDWord(m_pDocument->GetRoot()->GetObjNum()) < 0) - return -1; - if (m_File.AppendString(" 0 R\r\n") < 0) + if (m_File.AppendString("\r\n/Root ") < 0 || + m_File.AppendDWord(m_pDocument->GetRoot()->GetObjNum()) < 0 || + m_File.AppendString(" 0 R\r\n") < 0) { return -1; + } if (m_pDocument->GetInfo()) { - if (m_File.AppendString("/Info ") < 0) - return -1; - if (m_File.AppendDWord(m_pDocument->GetInfo()->GetObjNum()) < 0) - return -1; - if (m_File.AppendString(" 0 R\r\n") < 0) + if (m_File.AppendString("/Info ") < 0 || + m_File.AppendDWord(m_pDocument->GetInfo()->GetObjNum()) < 0 || + m_File.AppendString(" 0 R\r\n") < 0) { return -1; + } } } if (m_pEncryptDict) { @@ -806,18 +759,16 @@ int32_t CPDF_Creator::WriteDoc_Stage4() { uint32_t dwObjNum = m_pEncryptDict->GetObjNum(); if (dwObjNum == 0) dwObjNum = m_pDocument->GetLastObjNum() + 1; - if (m_File.AppendString(" ") < 0) - return -1; - if (m_File.AppendDWord(dwObjNum) < 0) - return -1; - if (m_File.AppendString(" 0 R ") < 0) + if (m_File.AppendString(" ") < 0 || m_File.AppendDWord(dwObjNum) < 0 || + m_File.AppendString(" 0 R ") < 0) { return -1; + } } - if (m_File.AppendString("/Size ") < 0) - return -1; - if (m_File.AppendDWord(m_dwLastObjNum + (bXRefStream ? 2 : 1)) < 0) + if (m_File.AppendString("/Size ") < 0 || + m_File.AppendDWord(m_dwLastObjNum + (bXRefStream ? 2 : 1)) < 0) { return -1; + } if (IsIncremental()) { FX_FILESIZE prev = m_pParser->GetLastXRefOffset(); if (prev) { @@ -850,17 +801,14 @@ int32_t CPDF_Creator::WriteDoc_Stage4() { for (i = 0; i < m_dwLastObjNum; i++) { if (!pdfium::ContainsKey(m_ObjectOffsets, i)) continue; - if (m_File.AppendDWord(i) < 0) - return -1; - if (m_File.AppendString(" 1 ") < 0) + if (m_File.AppendDWord(i) < 0 || m_File.AppendString(" 1 ") < 0) return -1; } - if (m_File.AppendString("]/Length ") < 0) - return -1; - if (m_File.AppendDWord(m_dwLastObjNum * 5) < 0) - return -1; - if (m_File.AppendString(">>stream\r\n") < 0) + if (m_File.AppendString("]/Length ") < 0 || + m_File.AppendDWord(m_dwLastObjNum * 5) < 0 || + m_File.AppendString(">>stream\r\n") < 0) { return -1; + } for (i = 0; i < m_dwLastObjNum; i++) { auto it = m_ObjectOffsets.find(i); if (it == m_ObjectOffsets.end()) @@ -871,18 +819,17 @@ int32_t CPDF_Creator::WriteDoc_Stage4() { size_t count = m_NewObjNumArray.size(); size_t i = 0; for (i = 0; i < count; i++) { - if (m_File.AppendDWord(m_NewObjNumArray[i]) < 0) - return -1; - if (m_File.AppendString(" 1 ") < 0) + if (m_File.AppendDWord(m_NewObjNumArray[i]) < 0 || + m_File.AppendString(" 1 ") < 0) { return -1; + } } - if (m_File.AppendString("]/Length ") < 0) - return -1; - if (m_File.AppendDWord(count * 5) < 0) + if (m_File.AppendString("]/Length ") < 0 || + m_File.AppendDWord(count * 5) < 0 || + m_File.AppendString(">>stream\r\n") < 0) { return -1; - if (m_File.AppendString(">>stream\r\n") < 0) - return -1; - for (i = 0; i < count; i++) + } + for (i = 0; i < count; ++i) OutputIndex(&m_File, m_ObjectOffsets[m_NewObjNumArray[i]]); } if (m_File.AppendString("\r\nendstream") < 0) @@ -896,10 +843,10 @@ int32_t CPDF_Creator::WriteDoc_Stage4() { char offset_buf[20]; memset(offset_buf, 0, sizeof(offset_buf)); FXSYS_i64toa(m_XrefStart, offset_buf, 10); - if (m_File.AppendBlock(offset_buf, FXSYS_strlen(offset_buf)) < 0) - return -1; - if (m_File.AppendString("\r\n%%EOF\r\n") < 0) + if (m_File.AppendBlock(offset_buf, FXSYS_strlen(offset_buf)) < 0 || + m_File.AppendString("\r\n%%EOF\r\n") < 0) { return -1; + } m_File.Flush(); return m_iStage = 100; @@ -919,6 +866,7 @@ bool CPDF_Creator::Create(uint32_t flags) { m_dwLastObjNum = m_pDocument->GetLastObjNum(); m_ObjectOffsets.clear(); m_NewObjNumArray.clear(); + InitID(); if (flags & FPDFCREATE_PROGRESSIVE) return true; diff --git a/core/fpdfapi/edit/cpdf_creator.h b/core/fpdfapi/edit/cpdf_creator.h index bda6507f21..5f39f5c40f 100644 --- a/core/fpdfapi/edit/cpdf_creator.h +++ b/core/fpdfapi/edit/cpdf_creator.h @@ -58,6 +58,10 @@ class CPDF_Creator { m_ObjectOffsets[objnum] = offset; } bool IsIncremental() const { return !!(m_dwFlags & FPDFCREATE_INCREMENTAL); } + bool IsOriginal() const { return !(m_dwFlags & FPDFCREATE_NO_ORIGINAL); } + bool HasObjectStream() const { + return !!(m_dwFlags & FPDFCREATE_OBJECTSTREAM); + } private: void Clear(); @@ -66,29 +70,26 @@ class CPDF_Creator { void InitNewObjNumOffsets(); void InitID(); - int32_t AppendObjectNumberToXRef(uint32_t objnum); + bool AppendObjectNumberToXRef(uint32_t objnum); int32_t WriteDoc_Stage1(); int32_t WriteDoc_Stage2(); int32_t WriteDoc_Stage3(); int32_t WriteDoc_Stage4(); - int32_t WriteOldIndirectObject(uint32_t objnum); - int32_t WriteOldObjs(); - int32_t WriteNewObjs(); - int32_t WriteIndirectObj(const CPDF_Object* pObj); - int32_t WriteDirectObj(uint32_t objnum, - const CPDF_Object* pObj, - bool bEncrypt); - int32_t WriteIndirectObjectToStream(const CPDF_Object* pObj); - int32_t WriteIndirectObj(uint32_t objnum, const CPDF_Object* pObj); - int32_t WriteIndirectObjectToStream(uint32_t objnum, - const uint8_t* pBuffer, - uint32_t dwSize); - - int32_t WriteStream(const CPDF_Object* pStream, - uint32_t objnum, - CPDF_CryptoHandler* pCrypto); + bool WriteOldIndirectObject(uint32_t objnum); + bool WriteOldObjs(); + bool WriteNewObjs(); + bool WriteIndirectObj(const CPDF_Object* pObj); + bool WriteDirectObj(uint32_t objnum, const CPDF_Object* pObj, bool bEncrypt); + bool WriteIndirectObj(uint32_t objnum, const CPDF_Object* pObj); + bool WriteIndirectObjectToStream(uint32_t objnum, + const uint8_t* pBuffer, + uint32_t dwSize); + + bool WriteStream(const CPDF_Object* pStream, + uint32_t objnum, + CPDF_CryptoHandler* pCrypto); bool IsXRefNeedEnd(); diff --git a/core/fpdfapi/edit/cpdf_objectstream.cpp b/core/fpdfapi/edit/cpdf_objectstream.cpp index fa0284433b..9b636f2e54 100644 --- a/core/fpdfapi/edit/cpdf_objectstream.cpp +++ b/core/fpdfapi/edit/cpdf_objectstream.cpp @@ -68,10 +68,9 @@ FX_FILESIZE CPDF_ObjectStream::End(CPDF_Creator* pCreator) { len = pFile->AppendString(" 0 obj\r\n<IncrementOffset(len); - uint32_t iCount = pdfium::CollectionSize(m_Items); - len = pFile->AppendDWord(iCount); + + len = pFile->AppendDWord(pdfium::CollectionSize(m_Items)); if (len < 0) return -1; pCreator->IncrementOffset(len); @@ -80,9 +79,7 @@ FX_FILESIZE CPDF_ObjectStream::End(CPDF_Creator* pCreator) { return -1; len = pFile->AppendDWord(static_cast(tempBuffer.GetLength())); - if (len < 0) - return -1; - if (pFile->AppendString("/Length ") < 0) + if (len < 0 || pFile->AppendString("/Length ") < 0) return -1; pCreator->IncrementOffset(len + 15); @@ -96,23 +93,23 @@ FX_FILESIZE CPDF_ObjectStream::End(CPDF_Creator* pCreator) { len = pFile->AppendDWord(encryptor.GetSize()); if (len < 0) return -1; - pCreator->IncrementOffset(len); + if (pFile->AppendString("/Filter /FlateDecode") < 0) return -1; - pCreator->IncrementOffset(20); + len = pFile->AppendString(">>stream\r\n"); - if (len < 0) + if (len < 0 || + pFile->AppendBlock(encryptor.GetData(), encryptor.GetSize()) < 0) { return -1; - if (pFile->AppendBlock(encryptor.GetData(), encryptor.GetSize()) < 0) - return -1; - + } pCreator->IncrementOffset(len + encryptor.GetSize()); + len = pFile->AppendString("\r\nendstream\r\nendobj\r\n"); if (len < 0) return -1; - pCreator->IncrementOffset(len); + return ObjOffset; } diff --git a/core/fpdfapi/edit/cpdf_xrefstream.cpp b/core/fpdfapi/edit/cpdf_xrefstream.cpp index 49174a54bc..7ec05fd8bc 100644 --- a/core/fpdfapi/edit/cpdf_xrefstream.cpp +++ b/core/fpdfapi/edit/cpdf_xrefstream.cpp @@ -41,29 +41,25 @@ int32_t WriteTrailer(CPDF_Document* pDocument, len = pFile->AppendString(PDF_NameEncode(key).AsStringC()); if (len < 0) return -1; - offset += len + 1; + if (!pValue->IsInline()) { if (pFile->AppendString(" ") < 0) return -1; len = pFile->AppendDWord(pValue->GetObjNum()); - if (len < 0) - return -1; - if (pFile->AppendString(" 0 R ") < 0) + if (len < 0 || pFile->AppendString(" 0 R ") < 0) return -1; - offset += len + 6; - } else { - if (!pValue->WriteTo(pFile, &offset)) - return -1; + } else if (!pValue->WriteTo(pFile, &offset)) { + return -1; } } if (pIDArray) { if (pFile->AppendString(("/ID")) < 0) return -1; - offset += 3; + if (!pIDArray->WriteTo(pFile, &offset)) return -1; } @@ -73,29 +69,24 @@ int32_t WriteTrailer(CPDF_Document* pDocument, return -1; len = pFile->AppendDWord(pDocument->GetRoot()->GetObjNum()); - if (len < 0) - return -1; - if (pFile->AppendString(" 0 R\r\n") < 0) + if (len < 0 || pFile->AppendString(" 0 R\r\n") < 0) return -1; - offset += len + 14; + if (pDocument->GetInfo()) { if (pFile->AppendString("/Info ") < 0) return -1; len = pFile->AppendDWord(pDocument->GetInfo()->GetObjNum()); - if (len < 0) - return -1; - if (pFile->AppendString(" 0 R\r\n") < 0) + if (len < 0 || pFile->AppendString(" 0 R\r\n") < 0) return -1; - offset += len + 12; } if (pIDArray) { if (pFile->AppendString(("/ID")) < 0) return -1; - offset += 3; + if (!pIDArray->WriteTo(pFile, &offset)) return -1; } @@ -110,18 +101,16 @@ int32_t WriteEncryptDictObjectReference(uint32_t dwObjNum, int32_t len = 0; if (pFile->AppendString("/Encrypt") < 0) return -1; - offset += 8; + if (pFile->AppendString(" ") < 0) return -1; len = pFile->AppendDWord(dwObjNum); - if (len < 0) + if (len < 0 || pFile->AppendString(" 0 R ") < 0) return -1; - if (pFile->AppendString(" 0 R ") < 0) - return -1; - offset += len + 6; + return offset; } @@ -171,39 +160,39 @@ bool CPDF_XRefStream::Start() { return true; } -int32_t CPDF_XRefStream::CompressIndirectObject(uint32_t dwObjNum, - const CPDF_Object* pObj, - CPDF_Creator* pCreator) { +bool CPDF_XRefStream::CompressIndirectObject(uint32_t dwObjNum, + const CPDF_Object* pObj, + CPDF_Creator* pCreator) { ASSERT(pCreator); m_ObjStream.CompressIndirectObject(dwObjNum, pObj); if (m_ObjStream.ItemCount() < kObjectStreamMaxSize && m_ObjStream.IsNotFull()) { - return 1; + return true; } return EndObjectStream(pCreator, true); } -int32_t CPDF_XRefStream::CompressIndirectObject(uint32_t dwObjNum, - const uint8_t* pBuffer, - uint32_t dwSize, - CPDF_Creator* pCreator) { +bool CPDF_XRefStream::CompressIndirectObject(uint32_t dwObjNum, + const uint8_t* pBuffer, + uint32_t dwSize, + CPDF_Creator* pCreator) { ASSERT(pCreator); m_ObjStream.CompressIndirectObject(dwObjNum, pBuffer, dwSize); if (m_ObjStream.ItemCount() < kObjectStreamMaxSize && m_ObjStream.IsNotFull()) { - return 1; + return true; } return EndObjectStream(pCreator, true); } -int32_t CPDF_XRefStream::EndObjectStream(CPDF_Creator* pCreator, bool bEOF) { +bool CPDF_XRefStream::EndObjectStream(CPDF_Creator* pCreator, bool bEOF) { FX_FILESIZE objOffset = 0; if (bEOF) { objOffset = m_ObjStream.End(pCreator); if (objOffset < 0) - return -1; + return false; } if (!m_ObjStream.GetObjectNumber()) @@ -237,7 +226,7 @@ int32_t CPDF_XRefStream::EndObjectStream(CPDF_Creator* pCreator, bool bEOF) { if (bEOF) m_ObjStream.Start(); - return 1; + return true; } for (auto it = m_IndexArray.begin() + m_iSeg; it != m_IndexArray.end(); @@ -262,7 +251,7 @@ int32_t CPDF_XRefStream::EndObjectStream(CPDF_Creator* pCreator, bool bEOF) { if (bEOF) m_ObjStream.Start(); - return 1; + return true; } bool CPDF_XRefStream::GenerateXRefStream(CPDF_Creator* pCreator, bool bEOF) { @@ -308,16 +297,12 @@ bool CPDF_XRefStream::GenerateXRefStream(CPDF_Creator* pCreator, bool bEOF) { } else { for (const auto& pair : m_IndexArray) { len = pFile->AppendDWord(pair.objnum); - if (len < 0) - return false; - if (pFile->AppendString(" ") < 0) + if (len < 0 || pFile->AppendString(" ") < 0) return false; pCreator->IncrementOffset(len + 1); len = pFile->AppendDWord(pair.count); - if (len < 0) - return false; - if (pFile->AppendString(" ") < 0) + if (len < 0 || pFile->AppendString(" ") < 0) return false; pCreator->IncrementOffset(len + 1); } @@ -361,8 +346,8 @@ bool CPDF_XRefStream::GenerateXRefStream(CPDF_Creator* pCreator, bool bEOF) { len = pFile->AppendDWord(encoder.GetSize()); if (len < 0) return false; - pCreator->IncrementOffset(len + 8); + if (bEOF) { len = WriteTrailer(pCreator->GetDocument(), pFile, pCreator->GetIDArray()); if (len < 0) @@ -399,7 +384,7 @@ bool CPDF_XRefStream::GenerateXRefStream(CPDF_Creator* pCreator, bool bEOF) { } bool CPDF_XRefStream::End(CPDF_Creator* pCreator, bool bEOF) { - if (EndObjectStream(pCreator, bEOF) < 0) + if (!EndObjectStream(pCreator, bEOF)) return false; return GenerateXRefStream(pCreator, bEOF); } diff --git a/core/fpdfapi/edit/cpdf_xrefstream.h b/core/fpdfapi/edit/cpdf_xrefstream.h index 2ca990732b..33869c656a 100644 --- a/core/fpdfapi/edit/cpdf_xrefstream.h +++ b/core/fpdfapi/edit/cpdf_xrefstream.h @@ -26,13 +26,13 @@ class CPDF_XRefStream { ~CPDF_XRefStream(); bool Start(); - int32_t CompressIndirectObject(uint32_t dwObjNum, - const CPDF_Object* pObj, - CPDF_Creator* pCreator); - int32_t CompressIndirectObject(uint32_t dwObjNum, - const uint8_t* pBuffer, - uint32_t dwSize, - CPDF_Creator* pCreator); + bool CompressIndirectObject(uint32_t dwObjNum, + const CPDF_Object* pObj, + CPDF_Creator* pCreator); + bool CompressIndirectObject(uint32_t dwObjNum, + const uint8_t* pBuffer, + uint32_t dwSize, + CPDF_Creator* pCreator); bool End(CPDF_Creator* pCreator, bool bEOF); void AddObjectNumberToIndexArray(uint32_t objnum); bool EndXRefStream(CPDF_Creator* pCreator); @@ -48,7 +48,7 @@ class CPDF_XRefStream { } private: - int32_t EndObjectStream(CPDF_Creator* pCreator, bool bEOF); + bool EndObjectStream(CPDF_Creator* pCreator, bool bEOF); bool GenerateXRefStream(CPDF_Creator* pCreator, bool bEOF); std::vector m_IndexArray; diff --git a/core/fxcrt/fx_basic_buffer.cpp b/core/fxcrt/fx_basic_buffer.cpp index 701676f71e..13057f1670 100644 --- a/core/fxcrt/fx_basic_buffer.cpp +++ b/core/fxcrt/fx_basic_buffer.cpp @@ -255,11 +255,9 @@ int32_t CFX_FileBufferArchive::AppendBlock(const void* pBuf, size_t size) { size_t buf_size = std::min(kBufSize - m_Length, temp_size); memcpy(m_pBuffer.get() + m_Length, buffer, buf_size); m_Length += buf_size; - if (m_Length == kBufSize) { - if (!Flush()) { - return -1; - } - } + if (m_Length == kBufSize && !Flush()) + return -1; + temp_size -= buf_size; buffer += buf_size; } -- cgit v1.2.3