OLD | NEW |
1 // Copyright 2014 PDFium Authors. All rights reserved. | 1 // Copyright 2014 PDFium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
6 | 6 |
7 #include "core/fpdfapi/fpdf_edit/editint.h" | 7 #include "core/fpdfapi/fpdf_edit/editint.h" |
8 | 8 |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
(...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
381 if (pFile->AppendByte(0) < 0) | 381 if (pFile->AppendByte(0) < 0) |
382 return -1; | 382 return -1; |
383 return 0; | 383 return 0; |
384 } | 384 } |
385 | 385 |
386 class CPDF_FlateEncoder { | 386 class CPDF_FlateEncoder { |
387 public: | 387 public: |
388 CPDF_FlateEncoder(CPDF_Stream* pStream, FX_BOOL bFlateEncode); | 388 CPDF_FlateEncoder(CPDF_Stream* pStream, FX_BOOL bFlateEncode); |
389 CPDF_FlateEncoder(const uint8_t* pBuffer, | 389 CPDF_FlateEncoder(const uint8_t* pBuffer, |
390 uint32_t size, | 390 uint32_t size, |
391 FX_BOOL bFlateEncode, | 391 bool bFlateEncode, |
392 FX_BOOL bXRefStream = FALSE); | 392 bool bXRefStream); |
393 ~CPDF_FlateEncoder(); | 393 ~CPDF_FlateEncoder(); |
394 | 394 |
395 void CloneDict(); | 395 void CloneDict(); |
396 | 396 |
397 uint8_t* m_pData; | 397 uint8_t* m_pData; |
398 uint32_t m_dwSize; | 398 uint32_t m_dwSize; |
399 CPDF_Dictionary* m_pDict; | 399 CPDF_Dictionary* m_pDict; |
400 FX_BOOL m_bCloned; | 400 FX_BOOL m_bCloned; |
401 FX_BOOL m_bNewData; | 401 FX_BOOL m_bNewData; |
402 CPDF_StreamAcc m_Acc; | 402 CPDF_StreamAcc m_Acc; |
(...skipping 29 matching lines...) Expand all Loading... |
432 } else { | 432 } else { |
433 m_pData = (uint8_t*)m_Acc.GetData(); | 433 m_pData = (uint8_t*)m_Acc.GetData(); |
434 m_dwSize = m_Acc.GetSize(); | 434 m_dwSize = m_Acc.GetSize(); |
435 m_pDict = pStream->GetDict(); | 435 m_pDict = pStream->GetDict(); |
436 } | 436 } |
437 return; | 437 return; |
438 } | 438 } |
439 | 439 |
440 m_bNewData = TRUE; | 440 m_bNewData = TRUE; |
441 m_bCloned = TRUE; | 441 m_bCloned = TRUE; |
442 ::FlateEncode(m_Acc.GetData(), m_Acc.GetSize(), m_pData, m_dwSize); | 442 // TODO(thestig): Move to Init() and check return value. |
| 443 ::FlateEncode(m_Acc.GetData(), m_Acc.GetSize(), &m_pData, &m_dwSize); |
443 m_pDict = ToDictionary(pStream->GetDict()->Clone()); | 444 m_pDict = ToDictionary(pStream->GetDict()->Clone()); |
444 m_pDict->SetAtInteger("Length", m_dwSize); | 445 m_pDict->SetAtInteger("Length", m_dwSize); |
445 m_pDict->SetAtName("Filter", "FlateDecode"); | 446 m_pDict->SetAtName("Filter", "FlateDecode"); |
446 m_pDict->RemoveAt("DecodeParms"); | 447 m_pDict->RemoveAt("DecodeParms"); |
447 } | 448 } |
448 | 449 |
449 CPDF_FlateEncoder::CPDF_FlateEncoder(const uint8_t* pBuffer, | 450 CPDF_FlateEncoder::CPDF_FlateEncoder(const uint8_t* pBuffer, |
450 uint32_t size, | 451 uint32_t size, |
451 FX_BOOL bFlateEncode, | 452 bool bFlateEncode, |
452 FX_BOOL bXRefStream) | 453 bool bXRefStream) |
453 : m_pData(nullptr), | 454 : m_pData(nullptr), |
454 m_dwSize(0), | 455 m_dwSize(0), |
455 m_pDict(nullptr), | 456 m_pDict(nullptr), |
456 m_bCloned(FALSE), | 457 m_bCloned(FALSE), |
457 m_bNewData(FALSE) { | 458 m_bNewData(FALSE) { |
458 if (!bFlateEncode) { | 459 if (!bFlateEncode) { |
459 m_pData = (uint8_t*)pBuffer; | 460 m_pData = (uint8_t*)pBuffer; |
460 m_dwSize = size; | 461 m_dwSize = size; |
461 return; | 462 return; |
462 } | 463 } |
463 m_bNewData = TRUE; | 464 m_bNewData = TRUE; |
| 465 // TODO(thestig): Move to Init() and check return value. |
464 if (bXRefStream) | 466 if (bXRefStream) |
465 ::FlateEncode(pBuffer, size, 12, 1, 8, 7, m_pData, m_dwSize); | 467 ::PngEncode(pBuffer, size, &m_pData, &m_dwSize); |
466 else | 468 else |
467 ::FlateEncode(pBuffer, size, m_pData, m_dwSize); | 469 ::FlateEncode(pBuffer, size, &m_pData, &m_dwSize); |
468 } | 470 } |
469 | 471 |
470 CPDF_FlateEncoder::~CPDF_FlateEncoder() { | 472 CPDF_FlateEncoder::~CPDF_FlateEncoder() { |
471 if (m_bCloned && m_pDict) | 473 if (m_bCloned && m_pDict) |
472 m_pDict->Release(); | 474 m_pDict->Release(); |
473 if (m_bNewData) | 475 if (m_bNewData) |
474 FX_Free(m_pData); | 476 FX_Free(m_pData); |
475 } | 477 } |
476 | 478 |
477 class CPDF_Encryptor { | 479 class CPDF_Encryptor { |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
570 if ((len = pFile->AppendDWord((uint32_t)tempBuffer.GetLength())) < 0) { | 572 if ((len = pFile->AppendDWord((uint32_t)tempBuffer.GetLength())) < 0) { |
571 return -1; | 573 return -1; |
572 } | 574 } |
573 if (pFile->AppendString("/Length ") < 0) { | 575 if (pFile->AppendString("/Length ") < 0) { |
574 return -1; | 576 return -1; |
575 } | 577 } |
576 offset += len + 15; | 578 offset += len + 15; |
577 | 579 |
578 tempBuffer << m_Buffer; | 580 tempBuffer << m_Buffer; |
579 CPDF_FlateEncoder encoder(tempBuffer.GetBuffer(), tempBuffer.GetLength(), | 581 CPDF_FlateEncoder encoder(tempBuffer.GetBuffer(), tempBuffer.GetLength(), |
580 TRUE); | 582 true, false); |
581 CPDF_Encryptor encryptor(pCreator->m_pCryptoHandler, m_dwObjNum, | 583 CPDF_Encryptor encryptor(pCreator->m_pCryptoHandler, m_dwObjNum, |
582 encoder.m_pData, encoder.m_dwSize); | 584 encoder.m_pData, encoder.m_dwSize); |
583 if ((len = pFile->AppendDWord(encryptor.m_dwSize)) < 0) { | 585 if ((len = pFile->AppendDWord(encryptor.m_dwSize)) < 0) { |
584 return -1; | 586 return -1; |
585 } | 587 } |
586 offset += len; | 588 offset += len; |
587 if (pFile->AppendString("/Filter /FlateDecode") < 0) { | 589 if (pFile->AppendString("/Filter /FlateDecode") < 0) { |
588 return -1; | 590 return -1; |
589 } | 591 } |
590 offset += 20; | 592 offset += 20; |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
778 } | 780 } |
779 FX_CHAR offset_buf[20]; | 781 FX_CHAR offset_buf[20]; |
780 FXSYS_memset(offset_buf, 0, sizeof(offset_buf)); | 782 FXSYS_memset(offset_buf, 0, sizeof(offset_buf)); |
781 FXSYS_i64toa(m_PrevOffset, offset_buf, 10); | 783 FXSYS_i64toa(m_PrevOffset, offset_buf, 10); |
782 int32_t offset_len = (int32_t)FXSYS_strlen(offset_buf); | 784 int32_t offset_len = (int32_t)FXSYS_strlen(offset_buf); |
783 if (pFile->AppendBlock(offset_buf, offset_len) < 0) { | 785 if (pFile->AppendBlock(offset_buf, offset_len) < 0) { |
784 return FALSE; | 786 return FALSE; |
785 } | 787 } |
786 offset += offset_len + 6; | 788 offset += offset_len + 6; |
787 } | 789 } |
788 FX_BOOL bPredictor = TRUE; | |
789 CPDF_FlateEncoder encoder(m_Buffer.GetBuffer(), m_Buffer.GetLength(), TRUE, | 790 CPDF_FlateEncoder encoder(m_Buffer.GetBuffer(), m_Buffer.GetLength(), TRUE, |
790 bPredictor); | 791 TRUE); |
791 if (pFile->AppendString("/Filter /FlateDecode") < 0) { | 792 if (pFile->AppendString("/Filter /FlateDecode") < 0) |
| 793 return FALSE; |
| 794 |
| 795 offset += 20; |
| 796 if ((len = pFile->AppendString("/DecodeParms<</Columns 7/Predictor 12>>")) < |
| 797 0) { |
792 return FALSE; | 798 return FALSE; |
793 } | 799 } |
794 offset += 20; | 800 |
795 if (bPredictor) { | 801 offset += len; |
796 if ((len = pFile->AppendString("/DecodeParms<</Columns 7/Predictor 12>>")) < | 802 if (pFile->AppendString("/Length ") < 0) |
797 0) { | |
798 return FALSE; | |
799 } | |
800 offset += len; | |
801 } | |
802 if (pFile->AppendString("/Length ") < 0) { | |
803 return FALSE; | 803 return FALSE; |
804 } | 804 |
805 if ((len = pFile->AppendDWord(encoder.m_dwSize)) < 0) { | 805 if ((len = pFile->AppendDWord(encoder.m_dwSize)) < 0) |
806 return FALSE; | 806 return FALSE; |
807 } | 807 |
808 offset += len + 8; | 808 offset += len + 8; |
809 if (bEOF) { | 809 if (bEOF) { |
810 if ((len = PDF_CreatorWriteTrailer(pCreator->m_pDocument, pFile, | 810 if ((len = PDF_CreatorWriteTrailer(pCreator->m_pDocument, pFile, |
811 pCreator->m_pIDArray)) < 0) { | 811 pCreator->m_pIDArray)) < 0) { |
812 return FALSE; | 812 return FALSE; |
813 } | 813 } |
814 offset += len; | 814 offset += len; |
815 if (pCreator->m_pEncryptDict) { | 815 if (pCreator->m_pEncryptDict) { |
816 uint32_t dwEncryptObjNum = pCreator->m_pEncryptDict->GetObjNum(); | 816 uint32_t dwEncryptObjNum = pCreator->m_pEncryptDict->GetObjNum(); |
817 if (dwEncryptObjNum == 0) { | 817 if (dwEncryptObjNum == 0) { |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
892 m_dwFlags(0), | 892 m_dwFlags(0), |
893 m_Pos(nullptr), | 893 m_Pos(nullptr), |
894 m_XrefStart(0), | 894 m_XrefStart(0), |
895 m_pIDArray(nullptr), | 895 m_pIDArray(nullptr), |
896 m_FileVersion(0) {} | 896 m_FileVersion(0) {} |
897 | 897 |
898 CPDF_Creator::~CPDF_Creator() { | 898 CPDF_Creator::~CPDF_Creator() { |
899 ResetStandardSecurity(); | 899 ResetStandardSecurity(); |
900 if (m_bEncryptCloned && m_pEncryptDict) { | 900 if (m_bEncryptCloned && m_pEncryptDict) { |
901 m_pEncryptDict->Release(); | 901 m_pEncryptDict->Release(); |
902 m_pEncryptDict = NULL; | 902 m_pEncryptDict = nullptr; |
903 } | 903 } |
904 Clear(); | 904 Clear(); |
905 } | 905 } |
906 | 906 |
907 int32_t CPDF_Creator::WriteIndirectObjectToStream(const CPDF_Object* pObj) { | 907 int32_t CPDF_Creator::WriteIndirectObjectToStream(const CPDF_Object* pObj) { |
908 if (!m_pXRefStream) | 908 if (!m_pXRefStream) |
909 return 1; | 909 return 1; |
910 | 910 |
911 uint32_t objnum = pObj->GetObjNum(); | 911 uint32_t objnum = pObj->GetObjNum(); |
912 if (m_pParser && m_pParser->GetObjectGenNum(objnum) > 0) | 912 if (m_pParser && m_pParser->GetObjectGenNum(objnum) > 0) |
(...skipping 521 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1434 int32_t CPDF_Creator::WriteDoc_Stage1(IFX_Pause* pPause) { | 1434 int32_t CPDF_Creator::WriteDoc_Stage1(IFX_Pause* pPause) { |
1435 ASSERT(m_iStage > -1 || m_iStage < 20); | 1435 ASSERT(m_iStage > -1 || m_iStage < 20); |
1436 if (m_iStage == 0) { | 1436 if (m_iStage == 0) { |
1437 if (!m_pParser) { | 1437 if (!m_pParser) { |
1438 m_dwFlags &= ~FPDFCREATE_INCREMENTAL; | 1438 m_dwFlags &= ~FPDFCREATE_INCREMENTAL; |
1439 } | 1439 } |
1440 if (m_bSecurityChanged && (m_dwFlags & FPDFCREATE_NO_ORIGINAL) == 0) { | 1440 if (m_bSecurityChanged && (m_dwFlags & FPDFCREATE_NO_ORIGINAL) == 0) { |
1441 m_dwFlags &= ~FPDFCREATE_INCREMENTAL; | 1441 m_dwFlags &= ~FPDFCREATE_INCREMENTAL; |
1442 } | 1442 } |
1443 CPDF_Dictionary* pDict = m_pDocument->GetRoot(); | 1443 CPDF_Dictionary* pDict = m_pDocument->GetRoot(); |
1444 m_pMetadata = pDict ? pDict->GetDirectObjectBy("Metadata") : NULL; | 1444 m_pMetadata = pDict ? pDict->GetDirectObjectBy("Metadata") : nullptr; |
1445 if (m_dwFlags & FPDFCREATE_OBJECTSTREAM) { | 1445 if (m_dwFlags & FPDFCREATE_OBJECTSTREAM) { |
1446 m_pXRefStream.reset(new CPDF_XRefStream); | 1446 m_pXRefStream.reset(new CPDF_XRefStream); |
1447 m_pXRefStream->Start(); | 1447 m_pXRefStream->Start(); |
1448 if ((m_dwFlags & FPDFCREATE_INCREMENTAL) != 0 && m_pParser) { | 1448 if ((m_dwFlags & FPDFCREATE_INCREMENTAL) != 0 && m_pParser) { |
1449 FX_FILESIZE prev = m_pParser->GetLastXRefOffset(); | 1449 FX_FILESIZE prev = m_pParser->GetLastXRefOffset(); |
1450 m_pXRefStream->m_PrevOffset = prev; | 1450 m_pXRefStream->m_PrevOffset = prev; |
1451 } | 1451 } |
1452 } | 1452 } |
1453 m_iStage = 10; | 1453 m_iStage = 10; |
1454 } | 1454 } |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1549 } | 1549 } |
1550 if (m_iStage == 26) { | 1550 if (m_iStage == 26) { |
1551 int32_t iRet = | 1551 int32_t iRet = |
1552 WriteNewObjs((m_dwFlags & FPDFCREATE_INCREMENTAL) != 0, pPause); | 1552 WriteNewObjs((m_dwFlags & FPDFCREATE_INCREMENTAL) != 0, pPause); |
1553 if (iRet) { | 1553 if (iRet) { |
1554 return iRet; | 1554 return iRet; |
1555 } | 1555 } |
1556 m_iStage = 27; | 1556 m_iStage = 27; |
1557 } | 1557 } |
1558 if (m_iStage == 27) { | 1558 if (m_iStage == 27) { |
1559 if (NULL != m_pEncryptDict && 0 == m_pEncryptDict->GetObjNum()) { | 1559 if (m_pEncryptDict && !m_pEncryptDict->GetObjNum()) { |
1560 m_dwLastObjNum += 1; | 1560 m_dwLastObjNum += 1; |
1561 FX_FILESIZE saveOffset = m_Offset; | 1561 FX_FILESIZE saveOffset = m_Offset; |
1562 if (WriteIndirectObj(m_dwLastObjNum, m_pEncryptDict) < 0) { | 1562 if (WriteIndirectObj(m_dwLastObjNum, m_pEncryptDict) < 0) { |
1563 return -1; | 1563 return -1; |
1564 } | 1564 } |
1565 m_ObjectOffset.Add(m_dwLastObjNum, 1); | 1565 m_ObjectOffset.Add(m_dwLastObjNum, 1); |
1566 m_ObjectOffset[m_dwLastObjNum] = saveOffset; | 1566 m_ObjectOffset[m_dwLastObjNum] = saveOffset; |
1567 m_dwEncryptObjNum = m_dwLastObjNum; | 1567 m_dwEncryptObjNum = m_dwLastObjNum; |
1568 if (m_dwFlags & FPDFCREATE_INCREMENTAL) { | 1568 if (m_dwFlags & FPDFCREATE_INCREMENTAL) { |
1569 m_NewObjNumArray.Add(m_dwLastObjNum); | 1569 m_NewObjNumArray.Add(m_dwLastObjNum); |
(...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1886 FXSYS_i64toa(m_XrefStart, offset_buf, 10); | 1886 FXSYS_i64toa(m_XrefStart, offset_buf, 10); |
1887 if (m_File.AppendBlock(offset_buf, FXSYS_strlen(offset_buf)) < 0) { | 1887 if (m_File.AppendBlock(offset_buf, FXSYS_strlen(offset_buf)) < 0) { |
1888 return -1; | 1888 return -1; |
1889 } | 1889 } |
1890 if (m_File.AppendString("\r\n%%EOF\r\n") < 0) { | 1890 if (m_File.AppendString("\r\n%%EOF\r\n") < 0) { |
1891 return -1; | 1891 return -1; |
1892 } | 1892 } |
1893 m_File.Flush(); | 1893 m_File.Flush(); |
1894 return m_iStage = 100; | 1894 return m_iStage = 100; |
1895 } | 1895 } |
| 1896 |
1896 void CPDF_Creator::Clear() { | 1897 void CPDF_Creator::Clear() { |
1897 m_pXRefStream.reset(); | 1898 m_pXRefStream.reset(); |
1898 m_File.Clear(); | 1899 m_File.Clear(); |
1899 m_NewObjNumArray.RemoveAll(); | 1900 m_NewObjNumArray.RemoveAll(); |
1900 if (m_pIDArray) { | 1901 if (m_pIDArray) { |
1901 m_pIDArray->Release(); | 1902 m_pIDArray->Release(); |
1902 m_pIDArray = NULL; | 1903 m_pIDArray = nullptr; |
1903 } | 1904 } |
1904 } | 1905 } |
1905 | 1906 |
1906 bool CPDF_Creator::Create(IFX_StreamWrite* pFile, uint32_t flags) { | 1907 bool CPDF_Creator::Create(IFX_StreamWrite* pFile, uint32_t flags) { |
1907 m_File.AttachFile(pFile); | 1908 m_File.AttachFile(pFile); |
1908 return Create(flags); | 1909 return Create(flags); |
1909 } | 1910 } |
1910 | 1911 |
1911 bool CPDF_Creator::Create(uint32_t flags) { | 1912 bool CPDF_Creator::Create(uint32_t flags) { |
1912 m_dwFlags = flags; | 1913 m_dwFlags = flags; |
1913 m_iStage = 0; | 1914 m_iStage = 0; |
1914 m_Offset = 0; | 1915 m_Offset = 0; |
1915 m_dwLastObjNum = m_pDocument->GetLastObjNum(); | 1916 m_dwLastObjNum = m_pDocument->GetLastObjNum(); |
1916 m_ObjectOffset.Clear(); | 1917 m_ObjectOffset.Clear(); |
1917 m_NewObjNumArray.RemoveAll(); | 1918 m_NewObjNumArray.RemoveAll(); |
1918 InitID(); | 1919 InitID(); |
1919 if (flags & FPDFCREATE_PROGRESSIVE) { | 1920 if (flags & FPDFCREATE_PROGRESSIVE) |
1920 return true; | 1921 return true; |
1921 } | 1922 return Continue(nullptr) > -1; |
1922 return Continue(NULL) > -1; | |
1923 } | 1923 } |
| 1924 |
1924 void CPDF_Creator::InitID(FX_BOOL bDefault) { | 1925 void CPDF_Creator::InitID(FX_BOOL bDefault) { |
1925 CPDF_Array* pOldIDArray = m_pParser ? m_pParser->GetIDArray() : NULL; | 1926 CPDF_Array* pOldIDArray = m_pParser ? m_pParser->GetIDArray() : nullptr; |
1926 FX_BOOL bNewId = !m_pIDArray; | 1927 FX_BOOL bNewId = !m_pIDArray; |
1927 if (!m_pIDArray) { | 1928 if (!m_pIDArray) { |
1928 m_pIDArray = new CPDF_Array; | 1929 m_pIDArray = new CPDF_Array; |
1929 CPDF_Object* pID1 = pOldIDArray ? pOldIDArray->GetObjectAt(0) : NULL; | 1930 CPDF_Object* pID1 = pOldIDArray ? pOldIDArray->GetObjectAt(0) : nullptr; |
1930 if (pID1) { | 1931 if (pID1) { |
1931 m_pIDArray->Add(pID1->Clone()); | 1932 m_pIDArray->Add(pID1->Clone()); |
1932 } else { | 1933 } else { |
1933 std::vector<uint8_t> buffer = | 1934 std::vector<uint8_t> buffer = |
1934 PDF_GenerateFileID((uint32_t)(uintptr_t) this, m_dwLastObjNum); | 1935 PDF_GenerateFileID((uint32_t)(uintptr_t) this, m_dwLastObjNum); |
1935 CFX_ByteString bsBuffer(buffer.data(), buffer.size()); | 1936 CFX_ByteString bsBuffer(buffer.data(), buffer.size()); |
1936 m_pIDArray->Add(new CPDF_String(bsBuffer, TRUE), m_pDocument); | 1937 m_pIDArray->Add(new CPDF_String(bsBuffer, TRUE), m_pDocument); |
1937 } | 1938 } |
1938 } | 1939 } |
1939 if (!bDefault) { | 1940 if (!bDefault) { |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2009 m_pCryptoHandler = nullptr; | 2010 m_pCryptoHandler = nullptr; |
2010 } | 2011 } |
2011 void CPDF_Creator::ResetStandardSecurity() { | 2012 void CPDF_Creator::ResetStandardSecurity() { |
2012 if (!m_bLocalCryptoHandler) | 2013 if (!m_bLocalCryptoHandler) |
2013 return; | 2014 return; |
2014 | 2015 |
2015 delete m_pCryptoHandler; | 2016 delete m_pCryptoHandler; |
2016 m_pCryptoHandler = nullptr; | 2017 m_pCryptoHandler = nullptr; |
2017 m_bLocalCryptoHandler = FALSE; | 2018 m_bLocalCryptoHandler = FALSE; |
2018 } | 2019 } |
OLD | NEW |