| 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 <vector> | 9 #include <vector> |
| 10 | 10 |
| 11 #include "core/fpdfapi/edit/cpdf_creator.h" | 11 #include "core/fpdfapi/edit/cpdf_creator.h" |
| 12 #include "core/fpdfapi/parser/cpdf_array.h" | 12 #include "core/fpdfapi/parser/cpdf_array.h" |
| 13 #include "core/fpdfapi/parser/cpdf_crypto_handler.h" | 13 #include "core/fpdfapi/parser/cpdf_crypto_handler.h" |
| 14 #include "core/fpdfapi/parser/cpdf_dictionary.h" | 14 #include "core/fpdfapi/parser/cpdf_dictionary.h" |
| 15 #include "core/fpdfapi/parser/cpdf_document.h" | 15 #include "core/fpdfapi/parser/cpdf_document.h" |
| 16 #include "core/fpdfapi/parser/cpdf_name.h" |
| 17 #include "core/fpdfapi/parser/cpdf_number.h" |
| 16 #include "core/fpdfapi/parser/cpdf_parser.h" | 18 #include "core/fpdfapi/parser/cpdf_parser.h" |
| 17 #include "core/fpdfapi/parser/cpdf_reference.h" | 19 #include "core/fpdfapi/parser/cpdf_reference.h" |
| 18 #include "core/fpdfapi/parser/cpdf_security_handler.h" | 20 #include "core/fpdfapi/parser/cpdf_security_handler.h" |
| 19 #include "core/fpdfapi/parser/cpdf_stream.h" | 21 #include "core/fpdfapi/parser/cpdf_stream.h" |
| 20 #include "core/fpdfapi/parser/cpdf_stream_acc.h" | 22 #include "core/fpdfapi/parser/cpdf_stream_acc.h" |
| 21 #include "core/fpdfapi/parser/cpdf_string.h" | 23 #include "core/fpdfapi/parser/cpdf_string.h" |
| 22 #include "core/fpdfapi/parser/fpdf_parser_decode.h" | 24 #include "core/fpdfapi/parser/fpdf_parser_decode.h" |
| 23 #include "core/fxcrt/fx_ext.h" | 25 #include "core/fxcrt/fx_ext.h" |
| 24 #include "third_party/base/stl_util.h" | 26 #include "third_party/base/stl_util.h" |
| 25 | 27 |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 121 break; | 123 break; |
| 122 } | 124 } |
| 123 case CPDF_Object::DICTIONARY: { | 125 case CPDF_Object::DICTIONARY: { |
| 124 if (pFile->AppendString("<<") < 0) { | 126 if (pFile->AppendString("<<") < 0) { |
| 125 return -1; | 127 return -1; |
| 126 } | 128 } |
| 127 offset += 2; | 129 offset += 2; |
| 128 const CPDF_Dictionary* p = pObj->AsDictionary(); | 130 const CPDF_Dictionary* p = pObj->AsDictionary(); |
| 129 for (const auto& it : *p) { | 131 for (const auto& it : *p) { |
| 130 const CFX_ByteString& key = it.first; | 132 const CFX_ByteString& key = it.first; |
| 131 CPDF_Object* pValue = it.second; | 133 CPDF_Object* pValue = it.second.get(); |
| 132 if (pFile->AppendString("/") < 0) { | 134 if (pFile->AppendString("/") < 0) { |
| 133 return -1; | 135 return -1; |
| 134 } | 136 } |
| 135 if ((len = pFile->AppendString(PDF_NameEncode(key).AsStringC())) < 0) { | 137 if ((len = pFile->AppendString(PDF_NameEncode(key).AsStringC())) < 0) { |
| 136 return -1; | 138 return -1; |
| 137 } | 139 } |
| 138 offset += len + 1; | 140 offset += len + 1; |
| 139 if (!pValue->IsInline()) { | 141 if (!pValue->IsInline()) { |
| 140 if (pFile->AppendString(" ") < 0) { | 142 if (pFile->AppendString(" ") < 0) { |
| 141 return -1; | 143 return -1; |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 190 int32_t PDF_CreatorWriteTrailer(CPDF_Document* pDocument, | 192 int32_t PDF_CreatorWriteTrailer(CPDF_Document* pDocument, |
| 191 CFX_FileBufferArchive* pFile, | 193 CFX_FileBufferArchive* pFile, |
| 192 CPDF_Array* pIDArray) { | 194 CPDF_Array* pIDArray) { |
| 193 FX_FILESIZE offset = 0; | 195 FX_FILESIZE offset = 0; |
| 194 int32_t len = 0; | 196 int32_t len = 0; |
| 195 CPDF_Parser* pParser = pDocument->GetParser(); | 197 CPDF_Parser* pParser = pDocument->GetParser(); |
| 196 if (pParser) { | 198 if (pParser) { |
| 197 CPDF_Dictionary* p = pParser->GetTrailer(); | 199 CPDF_Dictionary* p = pParser->GetTrailer(); |
| 198 for (const auto& it : *p) { | 200 for (const auto& it : *p) { |
| 199 const CFX_ByteString& key = it.first; | 201 const CFX_ByteString& key = it.first; |
| 200 CPDF_Object* pValue = it.second; | 202 CPDF_Object* pValue = it.second.get(); |
| 201 if (key == "Encrypt" || key == "Size" || key == "Filter" || | 203 if (key == "Encrypt" || key == "Size" || key == "Filter" || |
| 202 key == "Index" || key == "Length" || key == "Prev" || key == "W" || | 204 key == "Index" || key == "Length" || key == "Prev" || key == "W" || |
| 203 key == "XRefStm" || key == "Type" || key == "ID") { | 205 key == "XRefStm" || key == "Type" || key == "ID") { |
| 204 continue; | 206 continue; |
| 205 } | 207 } |
| 206 if (key == "DecodeParms") | 208 if (key == "DecodeParms") |
| 207 continue; | 209 continue; |
| 208 | 210 |
| 209 if (pFile->AppendString(("/")) < 0) { | 211 if (pFile->AppendString(("/")) < 0) { |
| 210 return -1; | 212 return -1; |
| (...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 435 m_pDict = pStream->GetDict(); | 437 m_pDict = pStream->GetDict(); |
| 436 } | 438 } |
| 437 return; | 439 return; |
| 438 } | 440 } |
| 439 | 441 |
| 440 m_bNewData = true; | 442 m_bNewData = true; |
| 441 m_bCloned = true; | 443 m_bCloned = true; |
| 442 // TODO(thestig): Move to Init() and check return value. | 444 // TODO(thestig): Move to Init() and check return value. |
| 443 ::FlateEncode(m_Acc.GetData(), m_Acc.GetSize(), &m_pData, &m_dwSize); | 445 ::FlateEncode(m_Acc.GetData(), m_Acc.GetSize(), &m_pData, &m_dwSize); |
| 444 m_pDict = ToDictionary(pStream->GetDict()->Clone().release()); | 446 m_pDict = ToDictionary(pStream->GetDict()->Clone().release()); |
| 445 m_pDict->SetIntegerFor("Length", m_dwSize); | 447 m_pDict->SetNewFor<CPDF_Number>("Length", static_cast<int>(m_dwSize)); |
| 446 m_pDict->SetNameFor("Filter", "FlateDecode"); | 448 m_pDict->SetNewFor<CPDF_Name>("Filter", "FlateDecode"); |
| 447 m_pDict->RemoveFor("DecodeParms"); | 449 m_pDict->RemoveFor("DecodeParms"); |
| 448 } | 450 } |
| 449 | 451 |
| 450 CPDF_FlateEncoder::CPDF_FlateEncoder(const uint8_t* pBuffer, | 452 CPDF_FlateEncoder::CPDF_FlateEncoder(const uint8_t* pBuffer, |
| 451 uint32_t size, | 453 uint32_t size, |
| 452 bool bFlateEncode, | 454 bool bFlateEncode, |
| 453 bool bXRefStream) | 455 bool bXRefStream) |
| 454 : m_pData(nullptr), | 456 : m_pData(nullptr), |
| 455 m_dwSize(0), | 457 m_dwSize(0), |
| 456 m_pDict(nullptr), | 458 m_pDict(nullptr), |
| (...skipping 531 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 988 } | 990 } |
| 989 int32_t CPDF_Creator::WriteStream(const CPDF_Object* pStream, | 991 int32_t CPDF_Creator::WriteStream(const CPDF_Object* pStream, |
| 990 uint32_t objnum, | 992 uint32_t objnum, |
| 991 CPDF_CryptoHandler* pCrypto) { | 993 CPDF_CryptoHandler* pCrypto) { |
| 992 CPDF_FlateEncoder encoder(const_cast<CPDF_Stream*>(pStream->AsStream()), | 994 CPDF_FlateEncoder encoder(const_cast<CPDF_Stream*>(pStream->AsStream()), |
| 993 pStream != m_pMetadata); | 995 pStream != m_pMetadata); |
| 994 CPDF_Encryptor encryptor(pCrypto, objnum, encoder.m_pData, encoder.m_dwSize); | 996 CPDF_Encryptor encryptor(pCrypto, objnum, encoder.m_pData, encoder.m_dwSize); |
| 995 if ((uint32_t)encoder.m_pDict->GetIntegerFor("Length") != | 997 if ((uint32_t)encoder.m_pDict->GetIntegerFor("Length") != |
| 996 encryptor.m_dwSize) { | 998 encryptor.m_dwSize) { |
| 997 encoder.CloneDict(); | 999 encoder.CloneDict(); |
| 998 encoder.m_pDict->SetIntegerFor("Length", encryptor.m_dwSize); | 1000 encoder.m_pDict->SetNewFor<CPDF_Number>( |
| 1001 "Length", static_cast<int>(encryptor.m_dwSize)); |
| 999 } | 1002 } |
| 1000 if (WriteDirectObj(objnum, encoder.m_pDict) < 0) { | 1003 if (WriteDirectObj(objnum, encoder.m_pDict) < 0) { |
| 1001 return -1; | 1004 return -1; |
| 1002 } | 1005 } |
| 1003 int len = m_File.AppendString("stream\r\n"); | 1006 int len = m_File.AppendString("stream\r\n"); |
| 1004 if (len < 0) { | 1007 if (len < 0) { |
| 1005 return -1; | 1008 return -1; |
| 1006 } | 1009 } |
| 1007 m_Offset += len; | 1010 m_Offset += len; |
| 1008 if (m_File.AppendBlock(encryptor.m_pData, encryptor.m_dwSize) < 0) { | 1011 if (m_File.AppendBlock(encryptor.m_pData, encryptor.m_dwSize) < 0) { |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1101 break; | 1104 break; |
| 1102 } | 1105 } |
| 1103 case CPDF_Object::STREAM: { | 1106 case CPDF_Object::STREAM: { |
| 1104 CPDF_FlateEncoder encoder(const_cast<CPDF_Stream*>(pObj->AsStream()), | 1107 CPDF_FlateEncoder encoder(const_cast<CPDF_Stream*>(pObj->AsStream()), |
| 1105 true); | 1108 true); |
| 1106 CPDF_Encryptor encryptor(m_pCryptoHandler, objnum, encoder.m_pData, | 1109 CPDF_Encryptor encryptor(m_pCryptoHandler, objnum, encoder.m_pData, |
| 1107 encoder.m_dwSize); | 1110 encoder.m_dwSize); |
| 1108 if ((uint32_t)encoder.m_pDict->GetIntegerFor("Length") != | 1111 if ((uint32_t)encoder.m_pDict->GetIntegerFor("Length") != |
| 1109 encryptor.m_dwSize) { | 1112 encryptor.m_dwSize) { |
| 1110 encoder.CloneDict(); | 1113 encoder.CloneDict(); |
| 1111 encoder.m_pDict->SetIntegerFor("Length", encryptor.m_dwSize); | 1114 encoder.m_pDict->SetNewFor<CPDF_Number>( |
| 1115 "Length", static_cast<int>(encryptor.m_dwSize)); |
| 1112 } | 1116 } |
| 1113 if (WriteDirectObj(objnum, encoder.m_pDict) < 0) { | 1117 if (WriteDirectObj(objnum, encoder.m_pDict) < 0) { |
| 1114 return -1; | 1118 return -1; |
| 1115 } | 1119 } |
| 1116 if ((len = m_File.AppendString("stream\r\n")) < 0) { | 1120 if ((len = m_File.AppendString("stream\r\n")) < 0) { |
| 1117 return -1; | 1121 return -1; |
| 1118 } | 1122 } |
| 1119 m_Offset += len; | 1123 m_Offset += len; |
| 1120 if (m_File.AppendBlock(encryptor.m_pData, encryptor.m_dwSize) < 0) { | 1124 if (m_File.AppendBlock(encryptor.m_pData, encryptor.m_dwSize) < 0) { |
| 1121 return -1; | 1125 return -1; |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1184 return PDF_CreatorAppendObject(pObj, &m_File, m_Offset); | 1188 return PDF_CreatorAppendObject(pObj, &m_File, m_Offset); |
| 1185 if (m_File.AppendString("<<") < 0) | 1189 if (m_File.AppendString("<<") < 0) |
| 1186 return -1; | 1190 return -1; |
| 1187 | 1191 |
| 1188 m_Offset += 2; | 1192 m_Offset += 2; |
| 1189 const CPDF_Dictionary* p = pObj->AsDictionary(); | 1193 const CPDF_Dictionary* p = pObj->AsDictionary(); |
| 1190 bool bSignDict = p->IsSignatureDict(); | 1194 bool bSignDict = p->IsSignatureDict(); |
| 1191 for (const auto& it : *p) { | 1195 for (const auto& it : *p) { |
| 1192 bool bSignValue = false; | 1196 bool bSignValue = false; |
| 1193 const CFX_ByteString& key = it.first; | 1197 const CFX_ByteString& key = it.first; |
| 1194 CPDF_Object* pValue = it.second; | 1198 CPDF_Object* pValue = it.second.get(); |
| 1195 if (m_File.AppendString("/") < 0) { | 1199 if (m_File.AppendString("/") < 0) { |
| 1196 return -1; | 1200 return -1; |
| 1197 } | 1201 } |
| 1198 if ((len = m_File.AppendString(PDF_NameEncode(key).AsStringC())) < 0) { | 1202 if ((len = m_File.AppendString(PDF_NameEncode(key).AsStringC())) < 0) { |
| 1199 return -1; | 1203 return -1; |
| 1200 } | 1204 } |
| 1201 m_Offset += len + 1; | 1205 m_Offset += len + 1; |
| 1202 if (bSignDict && key == "Contents") { | 1206 if (bSignDict && key == "Contents") { |
| 1203 bSignValue = true; | 1207 bSignValue = true; |
| 1204 } | 1208 } |
| (...skipping 501 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1706 return -1; | 1710 return -1; |
| 1707 } | 1711 } |
| 1708 if (m_File.AppendString(" 0 obj <<") < 0) { | 1712 if (m_File.AppendString(" 0 obj <<") < 0) { |
| 1709 return -1; | 1713 return -1; |
| 1710 } | 1714 } |
| 1711 } | 1715 } |
| 1712 if (m_pParser) { | 1716 if (m_pParser) { |
| 1713 CPDF_Dictionary* p = m_pParser->GetTrailer(); | 1717 CPDF_Dictionary* p = m_pParser->GetTrailer(); |
| 1714 for (const auto& it : *p) { | 1718 for (const auto& it : *p) { |
| 1715 const CFX_ByteString& key = it.first; | 1719 const CFX_ByteString& key = it.first; |
| 1716 CPDF_Object* pValue = it.second; | 1720 CPDF_Object* pValue = it.second.get(); |
| 1717 // TODO(ochang): Consolidate with similar check in | 1721 // TODO(ochang): Consolidate with similar check in |
| 1718 // PDF_CreatorWriteTrailer. | 1722 // PDF_CreatorWriteTrailer. |
| 1719 if (key == "Encrypt" || key == "Size" || key == "Filter" || | 1723 if (key == "Encrypt" || key == "Size" || key == "Filter" || |
| 1720 key == "Index" || key == "Length" || key == "Prev" || key == "W" || | 1724 key == "Index" || key == "Length" || key == "Prev" || key == "W" || |
| 1721 key == "XRefStm" || key == "ID") { | 1725 key == "XRefStm" || key == "ID") { |
| 1722 continue; | 1726 continue; |
| 1723 } | 1727 } |
| 1724 if (m_File.AppendString(("/")) < 0) { | 1728 if (m_File.AppendString(("/")) < 0) { |
| 1725 return -1; | 1729 return -1; |
| 1726 } | 1730 } |
| (...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2011 m_pCryptoHandler = nullptr; | 2015 m_pCryptoHandler = nullptr; |
| 2012 } | 2016 } |
| 2013 void CPDF_Creator::ResetStandardSecurity() { | 2017 void CPDF_Creator::ResetStandardSecurity() { |
| 2014 if (!m_bLocalCryptoHandler) | 2018 if (!m_bLocalCryptoHandler) |
| 2015 return; | 2019 return; |
| 2016 | 2020 |
| 2017 delete m_pCryptoHandler; | 2021 delete m_pCryptoHandler; |
| 2018 m_pCryptoHandler = nullptr; | 2022 m_pCryptoHandler = nullptr; |
| 2019 m_bLocalCryptoHandler = false; | 2023 m_bLocalCryptoHandler = false; |
| 2020 } | 2024 } |
| OLD | NEW |