Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(142)

Side by Side Diff: core/fpdfapi/edit/fpdf_edit_create.cpp

Issue 2522313002: Use CFX_MaybeOwned<> in fpdf_edit_create.cpp (Closed)
Patch Set: Fix botch Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | core/fpdfapi/parser/cpdf_stream.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « no previous file | core/fpdfapi/parser/cpdf_stream.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698