| Index: core/src/fpdfapi/fpdf_edit/fpdf_edit_create.cpp
|
| diff --git a/core/src/fpdfapi/fpdf_edit/fpdf_edit_create.cpp b/core/src/fpdfapi/fpdf_edit/fpdf_edit_create.cpp
|
| index 2dc985413b1cbab90a11ff9857d29f85f34766c0..183baa23f5ec6ac0f1adc2537424cc63a11b0944 100644
|
| --- a/core/src/fpdfapi/fpdf_edit/fpdf_edit_create.cpp
|
| +++ b/core/src/fpdfapi/fpdf_edit/fpdf_edit_create.cpp
|
| @@ -4,7 +4,7 @@
|
|
|
| // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
|
|
|
| -#include "editint.h"
|
| +#include "core/src/fpdfapi/fpdf_edit/editint.h"
|
|
|
| #include "core/include/fxcrt/fx_ext.h"
|
| #include "core/include/fpdfapi/fpdf_serial.h"
|
| @@ -13,6 +13,8 @@
|
| #define PDF_OBJECTSTREAM_MAXLENGTH (256 * 1024)
|
| #define PDF_XREFSTREAM_MAXSIZE 10000
|
|
|
| +namespace {
|
| +
|
| int32_t PDF_CreatorAppendObject(const CPDF_Object* pObj,
|
| CFX_FileBufferArchive* pFile,
|
| FX_FILESIZE& offset) {
|
| @@ -169,6 +171,7 @@ int32_t PDF_CreatorAppendObject(const CPDF_Object* pObj,
|
| }
|
| return 1;
|
| }
|
| +
|
| int32_t PDF_CreatorWriteTrailer(CPDF_Document* pDocument,
|
| CFX_FileBufferArchive* pFile,
|
| CPDF_Array* pIDArray,
|
| @@ -259,6 +262,7 @@ int32_t PDF_CreatorWriteTrailer(CPDF_Document* pDocument,
|
| }
|
| return offset;
|
| }
|
| +
|
| int32_t PDF_CreatorWriteEncrypt(const CPDF_Dictionary* pEncryptDict,
|
| FX_DWORD dwObjNum,
|
| CFX_FileBufferArchive* pFile) {
|
| @@ -284,25 +288,89 @@ int32_t PDF_CreatorWriteEncrypt(const CPDF_Dictionary* pEncryptDict,
|
| offset += len + 6;
|
| return offset;
|
| }
|
| -FX_BOOL PDF_GenerateFileID(FX_DWORD dwSeed1,
|
| - FX_DWORD dwSeed2,
|
| - FX_DWORD* pBuffer) {
|
| - if (!pBuffer) {
|
| - return FALSE;
|
| - }
|
| +
|
| +std::vector<uint8_t> PDF_GenerateFileID(FX_DWORD dwSeed1, FX_DWORD dwSeed2) {
|
| + std::vector<uint8_t> buffer(sizeof(FX_DWORD) * 4);
|
| + FX_DWORD* pBuffer = reinterpret_cast<FX_DWORD*>(buffer.data());
|
| void* pContext = FX_Random_MT_Start(dwSeed1);
|
| - int32_t i = 0;
|
| - for (i = 0; i < 2; i++) {
|
| + for (int i = 0; i < 2; ++i)
|
| *pBuffer++ = FX_Random_MT_Generate(pContext);
|
| - }
|
| FX_Random_MT_Close(pContext);
|
| pContext = FX_Random_MT_Start(dwSeed2);
|
| - for (i = 0; i < 2; i++) {
|
| + for (int i = 0; i < 2; ++i)
|
| *pBuffer++ = FX_Random_MT_Generate(pContext);
|
| - }
|
| FX_Random_MT_Close(pContext);
|
| - return TRUE;
|
| + return buffer;
|
| +}
|
| +
|
| +void AppendIndex0(CFX_ByteTextBuf& buffer, bool bFirstObject) {
|
| + buffer.AppendByte(0);
|
| + buffer.AppendByte(0);
|
| + buffer.AppendByte(0);
|
| + buffer.AppendByte(0);
|
| + buffer.AppendByte(0);
|
| + const uint8_t byte = bFirstObject ? 0xFF : 0;
|
| + buffer.AppendByte(byte);
|
| + buffer.AppendByte(byte);
|
| +}
|
| +
|
| +void AppendIndex1(CFX_ByteTextBuf& buffer, FX_FILESIZE offset) {
|
| + buffer.AppendByte(1);
|
| + buffer.AppendByte(FX_GETBYTEOFFSET24(offset));
|
| + buffer.AppendByte(FX_GETBYTEOFFSET16(offset));
|
| + buffer.AppendByte(FX_GETBYTEOFFSET8(offset));
|
| + buffer.AppendByte(FX_GETBYTEOFFSET0(offset));
|
| + buffer.AppendByte(0);
|
| + buffer.AppendByte(0);
|
| +}
|
| +
|
| +void AppendIndex2(CFX_ByteTextBuf& buffer, FX_DWORD objnum, int32_t index) {
|
| + buffer.AppendByte(2);
|
| + buffer.AppendByte(FX_GETBYTEOFFSET24(objnum));
|
| + buffer.AppendByte(FX_GETBYTEOFFSET16(objnum));
|
| + buffer.AppendByte(FX_GETBYTEOFFSET8(objnum));
|
| + buffer.AppendByte(FX_GETBYTEOFFSET0(objnum));
|
| + buffer.AppendByte(FX_GETBYTEOFFSET8(index));
|
| + buffer.AppendByte(FX_GETBYTEOFFSET0(index));
|
| +}
|
| +
|
| +bool IsXRefNeedEnd(CPDF_XRefStream* pXRef, FX_DWORD flag) {
|
| + if (!(flag & FPDFCREATE_INCREMENTAL))
|
| + return false;
|
| +
|
| + int32_t iSize = pXRef->m_IndexArray.GetSize() / 2;
|
| + int32_t iCount = 0;
|
| + for (int32_t i = 0; i < iSize; ++i)
|
| + iCount += pXRef->m_IndexArray.ElementAt(i * 2 + 1);
|
| + return iCount >= PDF_XREFSTREAM_MAXSIZE;
|
| }
|
| +
|
| +int32_t OutputIndex(CFX_FileBufferArchive* pFile, FX_FILESIZE offset) {
|
| + if (sizeof(offset) > 4) {
|
| + if (FX_GETBYTEOFFSET32(offset)) {
|
| + if (pFile->AppendByte(FX_GETBYTEOFFSET56(offset)) < 0)
|
| + return -1;
|
| + if (pFile->AppendByte(FX_GETBYTEOFFSET48(offset)) < 0)
|
| + return -1;
|
| + if (pFile->AppendByte(FX_GETBYTEOFFSET40(offset)) < 0)
|
| + return -1;
|
| + if (pFile->AppendByte(FX_GETBYTEOFFSET32(offset)) < 0)
|
| + return -1;
|
| + }
|
| + }
|
| + if (pFile->AppendByte(FX_GETBYTEOFFSET24(offset)) < 0)
|
| + return -1;
|
| + if (pFile->AppendByte(FX_GETBYTEOFFSET16(offset)) < 0)
|
| + return -1;
|
| + if (pFile->AppendByte(FX_GETBYTEOFFSET8(offset)) < 0)
|
| + return -1;
|
| + if (pFile->AppendByte(FX_GETBYTEOFFSET0(offset)) < 0)
|
| + return -1;
|
| + if (pFile->AppendByte(0) < 0)
|
| + return -1;
|
| + return 0;
|
| +}
|
| +
|
| class CPDF_FlateEncoder {
|
| public:
|
| CPDF_FlateEncoder();
|
| @@ -433,6 +501,9 @@ CPDF_Encryptor::~CPDF_Encryptor() {
|
| FX_Free(m_pData);
|
| }
|
| }
|
| +
|
| +} // namespace
|
| +
|
| CPDF_ObjectStream::CPDF_ObjectStream() : m_dwObjNum(0), m_index(0) {}
|
| FX_BOOL CPDF_ObjectStream::Start() {
|
| m_ObjNumArray.RemoveAll();
|
| @@ -582,41 +653,7 @@ int32_t CPDF_XRefStream::CompressIndirectObject(FX_DWORD dwObjNum,
|
| }
|
| return EndObjectStream(pCreator);
|
| }
|
| -static void _AppendIndex0(CFX_ByteTextBuf& buffer,
|
| - FX_BOOL bFirstObject = TRUE) {
|
| - buffer.AppendByte(0);
|
| - buffer.AppendByte(0);
|
| - buffer.AppendByte(0);
|
| - buffer.AppendByte(0);
|
| - buffer.AppendByte(0);
|
| - if (bFirstObject) {
|
| - buffer.AppendByte(0xFF);
|
| - buffer.AppendByte(0xFF);
|
| - } else {
|
| - buffer.AppendByte(0);
|
| - buffer.AppendByte(0);
|
| - }
|
| -}
|
| -static void _AppendIndex1(CFX_ByteTextBuf& buffer, FX_FILESIZE offset) {
|
| - buffer.AppendByte(1);
|
| - buffer.AppendByte(FX_GETBYTEOFFSET24(offset));
|
| - buffer.AppendByte(FX_GETBYTEOFFSET16(offset));
|
| - buffer.AppendByte(FX_GETBYTEOFFSET8(offset));
|
| - buffer.AppendByte(FX_GETBYTEOFFSET0(offset));
|
| - buffer.AppendByte(0);
|
| - buffer.AppendByte(0);
|
| -}
|
| -static void _AppendIndex2(CFX_ByteTextBuf& buffer,
|
| - FX_DWORD objnum,
|
| - int32_t index) {
|
| - buffer.AppendByte(2);
|
| - buffer.AppendByte(FX_GETBYTEOFFSET24(objnum));
|
| - buffer.AppendByte(FX_GETBYTEOFFSET16(objnum));
|
| - buffer.AppendByte(FX_GETBYTEOFFSET8(objnum));
|
| - buffer.AppendByte(FX_GETBYTEOFFSET0(objnum));
|
| - buffer.AppendByte(FX_GETBYTEOFFSET8(index));
|
| - buffer.AppendByte(FX_GETBYTEOFFSET0(index));
|
| -}
|
| +
|
| int32_t CPDF_XRefStream::EndObjectStream(CPDF_Creator* pCreator, FX_BOOL bEOF) {
|
| FX_FILESIZE objOffset = 0;
|
| if (bEOF) {
|
| @@ -633,7 +670,7 @@ int32_t CPDF_XRefStream::EndObjectStream(CPDF_Creator* pCreator, FX_BOOL bEOF) {
|
| int32_t iSeg = m_IndexArray.GetSize() / 2;
|
| if (!(pCreator->m_dwFlags & FPDFCREATE_INCREMENTAL)) {
|
| if (m_dwTempObjNum == 0) {
|
| - _AppendIndex0(m_Buffer);
|
| + AppendIndex0(m_Buffer, true);
|
| m_dwTempObjNum++;
|
| }
|
| FX_DWORD end_num = m_IndexArray.GetAt((iSeg - 1) * 2) +
|
| @@ -644,12 +681,12 @@ int32_t CPDF_XRefStream::EndObjectStream(CPDF_Creator* pCreator, FX_BOOL bEOF) {
|
| if (offset) {
|
| if (index >= iSize ||
|
| m_dwTempObjNum != m_ObjStream.m_ObjNumArray[index]) {
|
| - _AppendIndex1(m_Buffer, *offset);
|
| + AppendIndex1(m_Buffer, *offset);
|
| } else {
|
| - _AppendIndex2(m_Buffer, dwObjStmNum, index++);
|
| + AppendIndex2(m_Buffer, dwObjStmNum, index++);
|
| }
|
| } else {
|
| - _AppendIndex0(m_Buffer, FALSE);
|
| + AppendIndex0(m_Buffer, false);
|
| }
|
| }
|
| if (iSize > 0 && bEOF) {
|
| @@ -668,14 +705,14 @@ int32_t CPDF_XRefStream::EndObjectStream(CPDF_Creator* pCreator, FX_BOOL bEOF) {
|
| FX_DWORD end = m_IndexArray.ElementAt(i * 2 + 1) + start;
|
| for (FX_DWORD m = start; m < end; m++) {
|
| if (j >= iSize || m != m_ObjStream.m_ObjNumArray.ElementAt(j)) {
|
| - _AppendIndex1(m_Buffer, pCreator->m_ObjectOffset[m]);
|
| + AppendIndex1(m_Buffer, pCreator->m_ObjectOffset[m]);
|
| } else {
|
| - _AppendIndex2(m_Buffer, dwObjStmNum, j++);
|
| + AppendIndex2(m_Buffer, dwObjStmNum, j++);
|
| }
|
| }
|
| }
|
| if (iSize > 0 && bEOF) {
|
| - _AppendIndex1(m_Buffer, objOffset);
|
| + AppendIndex1(m_Buffer, objOffset);
|
| m_IndexArray.Add(dwObjStmNum);
|
| m_IndexArray.Add(1);
|
| iSeg += 1;
|
| @@ -698,13 +735,13 @@ FX_BOOL CPDF_XRefStream::GenerateXRefStream(CPDF_Creator* pCreator,
|
| for (; m_dwTempObjNum < pCreator->m_dwLastObjNum; m_dwTempObjNum++) {
|
| FX_FILESIZE* offset = pCreator->m_ObjectOffset.GetPtrAt(m_dwTempObjNum);
|
| if (offset) {
|
| - _AppendIndex1(m_Buffer, *offset);
|
| + AppendIndex1(m_Buffer, *offset);
|
| } else {
|
| - _AppendIndex0(m_Buffer, FALSE);
|
| + AppendIndex0(m_Buffer, false);
|
| }
|
| }
|
| }
|
| - _AppendIndex1(m_Buffer, offset_tmp);
|
| + AppendIndex1(m_Buffer, offset_tmp);
|
| FX_FILESIZE& offset = pCreator->m_Offset;
|
| int32_t len = pFile->AppendDWord(objnum);
|
| if (len < 0) {
|
| @@ -832,13 +869,13 @@ FX_BOOL CPDF_XRefStream::End(CPDF_Creator* pCreator, FX_BOOL bEOF) {
|
| }
|
| FX_BOOL CPDF_XRefStream::EndXRefStream(CPDF_Creator* pCreator) {
|
| if (!(pCreator->m_dwFlags & FPDFCREATE_INCREMENTAL)) {
|
| - _AppendIndex0(m_Buffer);
|
| + AppendIndex0(m_Buffer, true);
|
| for (FX_DWORD i = 1; i < pCreator->m_dwLastObjNum + 1; i++) {
|
| FX_FILESIZE* offset = pCreator->m_ObjectOffset.GetPtrAt(i);
|
| if (offset) {
|
| - _AppendIndex1(m_Buffer, *offset);
|
| + AppendIndex1(m_Buffer, *offset);
|
| } else {
|
| - _AppendIndex0(m_Buffer, FALSE);
|
| + AppendIndex0(m_Buffer, false);
|
| }
|
| }
|
| } else {
|
| @@ -847,7 +884,7 @@ FX_BOOL CPDF_XRefStream::EndXRefStream(CPDF_Creator* pCreator) {
|
| FX_DWORD start = m_IndexArray.ElementAt(i * 2);
|
| FX_DWORD end = m_IndexArray.ElementAt(i * 2 + 1) + start;
|
| for (FX_DWORD j = start; j < end; j++) {
|
| - _AppendIndex1(m_Buffer, pCreator->m_ObjectOffset[j]);
|
| + AppendIndex1(m_Buffer, pCreator->m_ObjectOffset[j]);
|
| }
|
| }
|
| }
|
| @@ -908,17 +945,7 @@ CPDF_Creator::~CPDF_Creator() {
|
| }
|
| Clear();
|
| }
|
| -static FX_BOOL _IsXRefNeedEnd(CPDF_XRefStream* pXRef, FX_DWORD flag) {
|
| - if (!(flag & FPDFCREATE_INCREMENTAL)) {
|
| - return FALSE;
|
| - }
|
| - int32_t iSize = pXRef->m_IndexArray.GetSize() / 2;
|
| - int32_t iCount = 0;
|
| - for (int32_t i = 0; i < iSize; i++) {
|
| - iCount += pXRef->m_IndexArray.ElementAt(i * 2 + 1);
|
| - }
|
| - return (iCount >= PDF_XREFSTREAM_MAXSIZE);
|
| -}
|
| +
|
| int32_t CPDF_Creator::WriteIndirectObjectToStream(const CPDF_Object* pObj) {
|
| if (!m_pXRefStream)
|
| return 1;
|
| @@ -933,10 +960,11 @@ int32_t CPDF_Creator::WriteIndirectObjectToStream(const CPDF_Object* pObj) {
|
| return 1;
|
|
|
| CPDF_Dictionary* pDict = pObj->GetDict();
|
| - if (pObj->IsStream())
|
| + if (pObj->IsStream()) {
|
| if (pDict && pDict->GetString("Type") == "XRef")
|
| return 0;
|
| return 1;
|
| + }
|
|
|
| if (pDict) {
|
| if (pDict == m_pDocument->m_pRootDict || pDict == m_pEncryptDict)
|
| @@ -950,7 +978,7 @@ int32_t CPDF_Creator::WriteIndirectObjectToStream(const CPDF_Object* pObj) {
|
| m_pXRefStream->AddObjectNumberToIndexArray(objnum);
|
| if (m_pXRefStream->CompressIndirectObject(objnum, pObj, this) < 0)
|
| return -1;
|
| - if (!_IsXRefNeedEnd(m_pXRefStream, m_dwFlags))
|
| + if (!IsXRefNeedEnd(m_pXRefStream, m_dwFlags))
|
| return 0;
|
| if (!m_pXRefStream->End(this))
|
| return -1;
|
| @@ -970,7 +998,7 @@ int32_t CPDF_Creator::WriteIndirectObjectToStream(FX_DWORD objnum,
|
| if (iRet < 1) {
|
| return iRet;
|
| }
|
| - if (!_IsXRefNeedEnd(m_pXRefStream, m_dwFlags)) {
|
| + if (!IsXRefNeedEnd(m_pXRefStream, m_dwFlags)) {
|
| return 0;
|
| }
|
| if (!m_pXRefStream->End(this)) {
|
| @@ -986,7 +1014,7 @@ int32_t CPDF_Creator::AppendObjectNumberToXRef(FX_DWORD objnum) {
|
| return 1;
|
| }
|
| m_pXRefStream->AddObjectNumberToIndexArray(objnum);
|
| - if (!_IsXRefNeedEnd(m_pXRefStream, m_dwFlags)) {
|
| + if (!IsXRefNeedEnd(m_pXRefStream, m_dwFlags)) {
|
| return 0;
|
| }
|
| if (!m_pXRefStream->End(this)) {
|
| @@ -1723,41 +1751,7 @@ int32_t CPDF_Creator::WriteDoc_Stage3(IFX_Pause* pPause) {
|
| }
|
| return m_iStage;
|
| }
|
| -static int32_t _OutPutIndex(CFX_FileBufferArchive* pFile, FX_FILESIZE offset) {
|
| - FXSYS_assert(pFile);
|
| - if (sizeof(offset) > 4) {
|
| - if (FX_GETBYTEOFFSET32(offset)) {
|
| - if (pFile->AppendByte(FX_GETBYTEOFFSET56(offset)) < 0) {
|
| - return -1;
|
| - }
|
| - if (pFile->AppendByte(FX_GETBYTEOFFSET48(offset)) < 0) {
|
| - return -1;
|
| - }
|
| - if (pFile->AppendByte(FX_GETBYTEOFFSET40(offset)) < 0) {
|
| - return -1;
|
| - }
|
| - if (pFile->AppendByte(FX_GETBYTEOFFSET32(offset)) < 0) {
|
| - return -1;
|
| - }
|
| - }
|
| - }
|
| - if (pFile->AppendByte(FX_GETBYTEOFFSET24(offset)) < 0) {
|
| - return -1;
|
| - }
|
| - if (pFile->AppendByte(FX_GETBYTEOFFSET16(offset)) < 0) {
|
| - return -1;
|
| - }
|
| - if (pFile->AppendByte(FX_GETBYTEOFFSET8(offset)) < 0) {
|
| - return -1;
|
| - }
|
| - if (pFile->AppendByte(FX_GETBYTEOFFSET0(offset)) < 0) {
|
| - return -1;
|
| - }
|
| - if (pFile->AppendByte(0) < 0) {
|
| - return -1;
|
| - }
|
| - return 0;
|
| -}
|
| +
|
| int32_t CPDF_Creator::WriteDoc_Stage4(IFX_Pause* pPause) {
|
| FXSYS_assert(m_iStage >= 90);
|
| if ((m_dwFlags & FPDFCREATE_OBJECTSTREAM) == 0) {
|
| @@ -1914,7 +1908,7 @@ int32_t CPDF_Creator::WriteDoc_Stage4(IFX_Pause* pPause) {
|
| if (!offset) {
|
| continue;
|
| }
|
| - _OutPutIndex(&m_File, *offset);
|
| + OutputIndex(&m_File, *offset);
|
| }
|
| } else {
|
| int count = m_NewObjNumArray.GetSize();
|
| @@ -1940,7 +1934,7 @@ int32_t CPDF_Creator::WriteDoc_Stage4(IFX_Pause* pPause) {
|
| for (i = 0; i < count; i++) {
|
| FX_DWORD objnum = m_NewObjNumArray.ElementAt(i);
|
| FX_FILESIZE offset = m_ObjectOffset[objnum];
|
| - _OutPutIndex(&m_File, offset);
|
| + OutputIndex(&m_File, offset);
|
| }
|
| }
|
| if (m_File.AppendString("\r\nendstream") < 0) {
|
| @@ -1999,18 +1993,16 @@ void CPDF_Creator::InitID(FX_BOOL bDefault) {
|
| CPDF_Array* pOldIDArray = m_pParser ? m_pParser->GetIDArray() : NULL;
|
| FX_BOOL bNewId = !m_pIDArray;
|
| if (!m_pIDArray) {
|
| - FX_DWORD* pBuffer = NULL;
|
| m_pIDArray = new CPDF_Array;
|
| CPDF_Object* pID1 = pOldIDArray ? pOldIDArray->GetElement(0) : NULL;
|
| if (pID1) {
|
| m_pIDArray->Add(pID1->Clone());
|
| } else {
|
| - pBuffer = FX_Alloc(FX_DWORD, 4);
|
| - PDF_GenerateFileID((FX_DWORD)(uintptr_t) this, m_dwLastObjNum, pBuffer);
|
| - CFX_ByteStringC bsBuffer((const uint8_t*)pBuffer, 4 * sizeof(FX_DWORD));
|
| + std::vector<uint8_t> buffer =
|
| + PDF_GenerateFileID((FX_DWORD)(uintptr_t) this, m_dwLastObjNum);
|
| + CFX_ByteStringC bsBuffer(buffer.data(), buffer.size());
|
| m_pIDArray->Add(new CPDF_String(bsBuffer, TRUE), m_pDocument);
|
| }
|
| - FX_Free(pBuffer);
|
| }
|
| if (!bDefault) {
|
| return;
|
| @@ -2021,11 +2013,10 @@ void CPDF_Creator::InitID(FX_BOOL bDefault) {
|
| m_pIDArray->Add(pID2->Clone());
|
| return;
|
| }
|
| - FX_DWORD* pBuffer = FX_Alloc(FX_DWORD, 4);
|
| - PDF_GenerateFileID((FX_DWORD)(uintptr_t) this, m_dwLastObjNum, pBuffer);
|
| - CFX_ByteStringC bsBuffer((const uint8_t*)pBuffer, 4 * sizeof(FX_DWORD));
|
| + std::vector<uint8_t> buffer =
|
| + PDF_GenerateFileID((FX_DWORD)(uintptr_t) this, m_dwLastObjNum);
|
| + CFX_ByteStringC bsBuffer(buffer.data(), buffer.size());
|
| m_pIDArray->Add(new CPDF_String(bsBuffer, TRUE), m_pDocument);
|
| - FX_Free(pBuffer);
|
| return;
|
| }
|
| m_pIDArray->Add(m_pIDArray->GetElement(0)->Clone());
|
|
|