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 = const_cast<uint8_t*>(m_Acc.GetData()); |
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); |
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 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
822 if (dwEncryptObjNum == 0) { | 807 if (dwEncryptObjNum == 0) { |
823 dwEncryptObjNum = pCreator->m_dwEncryptObjNum; | 808 dwEncryptObjNum = pCreator->m_dwEncryptObjNum; |
824 } | 809 } |
825 if ((len = PDF_CreatorWriteEncrypt(pCreator->m_pEncryptDict, | 810 if ((len = PDF_CreatorWriteEncrypt(pCreator->m_pEncryptDict, |
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) |
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 } |
| 831 |
846 bool CPDF_XRefStream::End(CPDF_Creator* pCreator, bool bEOF) { | 832 bool CPDF_XRefStream::End(CPDF_Creator* pCreator, bool bEOF) { |
847 if (EndObjectStream(pCreator, bEOF) < 0) { | 833 if (EndObjectStream(pCreator, bEOF) < 0) { |
848 return false; | 834 return false; |
849 } | 835 } |
850 return GenerateXRefStream(pCreator, bEOF); | 836 return GenerateXRefStream(pCreator, bEOF); |
851 } | 837 } |
852 bool CPDF_XRefStream::EndXRefStream(CPDF_Creator* pCreator) { | 838 bool CPDF_XRefStream::EndXRefStream(CPDF_Creator* pCreator) { |
853 if (!(pCreator->m_dwFlags & FPDFCREATE_INCREMENTAL)) { | 839 if (!(pCreator->m_dwFlags & FPDFCREATE_INCREMENTAL)) { |
854 AppendIndex0(m_Buffer, true); | 840 AppendIndex0(m_Buffer, true); |
855 for (uint32_t i = 1; i < pCreator->m_dwLastObjNum + 1; i++) { | 841 for (uint32_t i = 1; i < pCreator->m_dwLastObjNum + 1; i++) { |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
984 if (!m_pXRefStream->Start()) { | 970 if (!m_pXRefStream->Start()) { |
985 return -1; | 971 return -1; |
986 } | 972 } |
987 return 0; | 973 return 0; |
988 } | 974 } |
989 int32_t CPDF_Creator::WriteStream(const CPDF_Object* pStream, | 975 int32_t CPDF_Creator::WriteStream(const CPDF_Object* pStream, |
990 uint32_t objnum, | 976 uint32_t objnum, |
991 CPDF_CryptoHandler* pCrypto) { | 977 CPDF_CryptoHandler* pCrypto) { |
992 CPDF_FlateEncoder encoder(const_cast<CPDF_Stream*>(pStream->AsStream()), | 978 CPDF_FlateEncoder encoder(const_cast<CPDF_Stream*>(pStream->AsStream()), |
993 pStream != m_pMetadata); | 979 pStream != m_pMetadata); |
994 CPDF_Encryptor encryptor(pCrypto, objnum, encoder.m_pData, encoder.m_dwSize); | 980 CPDF_Encryptor encryptor(pCrypto, objnum, encoder.m_pData.Get(), |
995 if ((uint32_t)encoder.m_pDict->GetIntegerFor("Length") != | 981 encoder.m_dwSize); |
| 982 if (static_cast<uint32_t>(encoder.m_pDict->GetIntegerFor("Length")) != |
996 encryptor.m_dwSize) { | 983 encryptor.m_dwSize) { |
997 encoder.CloneDict(); | 984 encoder.CloneDict(); |
998 encoder.m_pDict->SetNewFor<CPDF_Number>( | 985 encoder.m_pDict->SetNewFor<CPDF_Number>( |
999 "Length", static_cast<int>(encryptor.m_dwSize)); | 986 "Length", static_cast<int>(encryptor.m_dwSize)); |
1000 } | 987 } |
1001 if (WriteDirectObj(objnum, encoder.m_pDict) < 0) { | 988 if (WriteDirectObj(objnum, encoder.m_pDict.Get()) < 0) |
1002 return -1; | 989 return -1; |
1003 } | 990 |
1004 int len = m_File.AppendString("stream\r\n"); | 991 int len = m_File.AppendString("stream\r\n"); |
1005 if (len < 0) { | 992 if (len < 0) |
1006 return -1; | 993 return -1; |
1007 } | 994 |
1008 m_Offset += len; | 995 m_Offset += len; |
1009 if (m_File.AppendBlock(encryptor.m_pData, encryptor.m_dwSize) < 0) { | 996 if (m_File.AppendBlock(encryptor.m_pData, encryptor.m_dwSize) < 0) |
1010 return -1; | 997 return -1; |
1011 } | 998 |
1012 m_Offset += encryptor.m_dwSize; | 999 m_Offset += encryptor.m_dwSize; |
1013 if ((len = m_File.AppendString("\r\nendstream")) < 0) { | 1000 if ((len = m_File.AppendString("\r\nendstream")) < 0) |
1014 return -1; | 1001 return -1; |
1015 } | 1002 |
1016 m_Offset += len; | 1003 m_Offset += len; |
1017 return 1; | 1004 return 1; |
1018 } | 1005 } |
1019 int32_t CPDF_Creator::WriteIndirectObj(uint32_t objnum, | 1006 int32_t CPDF_Creator::WriteIndirectObj(uint32_t objnum, |
1020 const CPDF_Object* pObj) { | 1007 const CPDF_Object* pObj) { |
1021 int32_t len = m_File.AppendDWord(objnum); | 1008 int32_t len = m_File.AppendDWord(objnum); |
1022 if (len < 0) | 1009 if (len < 0) |
1023 return -1; | 1010 return -1; |
1024 | 1011 |
1025 m_Offset += len; | 1012 m_Offset += len; |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1097 bHex); | 1084 bHex); |
1098 if ((len = m_File.AppendString(content.AsStringC())) < 0) { | 1085 if ((len = m_File.AppendString(content.AsStringC())) < 0) { |
1099 return -1; | 1086 return -1; |
1100 } | 1087 } |
1101 m_Offset += len; | 1088 m_Offset += len; |
1102 break; | 1089 break; |
1103 } | 1090 } |
1104 case CPDF_Object::STREAM: { | 1091 case CPDF_Object::STREAM: { |
1105 CPDF_FlateEncoder encoder(const_cast<CPDF_Stream*>(pObj->AsStream()), | 1092 CPDF_FlateEncoder encoder(const_cast<CPDF_Stream*>(pObj->AsStream()), |
1106 true); | 1093 true); |
1107 CPDF_Encryptor encryptor(m_pCryptoHandler, objnum, encoder.m_pData, | 1094 CPDF_Encryptor encryptor(m_pCryptoHandler, objnum, encoder.m_pData.Get(), |
1108 encoder.m_dwSize); | 1095 encoder.m_dwSize); |
1109 if ((uint32_t)encoder.m_pDict->GetIntegerFor("Length") != | 1096 if (static_cast<uint32_t>(encoder.m_pDict->GetIntegerFor("Length")) != |
1110 encryptor.m_dwSize) { | 1097 encryptor.m_dwSize) { |
1111 encoder.CloneDict(); | 1098 encoder.CloneDict(); |
1112 encoder.m_pDict->SetNewFor<CPDF_Number>( | 1099 encoder.m_pDict->SetNewFor<CPDF_Number>( |
1113 "Length", static_cast<int>(encryptor.m_dwSize)); | 1100 "Length", static_cast<int>(encryptor.m_dwSize)); |
1114 } | 1101 } |
1115 if (WriteDirectObj(objnum, encoder.m_pDict) < 0) { | 1102 if (WriteDirectObj(objnum, encoder.m_pDict.Get()) < 0) |
1116 return -1; | 1103 return -1; |
1117 } | 1104 |
1118 if ((len = m_File.AppendString("stream\r\n")) < 0) { | 1105 if ((len = m_File.AppendString("stream\r\n")) < 0) |
1119 return -1; | 1106 return -1; |
1120 } | 1107 |
1121 m_Offset += len; | 1108 m_Offset += len; |
1122 if (m_File.AppendBlock(encryptor.m_pData, encryptor.m_dwSize) < 0) { | 1109 if (m_File.AppendBlock(encryptor.m_pData, encryptor.m_dwSize) < 0) |
1123 return -1; | 1110 return -1; |
1124 } | 1111 |
1125 m_Offset += encryptor.m_dwSize; | 1112 m_Offset += encryptor.m_dwSize; |
1126 if ((len = m_File.AppendString("\r\nendstream")) < 0) { | 1113 if ((len = m_File.AppendString("\r\nendstream")) < 0) |
1127 return -1; | 1114 return -1; |
1128 } | 1115 |
1129 m_Offset += len; | 1116 m_Offset += len; |
1130 break; | 1117 break; |
1131 } | 1118 } |
1132 case CPDF_Object::NAME: { | 1119 case CPDF_Object::NAME: { |
1133 if (m_File.AppendString("/") < 0) { | 1120 if (m_File.AppendString("/") < 0) { |
1134 return -1; | 1121 return -1; |
1135 } | 1122 } |
1136 CFX_ByteString str = pObj->GetString(); | 1123 CFX_ByteString str = pObj->GetString(); |
1137 if ((len = m_File.AppendString(PDF_NameEncode(str).AsStringC())) < 0) { | 1124 if ((len = m_File.AppendString(PDF_NameEncode(str).AsStringC())) < 0) { |
1138 return -1; | 1125 return -1; |
(...skipping 874 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2013 m_pCryptoHandler = nullptr; | 2000 m_pCryptoHandler = nullptr; |
2014 } | 2001 } |
2015 void CPDF_Creator::ResetStandardSecurity() { | 2002 void CPDF_Creator::ResetStandardSecurity() { |
2016 if (!m_bLocalCryptoHandler) | 2003 if (!m_bLocalCryptoHandler) |
2017 return; | 2004 return; |
2018 | 2005 |
2019 delete m_pCryptoHandler; | 2006 delete m_pCryptoHandler; |
2020 m_pCryptoHandler = nullptr; | 2007 m_pCryptoHandler = nullptr; |
2021 m_bLocalCryptoHandler = false; | 2008 m_bLocalCryptoHandler = false; |
2022 } | 2009 } |
OLD | NEW |