Chromium Code Reviews| 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..5bba36a059b894ff87b2dae8391a19336412aa46 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,104 @@ 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; |
| - } |
| + |
| +void PDF_GenerateFileID(FX_DWORD dwSeed1, |
| + FX_DWORD dwSeed2, |
| + std::vector<uint8_t>* buffer) { |
|
Tom Sepez
2016/01/07 17:27:02
nit: does RVO allow us to return this as a result
Lei Zhang
2016/01/08 02:54:30
Done.
|
| + buffer->resize(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) |
|
Tom Sepez
2016/01/07 17:27:02
nit: worth unrolling this loop into two calls?
Lei Zhang
2016/01/08 02:54:30
Let the compiler figure it out?
Tom Sepez
2016/01/08 17:01:45
Nah, nothing to do with efficiency, I thought it r
|
| *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; |
| } |
| + |
| +void AppendIndex0(CFX_ByteTextBuf& buffer, bool bFirstObject) { |
| + buffer.AppendByte(0); |
| + buffer.AppendByte(0); |
| + buffer.AppendByte(0); |
| + buffer.AppendByte(0); |
| + buffer.AppendByte(0); |
| + if (bFirstObject) { |
|
Tom Sepez
2016/01/07 17:27:02
nit: maybe
uint8_t byte = bFirstObject ? 0xFF :
Lei Zhang
2016/01/08 02:54:30
Done.
|
| + buffer.AppendByte(0xFF); |
| + buffer.AppendByte(0xFF); |
| + } else { |
| + buffer.AppendByte(0); |
| + buffer.AppendByte(0); |
| + } |
| +} |
| + |
| +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) { |
|
Tom Sepez
2016/01/07 17:27:02
nit: OutputIndex
Lei Zhang
2016/01/08 02:54:30
Done.
|
| + FXSYS_assert(pFile); |
|
Tom Sepez
2016/01/07 17:27:02
nit: not needed.
Lei Zhang
2016/01/08 02:54:30
Done.
|
| + if (sizeof(offset) > 4) { |
| + if (FX_GETBYTEOFFSET32(offset)) { |
| + if (pFile->AppendByte(FX_GETBYTEOFFSET56(offset)) < 0) { |
|
Tom Sepez
2016/01/07 17:27:02
nit: {} not required.
Lei Zhang
2016/01/08 02:54:30
Done.
|
| + 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 +516,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 +668,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 +685,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 +696,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 +720,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 +750,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 +884,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 +899,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 +960,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; |
| @@ -950,7 +992,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 +1012,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 +1028,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 +1765,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 +1922,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 +1948,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 +2007,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, &buffer); |
| + 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 +2027,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, &buffer); |
| + 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()); |