John Abd-El-Malek | 3f3b45c | 2014-05-23 17:28:10 -0700 | [diff] [blame] | 1 | // Copyright 2014 PDFium Authors. All rights reserved. |
2 | // Use of this source code is governed by a BSD-style license that can be | ||||
3 | // found in the LICENSE file. | ||||
Lei Zhang | 95e854f | 2015-06-13 00:58:06 -0700 | [diff] [blame] | 4 | |
John Abd-El-Malek | 3f3b45c | 2014-05-23 17:28:10 -0700 | [diff] [blame] | 5 | // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
6 | |||||
dsinclair | 488b7ad | 2016-10-04 11:55:50 -0700 | [diff] [blame] | 7 | #include "core/fpdfapi/parser/cfdf_document.h" |
Wei Li | aa0f69a | 2016-01-07 10:49:33 -0800 | [diff] [blame] | 8 | |
tsepez | 0e606b5 | 2016-11-18 16:22:41 -0800 | [diff] [blame] | 9 | #include <memory> |
Henrique Nakashima | 5c09f4c | 2017-08-04 12:28:52 -0400 | [diff] [blame] | 10 | #include <sstream> |
tsepez | 0e606b5 | 2016-11-18 16:22:41 -0800 | [diff] [blame] | 11 | #include <utility> |
12 | |||||
dsinclair | 2415435 | 2016-10-04 11:01:48 -0700 | [diff] [blame] | 13 | #include "core/fpdfapi/edit/cpdf_creator.h" |
dsinclair | 488b7ad | 2016-10-04 11:55:50 -0700 | [diff] [blame] | 14 | #include "core/fpdfapi/parser/cpdf_dictionary.h" |
15 | #include "core/fpdfapi/parser/cpdf_syntax_parser.h" | ||||
Tom Sepez | a119340 | 2017-04-13 10:42:41 -0700 | [diff] [blame] | 16 | #include "core/fpdfapi/parser/fpdf_parser_utility.h" |
Lei Zhang | 3002941 | 2018-08-13 19:56:29 +0000 | [diff] [blame] | 17 | #include "core/fxcrt/cfx_readonlymemorystream.h" |
tsepez | 36eb4bd | 2016-10-03 15:24:27 -0700 | [diff] [blame] | 18 | #include "third_party/base/ptr_util.h" |
Lei Zhang | f0260b2 | 2018-08-13 22:50:02 +0000 | [diff] [blame^] | 19 | #include "third_party/base/span.h" |
Lei Zhang | a9fa50f | 2015-11-10 09:45:32 -0800 | [diff] [blame] | 20 | |
Lei Zhang | 3002941 | 2018-08-13 19:56:29 +0000 | [diff] [blame] | 21 | CFDF_Document::CFDF_Document() = default; |
dsinclair | a61c01e | 2016-08-24 10:31:23 -0700 | [diff] [blame] | 22 | |
Lei Zhang | 3002941 | 2018-08-13 19:56:29 +0000 | [diff] [blame] | 23 | CFDF_Document::~CFDF_Document() = default; |
dsinclair | a61c01e | 2016-08-24 10:31:23 -0700 | [diff] [blame] | 24 | |
tsepez | 05e0169 | 2016-11-28 17:30:09 -0800 | [diff] [blame] | 25 | std::unique_ptr<CFDF_Document> CFDF_Document::CreateNewDoc() { |
26 | auto pDoc = pdfium::MakeUnique<CFDF_Document>(); | ||||
tsepez | 5913a6c | 2016-11-16 17:31:18 -0800 | [diff] [blame] | 27 | pDoc->m_pRootDict = pDoc->NewIndirect<CPDF_Dictionary>(); |
tsepez | 0e606b5 | 2016-11-18 16:22:41 -0800 | [diff] [blame] | 28 | pDoc->m_pRootDict->SetNewFor<CPDF_Dictionary>("FDF"); |
Nico Weber | 9d8ec5a | 2015-08-04 13:00:21 -0700 | [diff] [blame] | 29 | return pDoc; |
John Abd-El-Malek | 3f3b45c | 2014-05-23 17:28:10 -0700 | [diff] [blame] | 30 | } |
thestig | 2f1e05a | 2016-05-26 16:24:15 -0700 | [diff] [blame] | 31 | |
Lei Zhang | f0260b2 | 2018-08-13 22:50:02 +0000 | [diff] [blame^] | 32 | std::unique_ptr<CFDF_Document> CFDF_Document::ParseMemory( |
33 | pdfium::span<const uint8_t> span) { | ||||
Lei Zhang | 58c2c14 | 2017-12-19 19:00:43 +0000 | [diff] [blame] | 34 | auto pDoc = pdfium::MakeUnique<CFDF_Document>(); |
Lei Zhang | f0260b2 | 2018-08-13 22:50:02 +0000 | [diff] [blame^] | 35 | pDoc->ParseStream( |
36 | pdfium::MakeRetain<CFX_ReadOnlyMemoryStream>(span.data(), span.size())); | ||||
Lei Zhang | 58c2c14 | 2017-12-19 19:00:43 +0000 | [diff] [blame] | 37 | return pDoc->m_pRootDict ? std::move(pDoc) : nullptr; |
John Abd-El-Malek | 3f3b45c | 2014-05-23 17:28:10 -0700 | [diff] [blame] | 38 | } |
thestig | 2f1e05a | 2016-05-26 16:24:15 -0700 | [diff] [blame] | 39 | |
tsepez | 833619b | 2016-12-07 09:21:17 -0800 | [diff] [blame] | 40 | void CFDF_Document::ParseStream( |
Dan Sinclair | 0b95042 | 2017-09-21 15:49:49 -0400 | [diff] [blame] | 41 | const RetainPtr<IFX_SeekableReadStream>& pFile) { |
Nico Weber | 9d8ec5a | 2015-08-04 13:00:21 -0700 | [diff] [blame] | 42 | m_pFile = pFile; |
Lei Zhang | 5b32233 | 2018-07-25 17:35:18 +0000 | [diff] [blame] | 43 | CPDF_SyntaxParser parser(m_pFile); |
Nico Weber | 9d8ec5a | 2015-08-04 13:00:21 -0700 | [diff] [blame] | 44 | while (1) { |
Lei Zhang | ec32127 | 2016-01-06 01:52:42 -0800 | [diff] [blame] | 45 | bool bNumber; |
Ryan Harrison | 275e260 | 2017-09-18 14:23:18 -0400 | [diff] [blame] | 46 | ByteString word = parser.GetNextWord(&bNumber); |
Nico Weber | 9d8ec5a | 2015-08-04 13:00:21 -0700 | [diff] [blame] | 47 | if (bNumber) { |
tsepez | b4c9f3f | 2016-04-13 15:41:21 -0700 | [diff] [blame] | 48 | uint32_t objnum = FXSYS_atoui(word.c_str()); |
tsepez | 761eed2 | 2016-11-04 11:02:59 -0700 | [diff] [blame] | 49 | if (!objnum) |
50 | break; | ||||
51 | |||||
Lei Zhang | ec32127 | 2016-01-06 01:52:42 -0800 | [diff] [blame] | 52 | word = parser.GetNextWord(&bNumber); |
thestig | 2f1e05a | 2016-05-26 16:24:15 -0700 | [diff] [blame] | 53 | if (!bNumber) |
Nico Weber | 9d8ec5a | 2015-08-04 13:00:21 -0700 | [diff] [blame] | 54 | break; |
thestig | 2f1e05a | 2016-05-26 16:24:15 -0700 | [diff] [blame] | 55 | |
Lei Zhang | ec32127 | 2016-01-06 01:52:42 -0800 | [diff] [blame] | 56 | word = parser.GetNextWord(nullptr); |
thestig | 2f1e05a | 2016-05-26 16:24:15 -0700 | [diff] [blame] | 57 | if (word != "obj") |
Nico Weber | 9d8ec5a | 2015-08-04 13:00:21 -0700 | [diff] [blame] | 58 | break; |
thestig | 2f1e05a | 2016-05-26 16:24:15 -0700 | [diff] [blame] | 59 | |
Artem Strygin | d8169d7 | 2017-10-02 19:19:28 +0300 | [diff] [blame] | 60 | std::unique_ptr<CPDF_Object> pObj = parser.GetObjectBody(this); |
thestig | 2f1e05a | 2016-05-26 16:24:15 -0700 | [diff] [blame] | 61 | if (!pObj) |
Nico Weber | 9d8ec5a | 2015-08-04 13:00:21 -0700 | [diff] [blame] | 62 | break; |
thestig | 2f1e05a | 2016-05-26 16:24:15 -0700 | [diff] [blame] | 63 | |
tsepez | 931d087 | 2016-11-04 16:00:03 -0700 | [diff] [blame] | 64 | ReplaceIndirectObjectIfHigherGeneration(objnum, std::move(pObj)); |
Lei Zhang | ec32127 | 2016-01-06 01:52:42 -0800 | [diff] [blame] | 65 | word = parser.GetNextWord(nullptr); |
thestig | 2f1e05a | 2016-05-26 16:24:15 -0700 | [diff] [blame] | 66 | if (word != "endobj") |
Nico Weber | 9d8ec5a | 2015-08-04 13:00:21 -0700 | [diff] [blame] | 67 | break; |
John Abd-El-Malek | 3f3b45c | 2014-05-23 17:28:10 -0700 | [diff] [blame] | 68 | } else { |
thestig | 2f1e05a | 2016-05-26 16:24:15 -0700 | [diff] [blame] | 69 | if (word != "trailer") |
Nico Weber | 9d8ec5a | 2015-08-04 13:00:21 -0700 | [diff] [blame] | 70 | break; |
thestig | 2f1e05a | 2016-05-26 16:24:15 -0700 | [diff] [blame] | 71 | |
tsepez | 5ab31ef | 2016-11-07 13:49:17 -0800 | [diff] [blame] | 72 | std::unique_ptr<CPDF_Dictionary> pMainDict = |
Artem Strygin | d8169d7 | 2017-10-02 19:19:28 +0300 | [diff] [blame] | 73 | ToDictionary(parser.GetObjectBody(this)); |
tsepez | 5ab31ef | 2016-11-07 13:49:17 -0800 | [diff] [blame] | 74 | if (pMainDict) |
dsinclair | 38fd844 | 2016-09-15 10:15:32 -0700 | [diff] [blame] | 75 | m_pRootDict = pMainDict->GetDictFor("Root"); |
tsepez | 5ab31ef | 2016-11-07 13:49:17 -0800 | [diff] [blame] | 76 | |
Nico Weber | 9d8ec5a | 2015-08-04 13:00:21 -0700 | [diff] [blame] | 77 | break; |
John Abd-El-Malek | 3f3b45c | 2014-05-23 17:28:10 -0700 | [diff] [blame] | 78 | } |
Nico Weber | 9d8ec5a | 2015-08-04 13:00:21 -0700 | [diff] [blame] | 79 | } |
John Abd-El-Malek | 3f3b45c | 2014-05-23 17:28:10 -0700 | [diff] [blame] | 80 | } |
thestig | 2f1e05a | 2016-05-26 16:24:15 -0700 | [diff] [blame] | 81 | |
Ryan Harrison | 275e260 | 2017-09-18 14:23:18 -0400 | [diff] [blame] | 82 | ByteString CFDF_Document::WriteToString() const { |
dsinclair | e07edce | 2016-08-23 20:14:27 -0700 | [diff] [blame] | 83 | if (!m_pRootDict) |
Ryan Harrison | 275e260 | 2017-09-18 14:23:18 -0400 | [diff] [blame] | 84 | return ByteString(); |
dsinclair | e07edce | 2016-08-23 20:14:27 -0700 | [diff] [blame] | 85 | |
Henrique Nakashima | 5c09f4c | 2017-08-04 12:28:52 -0400 | [diff] [blame] | 86 | std::ostringstream buf; |
Lei Zhang | d983b09 | 2015-12-14 16:58:33 -0800 | [diff] [blame] | 87 | buf << "%FDF-1.2\r\n"; |
dsinclair | e07edce | 2016-08-23 20:14:27 -0700 | [diff] [blame] | 88 | for (const auto& pair : *this) |
tsepez | 5b7c9bb | 2016-09-20 12:02:32 -0700 | [diff] [blame] | 89 | buf << pair.first << " 0 obj\r\n" |
90 | << pair.second.get() << "\r\nendobj\r\n\r\n"; | ||||
dsinclair | e07edce | 2016-08-23 20:14:27 -0700 | [diff] [blame] | 91 | |
Lei Zhang | d983b09 | 2015-12-14 16:58:33 -0800 | [diff] [blame] | 92 | buf << "trailer\r\n<</Root " << m_pRootDict->GetObjNum() |
93 | << " 0 R>>\r\n%%EOF\r\n"; | ||||
Henrique Nakashima | 5c09f4c | 2017-08-04 12:28:52 -0400 | [diff] [blame] | 94 | |
Ryan Harrison | 275e260 | 2017-09-18 14:23:18 -0400 | [diff] [blame] | 95 | return ByteString(buf); |
Nico Weber | 9d8ec5a | 2015-08-04 13:00:21 -0700 | [diff] [blame] | 96 | } |