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/edit/editint.h" | 7 #include "core/fpdfapi/edit/editint.h" |
8 | 8 |
9 #include <memory> | |
9 #include <vector> | 10 #include <vector> |
10 | 11 |
11 #include "core/fpdfapi/edit/cpdf_creator.h" | 12 #include "core/fpdfapi/edit/cpdf_creator.h" |
12 #include "core/fpdfapi/parser/cpdf_array.h" | 13 #include "core/fpdfapi/parser/cpdf_array.h" |
13 #include "core/fpdfapi/parser/cpdf_crypto_handler.h" | 14 #include "core/fpdfapi/parser/cpdf_crypto_handler.h" |
14 #include "core/fpdfapi/parser/cpdf_dictionary.h" | 15 #include "core/fpdfapi/parser/cpdf_dictionary.h" |
15 #include "core/fpdfapi/parser/cpdf_document.h" | 16 #include "core/fpdfapi/parser/cpdf_document.h" |
16 #include "core/fpdfapi/parser/cpdf_name.h" | 17 #include "core/fpdfapi/parser/cpdf_name.h" |
17 #include "core/fpdfapi/parser/cpdf_number.h" | 18 #include "core/fpdfapi/parser/cpdf_number.h" |
18 #include "core/fpdfapi/parser/cpdf_parser.h" | 19 #include "core/fpdfapi/parser/cpdf_parser.h" |
19 #include "core/fpdfapi/parser/cpdf_reference.h" | 20 #include "core/fpdfapi/parser/cpdf_reference.h" |
20 #include "core/fpdfapi/parser/cpdf_security_handler.h" | 21 #include "core/fpdfapi/parser/cpdf_security_handler.h" |
21 #include "core/fpdfapi/parser/cpdf_stream.h" | 22 #include "core/fpdfapi/parser/cpdf_stream.h" |
22 #include "core/fpdfapi/parser/cpdf_stream_acc.h" | 23 #include "core/fpdfapi/parser/cpdf_stream_acc.h" |
23 #include "core/fpdfapi/parser/cpdf_string.h" | 24 #include "core/fpdfapi/parser/cpdf_string.h" |
24 #include "core/fpdfapi/parser/fpdf_parser_decode.h" | 25 #include "core/fpdfapi/parser/fpdf_parser_decode.h" |
26 #include "core/fxcrt/cfx_maybe_owned.h" | |
25 #include "core/fxcrt/fx_ext.h" | 27 #include "core/fxcrt/fx_ext.h" |
26 #include "third_party/base/stl_util.h" | 28 #include "third_party/base/stl_util.h" |
27 | 29 |
28 #define PDF_OBJECTSTREAM_MAXLENGTH (256 * 1024) | 30 #define PDF_OBJECTSTREAM_MAXLENGTH (256 * 1024) |
29 #define PDF_XREFSTREAM_MAXSIZE 10000 | 31 #define PDF_XREFSTREAM_MAXSIZE 10000 |
30 | 32 |
31 // TODO(ochang): Make helper for appending "objnum 0 R ". | 33 // TODO(ochang): Make helper for appending "objnum 0 R ". |
32 | 34 |
33 namespace { | 35 namespace { |
34 | 36 |
(...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
389 public: | 391 public: |
390 CPDF_FlateEncoder(CPDF_Stream* pStream, bool bFlateEncode); | 392 CPDF_FlateEncoder(CPDF_Stream* pStream, bool bFlateEncode); |
391 CPDF_FlateEncoder(const uint8_t* pBuffer, | 393 CPDF_FlateEncoder(const uint8_t* pBuffer, |
392 uint32_t size, | 394 uint32_t size, |
393 bool bFlateEncode, | 395 bool bFlateEncode, |
394 bool bXRefStream); | 396 bool bXRefStream); |
395 ~CPDF_FlateEncoder(); | 397 ~CPDF_FlateEncoder(); |
396 | 398 |
397 void CloneDict(); | 399 void CloneDict(); |
398 | 400 |
399 uint8_t* m_pData; | |
400 uint32_t m_dwSize; | 401 uint32_t m_dwSize; |
401 CPDF_Dictionary* m_pDict; | 402 CFX_MaybeOwned<uint8_t, FxFreeDeleter> m_pData; |
402 bool m_bCloned; | 403 CFX_MaybeOwned<CPDF_Dictionary> m_pDict; |
403 bool m_bNewData; | |
404 CPDF_StreamAcc m_Acc; | 404 CPDF_StreamAcc m_Acc; |
405 }; | 405 }; |
406 | 406 |
407 void CPDF_FlateEncoder::CloneDict() { | 407 void CPDF_FlateEncoder::CloneDict() { |
408 if (!m_bCloned) { | 408 if (m_pDict.IsOwned()) |
409 m_pDict = ToDictionary(m_pDict->Clone().release()); | 409 return; |
410 ASSERT(m_pDict); | 410 m_pDict = ToDictionary(m_pDict->Clone()); |
411 m_bCloned = true; | 411 ASSERT(m_pDict.IsOwned()); |
412 } | |
413 } | 412 } |
414 | 413 |
415 CPDF_FlateEncoder::CPDF_FlateEncoder(CPDF_Stream* pStream, bool bFlateEncode) | 414 CPDF_FlateEncoder::CPDF_FlateEncoder(CPDF_Stream* pStream, bool bFlateEncode) |
416 : m_pData(nullptr), | 415 : m_dwSize(0) { |
417 m_dwSize(0), | |
418 m_pDict(nullptr), | |
419 m_bCloned(false), | |
420 m_bNewData(false) { | |
421 m_Acc.LoadAllData(pStream, true); | 416 m_Acc.LoadAllData(pStream, true); |
422 bool bHasFilter = pStream && pStream->HasFilter(); | 417 bool bHasFilter = pStream && pStream->HasFilter(); |
423 if (bHasFilter && !bFlateEncode) { | 418 if (bHasFilter && !bFlateEncode) { |
424 CPDF_StreamAcc destAcc; | 419 CPDF_StreamAcc destAcc; |
425 destAcc.LoadAllData(pStream); | 420 destAcc.LoadAllData(pStream); |
426 m_dwSize = destAcc.GetSize(); | 421 m_dwSize = destAcc.GetSize(); |
427 m_pData = (uint8_t*)destAcc.DetachData(); | 422 m_pData = destAcc.DetachData(); |
428 m_pDict = ToDictionary(pStream->GetDict()->Clone().release()); | 423 m_pDict = ToDictionary(pStream->GetDict()->Clone()); |
429 m_pDict->RemoveFor("Filter"); | 424 m_pDict->RemoveFor("Filter"); |
430 m_bNewData = true; | |
431 m_bCloned = true; | |
432 return; | 425 return; |
433 } | 426 } |
434 if (bHasFilter || !bFlateEncode) { | 427 if (bHasFilter || !bFlateEncode) { |
435 m_pData = (uint8_t*)m_Acc.GetData(); | 428 m_pData = (uint8_t*)m_Acc.GetData(); |
npm
2016/11/28 20:31:02
const_cast?
Tom Sepez
2016/11/28 21:38:08
Done.
| |
436 m_dwSize = m_Acc.GetSize(); | 429 m_dwSize = m_Acc.GetSize(); |
437 m_pDict = pStream->GetDict(); | 430 m_pDict = pStream->GetDict(); |
438 return; | 431 return; |
439 } | 432 } |
440 m_bNewData = true; | |
441 m_bCloned = true; | |
442 // TODO(thestig): Move to Init() and check return value. | 433 // TODO(thestig): Move to Init() and check return value. |
443 ::FlateEncode(m_Acc.GetData(), m_Acc.GetSize(), &m_pData, &m_dwSize); | 434 uint8_t* buffer = nullptr; |
444 m_pDict = ToDictionary(pStream->GetDict()->Clone().release()); | 435 ::FlateEncode(m_Acc.GetData(), m_Acc.GetSize(), &buffer, &m_dwSize); |
436 m_pData = std::unique_ptr<uint8_t, FxFreeDeleter>(buffer); | |
437 m_pDict = ToDictionary(pStream->GetDict()->Clone()); | |
445 m_pDict->SetNewFor<CPDF_Number>("Length", static_cast<int>(m_dwSize)); | 438 m_pDict->SetNewFor<CPDF_Number>("Length", static_cast<int>(m_dwSize)); |
446 m_pDict->SetNewFor<CPDF_Name>("Filter", "FlateDecode"); | 439 m_pDict->SetNewFor<CPDF_Name>("Filter", "FlateDecode"); |
447 m_pDict->RemoveFor("DecodeParms"); | 440 m_pDict->RemoveFor("DecodeParms"); |
448 } | 441 } |
449 | 442 |
450 CPDF_FlateEncoder::CPDF_FlateEncoder(const uint8_t* pBuffer, | 443 CPDF_FlateEncoder::CPDF_FlateEncoder(const uint8_t* pBuffer, |
451 uint32_t size, | 444 uint32_t size, |
452 bool bFlateEncode, | 445 bool bFlateEncode, |
453 bool bXRefStream) | 446 bool bXRefStream) |
454 : m_pData(nullptr), | 447 : m_dwSize(0) { |
455 m_dwSize(0), | |
456 m_pDict(nullptr), | |
457 m_bCloned(false), | |
458 m_bNewData(false) { | |
459 if (!bFlateEncode) { | 448 if (!bFlateEncode) { |
460 m_pData = (uint8_t*)pBuffer; | 449 m_pData = const_cast<uint8_t*>(pBuffer); |
Wei Li
2016/11/28 20:59:56
Nit: is cast needed? pBuffer is of type "const uin
npm
2016/11/28 21:01:29
I think yes because m_pData is not const
Wei Li
2016/11/28 21:21:12
Is const type better for m_pData?
Tom Sepez
2016/11/28 21:38:08
We may free it later, so it's technically not cons
| |
461 m_dwSize = size; | 450 m_dwSize = size; |
462 return; | 451 return; |
463 } | 452 } |
464 m_bNewData = true; | 453 uint8_t* buffer = nullptr; |
465 // TODO(thestig): Move to Init() and check return value. | 454 // TODO(thestig): Move to Init() and check return value. |
466 if (bXRefStream) | 455 if (bXRefStream) |
467 ::PngEncode(pBuffer, size, &m_pData, &m_dwSize); | 456 ::PngEncode(pBuffer, size, &buffer, &m_dwSize); |
468 else | 457 else |
469 ::FlateEncode(pBuffer, size, &m_pData, &m_dwSize); | 458 ::FlateEncode(pBuffer, size, &buffer, &m_dwSize); |
459 m_pData = std::unique_ptr<uint8_t, FxFreeDeleter>(buffer); | |
470 } | 460 } |
471 | 461 |
472 CPDF_FlateEncoder::~CPDF_FlateEncoder() { | 462 CPDF_FlateEncoder::~CPDF_FlateEncoder() {} |
473 if (m_bCloned) | |
474 delete m_pDict; | |
475 if (m_bNewData) | |
476 FX_Free(m_pData); | |
477 } | |
478 | 463 |
479 class CPDF_Encryptor { | 464 class CPDF_Encryptor { |
480 public: | 465 public: |
481 CPDF_Encryptor(CPDF_CryptoHandler* pHandler, | 466 CPDF_Encryptor(CPDF_CryptoHandler* pHandler, |
482 int objnum, | 467 int objnum, |
483 uint8_t* src_data, | 468 uint8_t* src_data, |
484 uint32_t src_size); | 469 uint32_t src_size); |
485 ~CPDF_Encryptor(); | 470 ~CPDF_Encryptor(); |
486 | 471 |
487 uint8_t* m_pData; | 472 uint8_t* m_pData; |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
576 } | 561 } |
577 if (pFile->AppendString("/Length ") < 0) { | 562 if (pFile->AppendString("/Length ") < 0) { |
578 return -1; | 563 return -1; |
579 } | 564 } |
580 offset += len + 15; | 565 offset += len + 15; |
581 | 566 |
582 tempBuffer << m_Buffer; | 567 tempBuffer << m_Buffer; |
583 CPDF_FlateEncoder encoder(tempBuffer.GetBuffer(), tempBuffer.GetLength(), | 568 CPDF_FlateEncoder encoder(tempBuffer.GetBuffer(), tempBuffer.GetLength(), |
584 true, false); | 569 true, false); |
585 CPDF_Encryptor encryptor(pCreator->m_pCryptoHandler, m_dwObjNum, | 570 CPDF_Encryptor encryptor(pCreator->m_pCryptoHandler, m_dwObjNum, |
586 encoder.m_pData, encoder.m_dwSize); | 571 encoder.m_pData.Get(), encoder.m_dwSize); |
587 if ((len = pFile->AppendDWord(encryptor.m_dwSize)) < 0) { | 572 if ((len = pFile->AppendDWord(encryptor.m_dwSize)) < 0) { |
588 return -1; | 573 return -1; |
589 } | 574 } |
590 offset += len; | 575 offset += len; |
591 if (pFile->AppendString("/Filter /FlateDecode") < 0) { | 576 if (pFile->AppendString("/Filter /FlateDecode") < 0) { |
592 return -1; | 577 return -1; |
593 } | 578 } |
594 offset += 20; | 579 offset += 20; |
595 if ((len = pFile->AppendString(">>stream\r\n")) < 0) { | 580 if ((len = pFile->AppendString(">>stream\r\n")) < 0) { |
596 return -1; | 581 return -1; |
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
826 dwEncryptObjNum, pFile)) < 0) { | 811 dwEncryptObjNum, pFile)) < 0) { |
827 return false; | 812 return false; |
828 } | 813 } |
829 offset += len; | 814 offset += len; |
830 } | 815 } |
831 } | 816 } |
832 if ((len = pFile->AppendString(">>stream\r\n")) < 0) { | 817 if ((len = pFile->AppendString(">>stream\r\n")) < 0) { |
833 return false; | 818 return false; |
834 } | 819 } |
835 offset += len; | 820 offset += len; |
836 if (pFile->AppendBlock(encoder.m_pData, encoder.m_dwSize) < 0) { | 821 if (pFile->AppendBlock(encoder.m_pData.Get(), encoder.m_dwSize) < 0) { |
npm
2016/11/28 20:31:02
Nit: no {}
Tom Sepez
2016/11/28 21:38:08
Done.
| |
837 return false; | 822 return false; |
838 } | 823 } |
839 if ((len = pFile->AppendString("\r\nendstream\r\nendobj\r\n")) < 0) { | 824 if ((len = pFile->AppendString("\r\nendstream\r\nendobj\r\n")) < 0) { |
840 return false; | 825 return false; |
841 } | 826 } |
842 offset += encoder.m_dwSize + len; | 827 offset += encoder.m_dwSize + len; |
843 m_PrevOffset = offset_tmp; | 828 m_PrevOffset = offset_tmp; |
844 return true; | 829 return true; |
845 } | 830 } |
846 bool CPDF_XRefStream::End(CPDF_Creator* pCreator, bool bEOF) { | 831 bool CPDF_XRefStream::End(CPDF_Creator* pCreator, bool bEOF) { |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
984 if (!m_pXRefStream->Start()) { | 969 if (!m_pXRefStream->Start()) { |
985 return -1; | 970 return -1; |
986 } | 971 } |
987 return 0; | 972 return 0; |
988 } | 973 } |
989 int32_t CPDF_Creator::WriteStream(const CPDF_Object* pStream, | 974 int32_t CPDF_Creator::WriteStream(const CPDF_Object* pStream, |
990 uint32_t objnum, | 975 uint32_t objnum, |
991 CPDF_CryptoHandler* pCrypto) { | 976 CPDF_CryptoHandler* pCrypto) { |
992 CPDF_FlateEncoder encoder(const_cast<CPDF_Stream*>(pStream->AsStream()), | 977 CPDF_FlateEncoder encoder(const_cast<CPDF_Stream*>(pStream->AsStream()), |
993 pStream != m_pMetadata); | 978 pStream != m_pMetadata); |
994 CPDF_Encryptor encryptor(pCrypto, objnum, encoder.m_pData, encoder.m_dwSize); | 979 CPDF_Encryptor encryptor(pCrypto, objnum, encoder.m_pData.Get(), |
995 if ((uint32_t)encoder.m_pDict->GetIntegerFor("Length") != | 980 encoder.m_dwSize); |
981 if (static_cast<uint32_t>(encoder.m_pDict->GetIntegerFor("Length")) != | |
996 encryptor.m_dwSize) { | 982 encryptor.m_dwSize) { |
997 encoder.CloneDict(); | 983 encoder.CloneDict(); |
998 encoder.m_pDict->SetNewFor<CPDF_Number>( | 984 encoder.m_pDict->SetNewFor<CPDF_Number>( |
999 "Length", static_cast<int>(encryptor.m_dwSize)); | 985 "Length", static_cast<int>(encryptor.m_dwSize)); |
1000 } | 986 } |
1001 if (WriteDirectObj(objnum, encoder.m_pDict) < 0) { | 987 if (WriteDirectObj(objnum, encoder.m_pDict.Get()) < 0) |
1002 return -1; | 988 return -1; |
1003 } | 989 |
1004 int len = m_File.AppendString("stream\r\n"); | 990 int len = m_File.AppendString("stream\r\n"); |
1005 if (len < 0) { | 991 if (len < 0) |
1006 return -1; | 992 return -1; |
1007 } | 993 |
1008 m_Offset += len; | 994 m_Offset += len; |
1009 if (m_File.AppendBlock(encryptor.m_pData, encryptor.m_dwSize) < 0) { | 995 if (m_File.AppendBlock(encryptor.m_pData, encryptor.m_dwSize) < 0) |
1010 return -1; | 996 return -1; |
1011 } | 997 |
1012 m_Offset += encryptor.m_dwSize; | 998 m_Offset += encryptor.m_dwSize; |
1013 if ((len = m_File.AppendString("\r\nendstream")) < 0) { | 999 if ((len = m_File.AppendString("\r\nendstream")) < 0) |
1014 return -1; | 1000 return -1; |
1015 } | 1001 |
1016 m_Offset += len; | 1002 m_Offset += len; |
1017 return 1; | 1003 return 1; |
1018 } | 1004 } |
1019 int32_t CPDF_Creator::WriteIndirectObj(uint32_t objnum, | 1005 int32_t CPDF_Creator::WriteIndirectObj(uint32_t objnum, |
1020 const CPDF_Object* pObj) { | 1006 const CPDF_Object* pObj) { |
1021 int32_t len = m_File.AppendDWord(objnum); | 1007 int32_t len = m_File.AppendDWord(objnum); |
1022 if (len < 0) | 1008 if (len < 0) |
1023 return -1; | 1009 return -1; |
1024 | 1010 |
1025 m_Offset += len; | 1011 m_Offset += len; |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1097 bHex); | 1083 bHex); |
1098 if ((len = m_File.AppendString(content.AsStringC())) < 0) { | 1084 if ((len = m_File.AppendString(content.AsStringC())) < 0) { |
1099 return -1; | 1085 return -1; |
1100 } | 1086 } |
1101 m_Offset += len; | 1087 m_Offset += len; |
1102 break; | 1088 break; |
1103 } | 1089 } |
1104 case CPDF_Object::STREAM: { | 1090 case CPDF_Object::STREAM: { |
1105 CPDF_FlateEncoder encoder(const_cast<CPDF_Stream*>(pObj->AsStream()), | 1091 CPDF_FlateEncoder encoder(const_cast<CPDF_Stream*>(pObj->AsStream()), |
1106 true); | 1092 true); |
1107 CPDF_Encryptor encryptor(m_pCryptoHandler, objnum, encoder.m_pData, | 1093 CPDF_Encryptor encryptor(m_pCryptoHandler, objnum, encoder.m_pData.Get(), |
1108 encoder.m_dwSize); | 1094 encoder.m_dwSize); |
1109 if ((uint32_t)encoder.m_pDict->GetIntegerFor("Length") != | 1095 if (static_cast<uint32_t>(encoder.m_pDict->GetIntegerFor("Length")) != |
1110 encryptor.m_dwSize) { | 1096 encryptor.m_dwSize) { |
1111 encoder.CloneDict(); | 1097 encoder.CloneDict(); |
1112 encoder.m_pDict->SetNewFor<CPDF_Number>( | 1098 encoder.m_pDict->SetNewFor<CPDF_Number>( |
1113 "Length", static_cast<int>(encryptor.m_dwSize)); | 1099 "Length", static_cast<int>(encryptor.m_dwSize)); |
1114 } | 1100 } |
1115 if (WriteDirectObj(objnum, encoder.m_pDict) < 0) { | 1101 if (WriteDirectObj(objnum, encoder.m_pDict.Get()) < 0) |
1116 return -1; | 1102 return -1; |
1117 } | 1103 |
1118 if ((len = m_File.AppendString("stream\r\n")) < 0) { | 1104 if ((len = m_File.AppendString("stream\r\n")) < 0) |
1119 return -1; | 1105 return -1; |
1120 } | 1106 |
1121 m_Offset += len; | 1107 m_Offset += len; |
1122 if (m_File.AppendBlock(encryptor.m_pData, encryptor.m_dwSize) < 0) { | 1108 if (m_File.AppendBlock(encryptor.m_pData, encryptor.m_dwSize) < 0) |
1123 return -1; | 1109 return -1; |
1124 } | 1110 |
1125 m_Offset += encryptor.m_dwSize; | 1111 m_Offset += encryptor.m_dwSize; |
1126 if ((len = m_File.AppendString("\r\nendstream")) < 0) { | 1112 if ((len = m_File.AppendString("\r\nendstream")) < 0) |
1127 return -1; | 1113 return -1; |
1128 } | 1114 |
1129 m_Offset += len; | 1115 m_Offset += len; |
1130 break; | 1116 break; |
1131 } | 1117 } |
1132 case CPDF_Object::NAME: { | 1118 case CPDF_Object::NAME: { |
1133 if (m_File.AppendString("/") < 0) { | 1119 if (m_File.AppendString("/") < 0) { |
1134 return -1; | 1120 return -1; |
1135 } | 1121 } |
1136 CFX_ByteString str = pObj->GetString(); | 1122 CFX_ByteString str = pObj->GetString(); |
1137 if ((len = m_File.AppendString(PDF_NameEncode(str).AsStringC())) < 0) { | 1123 if ((len = m_File.AppendString(PDF_NameEncode(str).AsStringC())) < 0) { |
1138 return -1; | 1124 return -1; |
(...skipping 874 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2013 m_pCryptoHandler = nullptr; | 1999 m_pCryptoHandler = nullptr; |
2014 } | 2000 } |
2015 void CPDF_Creator::ResetStandardSecurity() { | 2001 void CPDF_Creator::ResetStandardSecurity() { |
2016 if (!m_bLocalCryptoHandler) | 2002 if (!m_bLocalCryptoHandler) |
2017 return; | 2003 return; |
2018 | 2004 |
2019 delete m_pCryptoHandler; | 2005 delete m_pCryptoHandler; |
2020 m_pCryptoHandler = nullptr; | 2006 m_pCryptoHandler = nullptr; |
2021 m_bLocalCryptoHandler = false; | 2007 m_bLocalCryptoHandler = false; |
2022 } | 2008 } |
OLD | NEW |